前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >webpack基础探讨

webpack基础探讨

作者头像
IMWeb前端团队
发布2019-12-03 17:03:59
6840
发布2019-12-03 17:03:59
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb zixinfeng 原文出处:IMWeb社区 未经同意,禁止转载

1. 使用webpack

  • webpack命令使用
    • webpack --help (webpack -h) 查看所有的命令
    • webpack-v
    • 打包命令 webpack [] 不适用webpack配置文件的时候
    • 使用webpack配置文件, 直接webpack
      • --config 指定配置文件 (默认配置文件名称 webpack.config.js或者 webpackfile.js)
    • Basic Options
      • --entry 指定入口文件
      • --watch -w 检测文件系统的变化
      • --debug -d 打开调试状态
      • --devtool 生成sourceMap
      • --progress 进度条显示
      • -d 简写 --mode development
    • Module Options
    • Output Options
    • Advanced Options 高级选项
    • Resolved Options 解析选项
    • Optimization Options 优化选项
    • Stats Option 状态选项 (打包出来样式的选项)
      • 使用webpack配置(配合node npm使用)
    • 不同的配置文件, 开发环境, 生产环境, 测试环境, 打包给第三方使用的
      • 第三方的脚手架vue-cli
    • 交互式的初始化一个项目
    • 项目迁移v1->v2# wepbpack-cli的使用 webpack-cli init webpack-addons-demo # 项目迁移 webpack-cli migrate <config> ## 只会升级配置文件, package.json里面的文件 需要手机升级 2. 直接使用webpack命名, 使用默认文件或者默认配置
代码语言:javascript
复制
   // app.js
   import sum from './sum'
   conosle.log(sum(1,2))

   // sum.js
   export default function sum(a, b) {
       return a + b;
   }

   //  打包命令: webpack app.js --output-path=dist --output-filename=bundle.js --mode development

   // 指定配置文件 webpack --config webpack.config.dev.js

