webpack 4 配置遇到的坑

2,287 阅读3分钟

webpack 版本:4.8.3

1. extract-text-webpack-plugin (CSS独立分离)

报错信息:

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
    at Chunk.get (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/lib/Chunk.js:712:9)
    at /Users/chenziyun/Desktop/spa/node_modules/extract-text-webpack-plugin/dist/index.js:176:48
    at Array.forEach (<anonymous>)
    at /Users/chenziyun/Desktop/spa/node_modules/extract-text-webpack-plugin/dist/index.js:171:18
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/node_modules/tapable/lib/Hook.js:35:21)
    at Compilation.seal (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/lib/Compilation.js:890:27)
    at hooks.make.callAsync.err (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/lib/Compiler.js:481:17)
    at _err0 (eval at create (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:11:1)
    at _addModuleChain (/Users/chenziyun/.nvm/versions/node/v10.0.0/lib/node_modules/webpack/lib/Compilation.js:758:12)
  • 问题:extract-text-webpack-plugin报错 // 独立分离CSS
  • 原因:没有webpack 4 版本的 extract-text-webpack-plugin
  • 解决办法:npm install -D extract-text-webpack-plugin@next 替代

2. postcss-loader 自动加前缀

webpack.config.js

{
    test: /\.css$/,
    use: ExtractTextPlugin.extract({
    fallback: "style-loader",
    use: [
            { loader: 'css-loader', options: { importLoaders: 1 } },
            'postcss-loader' //自动加前缀
         ]
    })
 },

创建postcss.config.js (放在项目的根目录下)

module.exports = {
  plugins: [
      require('autoprefixer') //自动添加前缀插件
  ]
}

发现css中并没有自动加前缀,这是需要在package.json中配置

"browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]

参数:

  1. last 2 versions: // 每个浏览器中最新的两个版本。
  2. 1% // 全球浏览器使用率大于1%。
  3. IE9以上
  4. 其他参数请参考 https://github.com/browserslist/browserslist

3. purifycss-webpack (消除未使用的CSS)

  • webpack 4中 使用purifycss-webpack
  • 可以查询:purifycss-webpac
  • npm install purifycss-webpack purify-css --save-dev
  • webpack.config.js 配置 引入模块:
const glob = require('glob'); 
const PurifyCSSPlugin = require("purifycss-webpack");

plugin配置:

new PurifyCSSPlugin({ 
    paths: glob.sync(path.join(__dirname, 'src/*.html'))
})
  • 问题:没有任何报错,但是打包时,丢失,部分CSS并没有合并进来,背景图片也是没有被打包。
  • 原因:分离CSS插件在去除未使用CSS插件之前,或者是文件路径问题。
  • 解决办法:
  1. new ExtractTextPlugin 放在new PurifyCSSPlugin之前。
  2. 检查下'../src/*.html'路径是否有问题。。

这里我是因为webpack.config.js在config目录下,并非默认在项目根目录下,所以这里的__dirname 在config 具体如下:

    paths: glob.sync(path.join(__dirname, '../src/*.html'))
    new ExtractTextPlugin("css/index.css"),
    new PurifyCSSPlugin({ 
      paths: glob.sync(path.join(__dirname, '../src/*.html')),
    }),

4.对于babel-polyfill 和 transform-runtime

目的:可以使用新的内置对象比如 Promise 或者 WeakMap, 静态方法比如 Array.from 或者 Object.assign, 实例方法比如 Array.prototype.includes 和生成器函数(提供给你使用 regenerator 插件)。

第一种方式 全局引入,完全交由babel-polyfill插件处理转义:

npm install --save babel-polyfill

main.js

import "babel-polyfill";
require("babel-polyfill")

webpack.config.js

module.exports = {
  entry: ["babel-polyfill", "./app/js"]
};

优点

  • 作用域是模块,避免全局冲突
  • 是按需引入,避免不必要引入造成及代码臃肿 缺点
  • 每个模块内单独引用和定义polyfill函数,造成了重复定义,使代码产生冗余

第二种方式,局部引入在使用第三方库时候,比如ElementUI,iview。建议使用这种方式。

npm install --save-dev babel-plugin-tranform-runtime babel-runtime

.babelrc文件中配置插件:

"plugins": ["transform-runtime"]
  • 优点
    • 无全局污染
    • 依赖统一按需引入(polyfill是各个模块共享的), 无重复引入, 无多余引入
    • 适合用来编写lib(第三方库)类型的代码
  • 缺点
    • 被polyfill的对象是临时构造并被import/require的,并不是真正挂载到全局由于不是全局生效,对于实例化对象的方法,如[].includes(x),依赖于Array.prototype.includes仍无法使用

5.package.json中scripts

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --config=build/webpack.dev.config.js --inline --open --hot",
    "build": "cross-env NODE_ENV=prod webpack --config=build/webpack.prod.config.js"
  },
npm install cross-env --save-dev

设置变量时,不要使用&&否则,会被认为执行两条命令,这时重新开始webpack没有cross-env的webpack,通过process.env.NODE_ENV拿到了undefined