3. 编译ES6/7

  • babel-loader ## 安装最新版本loader npm install babel-loader@8.0.0-beta @babel/core --save-dev ## 安装最新preset npm install @babel/preset-env --save-dev
  • npm install babel-loader babel-core --save-dev
  • npm install babel-preset-env --save-dev 指定规范的版本, 只是针对语法
    • es2015
    • es2016
    • es2017
    • env 包括2015~2017, 以及latest 用的比较多
      • 业内自定义的babel-preset-react
      • babel-preset-stage 0 ~3 表示规范组还没有正式发布阶段的
      • babel-presets - options - target 当需要编译的时候, 会根据指定的target来选择那些语法进行编译, 那些语法不进行编译
      • target.browsers 指定浏览器环境
      • target.browsers: 'last 2 versions' 主流浏览器的最后两个版本
      • target.browsers: '> 1%' 大于全球浏览器占有率1%的浏览器
      • 数据来源是 browserlist中, can i use中 { test: /\.js$/, use: { // use: 'babel-loader' //可以直接是一个字符串 loader: 'babel-loader', options: { // 指定preset presets: [['env', { // 告诉babel, 当需要编译的时候, 会根据指定的target来选择那些语法进行编译, 那些语法不进行编译 targets: { browsers: ['> 1%', 'last 2 versions'], // chrome: '52' // 一些新语法浏览器直接支持 不会被转换 } }]] } }, exclude: '/node-modules/' } // 当同时指定'> 1%', 'last 2 versions'的时候, 箭头函数会被转化, const, let等被转化, set不会被转化, num**2 转成了Math.pow // 将targets换成 chrome: '52', 转化后代码基本和原生代码一样
    • target.node 指定node环境
  • babel-polyfill插件和babel-runtime-transform插件
    • 针对一些方法比如数组的map, includes, Set并没有被babel处理, 但是在一些低版本的浏览器中这些方法并没有被实现, 所以需要借助这两个插件
    • babel-preset 只是针对语法, 而这两个插件针对函数和方法
      • generator
      • Set
      • Map
      • Array.from
      • Array.prototype.includes
    • 上述方法都没有被babel处理, 所以就需要借助babel的插件进行处理
  • babel-polyfill 垫片, 浏览器之间标准实现的方式不一样,保持浏览器之间同样的API
    • 全局垫片 (只要引入, 在全局范围内整个浏览器范围内, 可以对实现的API进行调用)
    • 相当于对全局变量的一个污染, 为开发应用而准备的 (在业务中使用, 而不是框架比如vue)
    • 使用: npm install babel-polyfill --save 真实项目中的依赖 所以是--save
    • 在项目中使用 import 'babel-polyfill'
  • babel-runtime-transform
    • 局部垫片
    • 为开发框架而准备的, 不会污染全局变量, 会在局部的方法里面新增加变量和方法
    • 优势: 当在代码中使用它的时候, 项目中的其他函数,如果使用es6/7方法, 会将每一个引用到的方法打包到单独的文件中去的; 如果使用了runtime-transform, 将其作为一个独立的整体单独打包进去, 相当于文件之间多余的代码就不会再有了
    • npm install babel-plugin-transform-runtime --save-dev
    • npm install babel-runtime --save
  • .babelrc 在里面配置和babel插件相关的内容 // app.js import sum from './sum' const func = () => { console.log('hello babel') } func() const arr = [1, 2, 3, 4, 5, 4, 3, 2, 1] const arrb = arr.map(item => item * 2) // 下面的语句 不会经过runtime编译 arr.includes(5); // 会经过runtime编译 但是没有exports 使用的时候报错 console.log('SetB', new Set(arrb)) /* function* gen() { yield 1 } */ sum(1, 2) // .babelrc { "presets": [["env", { "targets": { "browsers": ["> 1%", "last 2 versions"] } }]], "plugins": [ "transform-runtime" ] } // 1. 当plugins为空的时候, 上面的代码会完整运行, 都不会被转义 // 2. 添加generator函数的时候, 会报错找不到 regenerator // 3. 添插件的时候 includes不会编译, Set, generator会编译, 但是报错$export is not a function // 4. 屏蔽插件plugins, 使用polyfill, 完美运行所有新属性, 但是打包文件很大, 达到了471Kb
  • 实际开发中如何选择
    • 如果是应用开发, 只需要配置preset, 如果要使用es6/7新语法, 使用polyfill
    • 如果是开发UI库, 框架, 使用runtime

4. 编译TypeScript

  • JS的超集 tslang.cn 来自于微软
  • 官方推荐: npm install typescript ts-loader --save-dev
  • 第三方loader: npm install typescript awesome-typescript-loader --save-dev
  • 配置: tsconfig.json## 常用配置选项 compilerOptions:告诉编译器常用的配置选项, 比如 允许js 模块化方式指定:commonjs 指定输出路径等 compilerOptions.module: 模块化方式指定 compilerOptions.target: 编译之后的文件在什么环境下运行的 (类似将语言编译到什么程度) compilerOptions.typeRoots: [ "./node_modules/@type", // 默认安装npm install @types/lodash时路径 "./typings/modules", // 使用typings安装的声明文件路径 ] 指定types声明文件所在的地址 include: 给出一系列的文件路径, 表示需要编译的文件 exclude: 忽略的文件 allowJs: 是否允许js的语法
  • 安装声明文件.这样在编译的时候就会给出警告错误, 告诉我们传递的参数类型有错误
    • npm install @types/lodash
    • npm install @types/vue
    • 或者使用typings安装types声明文件, 使用compilerOptions.typeRoots

5. 提取公用代码

  • 减少冗余代码(每一个页面都会存在公共代码, 造成带宽浪费)
  • 提高用户的加载速度(只加载页面所需要的依赖, 其他页面在加载的时候, 公共代码已经加载好了)
  • CommonChunkPlugin (webpack.optimize.CommonChunkPlugin) // 针对webpack3 { plugins: [ new webpack.optimize.CommonChunkPlugin({ name: String | Array, // 表示chunk的名称 ? filename: String, // 公用代码打包的文件名称 minChunks: Number|function|Infinity // 数字表示为需要提取的公用代码出现的次数(最小是多少, 比如出现两次以上就提取到公用代码), Infinity 表示不讲任何的模块打包进去, 函数的话表示自定义逻辑 chunks: 表示指定提取代码的范围, 需要在哪几个代码快中提取公用代码 children: 是不是在entry的子模块中 还是在所有模块中查找依赖 deepChildren async: 创建一个异步的公共代码流 }) ] } // webpack4 optimization: { splitChunks: { chunks: 'all', // async(默认, 只会提取异步加载模块的公共代码), initial(提取初始入口模块的公共代码), all(同时提取前两者), minSize: 0, // 30000, // 大于30K会被抽离到公共模块 minChunks: 2, // 模块出现一次就会被抽离到公共模块中, 如果是1的话, 表示将所有的模块都提走, 针对pageA中, 如果只有自己引用jQuery, 那么会生成jQuery-vendor.js 的打包文件 maxAsyncRequests: 5, // 异步模块, 一次最多只能加载5个, maxInitialRequests: 3, // 入口模块最多只能加载3个 name: true } }
  • 场景
    • 单页应用
    • 单页应用 + 第三方依赖
    • 多页应用 + 第三方依赖 + webpack生成代码 (webpack内置函数)
  • 针对单入口的commonChunksPlugin = 并没有将公共部分打包, 只有针对多入口才会
  • 多入口文件的时候 entry: { pageA: path.resolve(__dirname, 'src/cmp', 'pageA'), pageB: path.resolve(__dirname, 'src/cmp', 'pageB') // vendor: ['lodash'] }, // webpack3 plugins: [ new webpack.optimize.CommonPluginsChun({ name: 'vendor', minChunks: Infinity }) // 公共模块打包的名字为vendor, entry中也有vendor, 所以会将webpack生成代码以及lodash打包进vendor中 ] // webpack4 splitChunks: { chunks: 'all', // async(默认, 只会提取异步加载模块的公共代码), initial(提取初始入口模块的公共代码), all(同时提取前两者), minSize: 30000, // 大于30K会被抽离到公共模块 // minChunks: 2, // 模块出现两次次就会被抽离到公共模块中 minChunks: Infinity, // 不需要在任何的地方重复 maxAsyncRequests: 5, // 异步模块, 一次最多只能加载5个, maxInitialRequests: 3, // 入口模块最多只能加载3个 // name: 'common' // 打包出来公共模块的名称 name: 'vendor' // 打包出来公共模块的名称 } // 1. 会将pageA, pageB中 公共使用的模块打包成进common.chunk.js (name:'common'的时候), 公共模块中包括webpack生成的代码 // 2. lodash只在pageA中使用, 次数为1, 但是minChunks: 2, 所以lodash只会被打包进pageA中 // 3. 在entry中添加 vendor: ['lodash'] 将公共库lodash单独打包, 在webpack4中将其打包进了公共common.chunk中, vendor中只有对lodash的引用 // 4. 如果想将lodash和webpack运行生成时代码以及公共代码打包到一起, minChunks改成Infinity, name:vendor, 将所有生成的文件引用都放到vendor中了 // 5. 保持第三方代码的纯净, 即将第三方代码和webpack分离开, webapck3添加plugins, webpack4添加runtimeChunk配置 // webpack3 new webpack.optimize.CommonPluginsChun({ name: 'manifest', minChunks: Infinity }) // 发现vendor和manifest处大部分代码是一样的可以, 可以改成 new webpack.optimize.CommonPluginsChun({ names: ['vendor','manifest'], minChunks: Infinity }) // webpack4 runtimeChunk: { name: 'manifest' }, // 结果是: 将webpack生成的代码打包到manifest中, 将lodash打包进vendor中, 将引用次数超过两次的打包进vendor中

6. 代码分割和懒加载

  • 通过代码分割和懒加载, 让用户在尽可能的下载时间内加载想要的页面, 只看一个页面的时候, 下载所有的代码, 带宽浪费;
  • 在webpack中, 代码分割和懒加载是一个概念, webpack会自动分割代码, 然后再把需要的代码加载进来, 不是通过配置来实现的, 通过改变写代码的方式来实现的, 当依赖一个模块的时候, 告诉webpack我们是需要懒加载或者代码切分, 通过两种方式来实现
    • webpack.methods
      • require.ensure() 接收四个参数
      • 第一个参数dependencies, 加载进来的代码并不会执行, 在callback中引入, 这个时候才会去执行, 第三个参数errorBack, 第四个参数chunkName
      • 如果浏览器不支持promise, 需要添加垫片
      • require.include 只有一个参数, 只引入进来, 但不执行
        • 当两个子模块都引入了第三个模块, 可以将第三个模块放入父模块中, 这样动态加载子模块的时候, 父模块已经有了第三方模块, 不会在多余加载; 比如subPageA, subPageB都引入了moduleA, 但是moduleA不会被打包进父依赖, 所以可以使用include
    • ES2015 loader spec (动态import) stage-3
      • 早起system.import
      • 后来import方式 返回一个Promise
        • import().then
    • webpack import function 通过注释的方式来解决动态的chunkName以及加载模式import( /*webpackChunkName: async-chunk-name*/ /*webpackMode: lazy*/ moduleName )
  • 代码分割的场景
    • 分离业务代码和第三方依赖 (提取公共代码中有涉及)
    • 分离业务代码 和 业务公共代码 和 第三方依赖; 相比于上一个,将业务代码拆成两部分
    • 分离首次加载 和 访问后加载的代码 (访问速度优化相关的) - LazyLoad - 提高首屏加载速度
代码语言:javascript
复制
   // 0. 单入口pageA, 不做任何的优化 直接引入 subPageA, subPageB, lodash 会发现pageA非常大

   // 1. 异步引入, 将lodash打包到vendor中
   require.ensure('lodash', require => {
     const _ = require('lodash')
     _.join([1, 2, 3], 4)
     console.log(_)
   }, 'vendor')

   // 2. pageA.js中修改
   if (page === 'subPageA') {
     // require([]) 参数是空数组的话, 里面的require的包还是会被异步打包
     require.ensure(['./subPageA'], require => {
       // 如果不require的话, 那么就不会执行subPageA中的代码块
       const subPageA = require('./subPageA')
       console.log(subPageA)
     }, 'subPageA')
   } else if (page === 'subPageB') {
     require.ensure(['./subPageB'], require => {
       const subPageB = require('./subPageB')
       console.log(subPageB)
     }, 'subPageB')
   }
   // 结果: moduleA分别在打包好的文件 subPageA.chunk.js 和 subPageB.chunk.js中, 公共部分moduleA没有被提取出来

   // 3. 单entry有上述公共代码的情况的话, 使用inlcude的情况处理, 将module在父模块pageA.js提前引入, 但是并不运行
   require.include('./moduleA')
   // 结果: moduleA被打包进入了pageA.bundle.js中, 这样就完成了代码分割


   // --- import 方案 ------------- 
   /*   坑: import 只有在stage-0 或者 syntax-dynamic-import
       yarn add babel-preset-stage-0 babel-plugin-syntax-dynamic-import --dev
       .babelrc   { "presets": ["stage-0"], "plugins": ["syntax-dynamic-import"] }
       上述两种情况只使用一种即可
   */
   // 在import的时候 代码实际上已经执行了
   if (page) {
     import(
       /* webpackChunkName: "subPageA" */
       /* webpackMode: "lazy" */
       './subPageC'
     ).then(subPageC => {
       console.log(subPageC)
     })
   } else {
     import(
       /* webpackChunkName: 'subPageD' */
       /* webpackMode: "lazy" */
       './subPageD'
     )
   }
  • async 在代码分割中如何使用, 即结合commonChunkPlugin // webpack.plugin.lazy.cmp.js entry: { pageA: path.resolve(__dirname, 'src/lazy_cmp', 'pageA'), pageB: path.resolve(__dirname, 'src/lazy', 'pageB'), vendor: ['lodash'] } // webpack3 plugins: [ new wepback.optimize.CommonsChunkPlugin({ // async 指定为true表示异步模块, 或者指定为 异步模块提取后的名称 async: 'async-common', children: true, // 表示不仅仅是两个入口页面之间, 而且还是两个页面之间的子依赖中去寻找 minChunks: 2 }), new wepback.optimize.CommonsChunkPlugin({ // lodash打包进入vendor中, manifest是webpack运行时代码 names: ['vendor', 'manifest'], minChunks: Infinity }) ] // webpack4 optimization: { // webpack runtime 代码 runtimeChunk: { name: 'manifest' }, // 公共模块提取 splitChunks: { chunks: 'all', // async(默认, 只会提取异步加载模块的公共代码), initial(提取初始入口模块的公共代码), all(同时提取前两者), minSize: 30000, // 大于30K会被抽离到公共模块 // minChunks: 2, // 模块出现两次次就会被抽离到公共模块中 minChunks: Infinity, // 不需要在任何的地方重复 maxAsyncRequests: 5, // 异步模块, 一次最多只能加载5个, maxInitialRequests: 3, // 入口模块最多只能加载3个 name: 'vendor' // 打包出来公共模块的名称 } } // pageA.js import _ from 'lodash' / 1. 这里不再使用include, 因为会和pageA打包到一起, 这里的目的是 将其异步单独提取出来 // require.include('./moduleA') const page = 'subPageA' // 在pageB中, 这里page='subPageB', 其余一样 if (page) { import( /* webpackChunkName: "subPageA" */ /* webpackMode: "lazy" */ './subPageA' ).then(subPageA => { console.log(subPageA) }) } else { import( /* webpackChunkName: 'subPageB' */ /* webpackMode: "lazy" */ './subPageB' ) } // 2. webpack3 结果: 将异步打包结果中subPageA和subPageB中的公共模块moduleA, 单独的提取到了async-common-pageA.chunk.js中 这里比较坑的困惑: commonsChunkPlugin参数说的不是很明确, 比如async, children, deepChildren, minChunk, 他们之间是有依赖忽视关系的 // 3. webpack4 结果: chunks:all, 结果是将多次引用的公共模块moduleA, lodash提取到了vendor.chunk中, 其余的和webpack3一样, 生成打包文件pageA.chunk, pageB.chunk(入口文件), subPageA.chunk, subPageB.chunk(异步单独提取), manifest.chunk(webpack-runtime单独提取)

5. 处理CSS

  • 每一个模块都有自己的css文件, 在使用的时候将css样式引入
  • 如何在webpack中引入css
    • style-loader 在页面中创建style标签, 标签里面的内容就是css内容
      • style-loader/url
      • style-loader/useable
    • css-loader 如何让js可以import一个css文件, 包装一层, 让js可以引入css文件 // index.js import './css/base.css' // webpack.config.style.js { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] } // 将打包后的文件引入到index.html中 // 1. 结果: 在html中生成了style标签, 将base.css标签中的样式放到了style标签中 // 2. 生成link标签的形式 (不过用的比较少) 注意publicPath配置 use: [ { loader: 'style-loader/url' // loader: 'style-loader/useable' }, { loader: 'file-loader' } ] // 结果: style-loader/url 单独生成一份css文件 , 但是引入多个文件的时候, 会生成多个link标签, 会造成越多的网路请求 //3. style-loader/useable import base from 'base.css' import common from 'common.css' var flag = false; setInterval(function() { if(flag) { base.use() } else { base.ununse() } flag = !flag; }, 2000) // base.use() 样式插入到style标签中 // common.unuse() // 控制样式不被引用 // 结果: 没过2000ms, 页面中样式循环引用和删除

6. StyleLoader 配置

  • insertAt (插入位置)
  • insertInto(插入到DOM)
  • singleton (是否只使用一个style标签) 当css模块比较多的时候 会有很多css标签
  • transform (转化, 浏览器环境下, 插入页面之前)
  • transform: './src/style/css.transform.js' // css.transform.js 文件内容 // 该函数并不是在打包的时候执行的,在运行webpack的时候, 是不行执行的 // 在style-loader 将样式插入到DOM中的时候 执行的, 运行的环境是在浏览器环境下, 可以拿到浏览器参数, window,UA // 可以根据当前浏览器来对当前的css进行形变 module.exports = function(css) { console.log(css) console.log(window.innerWidth) // 输出形变以后的css if (window.innerWidth >= 768) { css = css.replace('yellow', 'dodgerblue') } else { css = css.replace('yellow', 'orange') } return css; } - 针对每一次在index.js中引入的css文件都会执行上面的代码
    • CssLoader 配置参数
      • alias 解析的别名 将引入css的路径映射到其他地方
      • importLoader 取决于css处理后面是不是还有其他的loader (sass会使用到 @import)
      • minimize 是否压缩
      • modules 是否启用css-modules
      • 打包出来的样式class 都变成一段随机字符串
        • CSS modules
        • :local 给定一个本地的样式 局部的样式
        • :global 给定一个全局样式
        • compose 继承一个样式
        • compose ... from path 引入一个样式 (尽量将composes放在前面, 这样可以控制引入顺序, 样式不会被覆盖) // base.css .box { composes: big-box from './common.css'; height: 200px; width: 100px; border-radius: 4px; background: #696969; }
    • localIdentName: '[[path]][name]_[local]--[hash:base64:5]' 控制生成的class类名
      • path代表引用css路径 name表示文件名称 local本地样式名称
        • 配置less/sass
    • npm install less-loader less --save-dev
    • npm install sass-loader node-sass --save-dev.header { composes: font from './header.less' }
      • 提取css代码 - 提取公共代码 做缓存 (不提取的话, 将css代码打包到了js文件中)
      • extract-loader
      • ExtractTextWebpackPlugin
      • npm install extract-text-webpack-plugin --save-dev
代码语言:javascript
复制
       // webpack3
       var ExtractTextWebpackPlugin = require('ExtractTextWebpackPlugin)

       module: {
           rules: [

               {
                   test: /\.less$/,
                   use: ExtractTextWebpackPlugin.extract({
                       fallback: {
                           // 告诉webpack, 当不提取的时候, 使用何种方式将其加载到页面中
                           loader: 'style-loader,
                           options: {
                               singleton: true,
                               // transform: ''
                           }
                       },
                       use: [
                           {loader: 'css-loader'}
                           {loader: 'less-loader'}
                       ], // 定义我们继续处理的loader
                   })
               }
           ]
       },
       plugins: [
           new ExtractTextWebpackPlugin({
               filename: '[name].min.css', // 提取出来的css的名称
               // 将css-loader的option中的minimize打开

               // allChunks 给插件指定一个范围, 指定提取css的范围
               // 1. 设置为true 表示所有的引用的css文件都提取
               // 2. 设置为false, 默认, 只会提取初始化的css(异步加载不认为是初始化)
               allChunks:false, 
           })
       ]
       // webpack3 结果: index.bundle.js app.min.css 但是打开index.html 并没有插入进去

       // webpack4 
       {
           test: /\.less$/,
           use: [
             MiniCssExtractPlugin.loader,
             {
               loader: 'css-loader',
               // loader: 'file-loader'
               options: {
                 minimize: process.env.NODE_ENV === 'production',
                 modules: true,
                 localIdentName: '[path]_[name]_[local]--[hash:base64:5]'
               }
             },
             {
               loader: 'less-loader'
             }
           ]
       }

        plugins: [
           new MiniCssExtractPlugin({
             // Options similar to the same options in webpackOptions.output
             // both options are optional
             filename: '[name].css',
             chunkFilename: '[id].css'
           })
       ]
 - 异步引入a.js文件, 在a.js文件中引入a.less
   1. 针对allChunks为false的情况
      - webpack3: 生成a.bundle.js文件, css文件被当成js的一个模块被打包处理, 将css放在js文件里面, 一起被提取; css代码切分的一种方式, 将初始化加载和动态加载区分开; 借助动态加载的代码区分, 也是css-in-js的一个概念
      - weboack4: 生成moduleA.chunk.js 和moduleA.chunk.css文件, 在index.bundle.js 包括了对于modulA.js和module.css文件的引用
   2. webpack4使用splitChunks配置
          optimization: {
            splitChunks: {
              cacheGroups: {
                styles: {            
                  name: 'styles',
                  test: /\.scss|css$/,
                  chunks: 'all',    // merge all the css chunk to one file
                  enforce: true
                }
              }
            }
          }
      - 结果: 生成index.bundle.js style.chunk.js style.chunk.css 将所有的样式文件都打包进了style.chunk.css文件中, 但是需要手动添加到项目htm中
      - question: 为什么这里不会运行? npm run extract
  • PostCss (Autoprefixer CSS-nano CSS-next) A tool for transforming Css With Javascript用js去转化css的一个工具
    • 联系到上一节中的css.transform.js, 但是时机是不一样的, PostCss是打包的时期, css.transform是浏览器插入到style标签中的时候
    • postcss的强大, 理解成为一个处理css的工具
      • 安装 npm install postcss postcss-loader autoprefixer cssnano postcss-cssnext --save-dev
      • autoprefixer: 帮助加上浏览器前缀
      • css-nano 帮助我们优化压缩css, 在postcss可以当做插件使用, css-loader就是用的css-nano做的压缩
      • css-next 使用未来的css新语法
      • css variables
      • custom selectors 自定义选择器
      • calc() 动态计算 ...
代码语言:javascript
复制
         {
             loader: 'postcss-loader',
              options: {
                 // require进来的插件给postcss使用的
                 ident: 'postcss', // 表明接下来的插件是给postcss使用的
                 plugins: [
                     // require('autoprefixer')(),
                     // 两个一起用cssnext 会给出警告, 提示已经包含autoprefixer
                     require('postcss-cssnext')()
                 ]
             }
           },
  • 一旦涉及到浏览器兼容性问题的时候, 一定会有针对的浏览器兼容问题, 使用browserlist, 让所有的插件都公用一份browserlist
    • 可以放在package.json里面
    • .browserlistrc 存入对浏览器的要求
      • postcss-import 插件 将@import的文件内容直接放入到当前的css文件中, 但是存过来之后要考虑相对文件路径的变化, 需要配合postcss-url来使用
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 使用webpack
  • 3. 编译ES6/7
  • 4. 编译TypeScript
  • 5. 提取公用代码
  • 6. 代码分割和懒加载
  • 5. 处理CSS
  • 6. StyleLoader 配置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档