webpack3.x升级4.x时遇到的问题

背景

vue-cli3 发布以前,使用 vue-cli2 构建的 vue 项目是基于 webpack3.x 的,伴随着项目的版本迭代,功能逐渐增多,文件也逐渐增多,打包时间从最初的 4.5 分钟,最久的时候 17 分钟。javascript

由于使用 ts 的缘故,每次打包 ts-loader 须要进行类型检查,致使耗时剧增。权衡利弊下,将 ts-loader 的类型检查禁用后(transpileOnly 选项设置为 true),打包时间锐减到 1 分钟。css

随着时间的推移,项目依赖逐渐落后,打包时间也到了 2.5 分钟,恰逢 webpack4 对于打包性能的提高,因而就有了这篇升级日志:html

起步

总体思路:vue

  1. 升级项目依赖
  2. 跑通开发环境打包
  3. 跑通生成环境打包

升级项目依赖

一开始的项目依赖升级的思路是,先升级 webpack 到最新的版本,而后逐步升级 loaderpluginbabel 等依赖。可是基于以前其余项目升级 webpack4 的经验,发现逐步升级会耗费一部分时间在新旧依赖的问题上,因而决定激进一点,使用 ncu 一次性将 package.json 中包含的项目依赖升级到最新版本,考虑到不肯定性,能够选择性的修改 package.json 不升级某些依赖,好比主要版本号有变更的依赖(eg: 0.x.x => 1.x.x)。java

# 安装 npm-check-updates
npm i -g npm-check-updates

# 检查项目依赖的版本与最新稳定版本,列出清单(beta版本可能不会列出来)
ncu

# 将 `package.json` 中包含的依赖的版本号,更新到最新
ncu -u

# 删除旧的依赖,安装新的依赖
rm -rf node_modules
rm package-lock.json
npm i
复制代码

跑通开发环境打包

npm run dev
复制代码

运行过程当中遇到的问题:node

  1. TypeError: proxyMiddleware is not a function

    报错日志:webpack

    /Users/yourProjectPath/build/dev-server.js:47
      app.use(proxyMiddleware(options.filter || context, options));
            ^
    
    TypeError: proxyMiddleware is not a function
        at /Users/yourProjectPath/build/dev-server.js:47:11
        at Array.forEach (<anonymous>)
        at Object.<anonymous> (/Users/yourProjectPath/build/dev-server.js:42:25)
        at Module._compile (module.js:643:30)
        at Object.Module._extensions..js (module.js:654:10)
        at Module.load (module.js:556:32)
        at tryModuleLoad (module.js:499:12)
        at Function.Module._load (module.js:491:3)
        at Function.Module.runMain (module.js:684:10)
        at startup (bootstrap_node.js:187:16)
        at bootstrap_node.js:608:3
    复制代码

    缘由:git

    由于 http-proxy-middleware 升级到 v1.x 致使的:es6

    - "http-proxy-middleware": "~0.17.3",
    + "http-proxy-middleware": "~1.0.3",
    复制代码

    v1.x 起,须要经过主动导入 createProxyMiddleware 的方式使用中间件:github

    // javascript
    
    const express = require("express");
    const { createProxyMiddleware } = require("http-proxy-middleware");
    
    const app = express();
    
    app.use(
      "/api",
      createProxyMiddleware({
        target: "http://www.example.org",
        changeOrigin: true,
      })
    );
    app.listen(3000);
    
    // http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
    复制代码

    如何解决:

    主动导入 createProxyMiddleware

    - const proxyMiddleware = require('http-proxy-middleware');
    + const { createProxyMiddleware } = require('http-proxy-middleware');
    复制代码

    proxyMiddleware 改成 createProxyMiddleware

    - app.use(proxyMiddleware(options.filter || context, options));
    + app.use(createProxyMiddleware(options.filter || context, options));
    复制代码
  2. vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.

    vue-loader 如何从 v14 迁移至 v15

    报错日志:

    ERROR in ./src/App.vue
    Module Error (from ./node_modules/vue-loader/lib/index.js):
    vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
    @ ./src/main.ts 2:0-28 45:23-26
    @ multi ./build/dev-client ./src/main.ts
    复制代码
    ERROR in ./src/page/supplier/preferential/full-discount/view.vue?vue&type=script&lang=ts&
    Module not found: Error: Can't resolve '../../../../interface/coupon.coupon_code_view' in '/Users/yourProjectPath/src/page/supplier/preferential/full-discount'
    @ ./src/page/supplier/preferential/full-discount/view.vue?vue&type=script&lang=ts& 19:0-70
    @ ./src/page/supplier/preferential/full-discount/view.vue
    @ ./src/router/supplier/preferential.ts
    @ ./src/router/supplier/index.ts
    @ ./src/router/index.ts
    @ ./src/main.ts
    @ multi ./build/dev-client ./src/main.ts
    复制代码

    缘由:

    vue-loader 升级到 v15.x 之后,须要搭配 VueLoaderPlugin 使用

    如何解决:

    // webpack.base.confg.js
    const { VueLoaderPlugin } = require("vue-loader");
    
    module.exports = {
      // ...
      plugins: [new VueLoaderPlugin()],
    };
    复制代码
  3. Component template requires a root element, rather than just text.

    报错日志:

    Module Error (from ./node_modules/vue-loader/lib/loaders/templateLoader.js):
    (Emitted value instead of an instance of Error)
    
    Errors compiling template:
    
    Component template requires a root element, rather than just text.
    
    1   |
        |
    2   |  #app
        |  ^^^^
    3   |    router-view
        |  ^^^^^^^^^^^^^
    
     @ ./src/App.vue?vue&type=template&id=7ba5bd90&lang=pug& 1:0-238 1:0-238
     @ ./src/App.vue
     @ ./src/main.ts
     @ multi ./build/dev-client ./src/main.ts
    复制代码
    Module Error (from ./node_modules/vue-loader/lib/loaders/templateLoader.js):
    (Emitted value instead of an instance of Error)
    
    Errors compiling template:
    
    text "div
    el-card" outside root element will be ignored.
    复制代码

    缘由:

    引用自 vue-loader 文档:

    注意有些模板的 loader 会导出一个编译好的模板函数而不是普通的 HTML,诸如 pug-loader。为了向 Vue 的模板编译器传递正确的内容,你必须换用一个输出普通 HTML 的 loader。例如,为了支持 <template lang="pug">,你可使用 pug-plain-loader:

    如何解决:

    项目中使用到了 pug 语法,因为 vue-loader 的升级,如今须要引入 pug-plain-loader

    npm i -D pug-plain-loader
    复制代码
    // webpack.base.confg.js
    
    module.exports = {
      // ...
      module: {
        rules: [
         // ...
          {
            test: /\.pug$/,
            loader: "pug-plain-loader"
          }
        ];
      }
    };
    复制代码
  4. Cannot find module '@babel/core'

    报错日志:

    ERROR in ./src/store/mutation/util.js
    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    Error: Cannot find module '@babel/core'
    babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
        at Function.Module._resolveFilename (module.js:538:15)
        at Function.Module._load (module.js:468:25)
        at Module.require (module.js:587:17)
        at require (internal/module.js:11:18)
        at Object.<anonymous> (/Users/yourProjectPath/node_modules/babel-loader/lib/index.js:10:11)
        at Module._compile (module.js:643:30)
        at Object.Module._extensions..js (module.js:654:10)
        at Module.load (module.js:556:32)
        at tryModuleLoad (module.js:499:12)
        at Function.Module._load (module.js:491:3)
        at Module.require (module.js:587:17)
        at require (internal/module.js:11:18)
        at loadLoader (/Users/yourProjectPath/node_modules/loader-runner/lib/loadLoader.js:18:17)
        at iteratePitchingLoaders (/Users/yourProjectPath/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
        at runLoaders (/Users/yourProjectPath/node_modules/loader-runner/lib/LoaderRunner.js:365:2)
        at NormalModule.doBuild (/Users/yourProjectPath/node_modules/webpack/lib/NormalModule.js:295:3)
    @ ./src/store/mutation/nav.ts 3:0-48 54:41-63 59:41-63 63:41-63 70:37-59
    @ ./src/store/mutation/index.ts
    @ ./src/store/index.ts
    @ ./src/main.ts
    @ multi ./build/dev-client ./src/main.ts
    复制代码

    缘由:

    根据错误提示能够知道,babel-loader@8 依赖 Babel 7.x (也就是 @babel/core)。

    如何解决:

    卸载 babel-core

    npm un babel-core
    复制代码

    安装 @babel/core

    npm i -D @babel/core
    复制代码
  5. Cannot read property 'bindings' of null

    报错日志:

    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    
    TypeError: /Users/yourProjectPath/src/page/image-tag/bus.js: Cannot read property 'bindings' of null
    at Scope.moveBindingTo (/Users/yourProjectPath/node_modules/@babel/traverse/lib/scope/index.js:926:13)
    at BlockScoping.updateScopeInfo (/Users/yourProjectPath/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:364:17)
    at BlockScoping.run (/Users/yourProjectPath/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:330:12)
    at PluginPass.BlockStatementSwitchStatementProgram (/Users/yourProjectPath/node_modules/babel-plugin-transform-es2015-block-scoping/lib/index.js:70:24)
    at newFn (/Users/yourProjectPath/node_modules/@babel/traverse/lib/visitors.js:179:21)
    at NodePath.\_call (/Users/yourProjectPath/node_modules/@babel/traverse/lib/path/context.js:55:20)
    at NodePath.call (/Users/yourProjectPath/node_modules/@babel/traverse/lib/path/context.js:42:17)
    at NodePath.visit (/Users/yourProjectPath/node_modules/@babel/traverse/lib/path/context.js:90:31)
    at TraversalContext.visitQueue (/Users/yourProjectPath/node_modules/@babel/traverse/lib/context.js:112:16)
    at TraversalContext.visitSingle (/Users/yourProjectPath/node_modules/@babel/traverse/lib/context.js:84:19)
    at TraversalContext.visit (/Users/yourProjectPath/node_modules/@babel/traverse/lib/context.js:140:19)
    at Function.traverse.node (/Users/yourProjectPath/node_modules/@babel/traverse/lib/index.js:84:17)
    at traverse (/Users/yourProjectPath/node_modules/@babel/traverse/lib/index.js:66:12)
    at transformFile (/Users/yourProjectPath/node_modules/@babel/core/lib/transformation/index.js:107:29)
    at transformFile.next (<anonymous>)
    at run (/Users/yourProjectPath/node_modules/@babel/core/lib/transformation/index.js:35:12)
    复制代码

    缘由:

    因为已经将 Babel 升级到 7.x,可是 .babelrc 仍在引用适用于 Babel 6.xbabel-preset-env

    如何解决:

    卸载 babel-preset-env

    npm un babel-preset-env
    复制代码

    安装 @babel/preset-env

    npm i -D @babel/preset-env
    复制代码

    .babelrc 中移除 babel-preset-env,改用 @babel/preset-env

    - { "presets": ["env"] }
    + { "presets": ["@babel/preset-env"] }
    复制代码
  6. this.setDynamic is not a function

    报错日志:

    ERROR in ./src/lib/image-drop.js
    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    TypeError: /Users/yourProjectPath/src/lib/image-drop.js: this.setDynamic is not a function
        at PluginPass.pre (/Users/yourProjectPath/node_modules/babel-plugin-transform-runtime/lib/index.js:31:12)
        at transformFile (/Users/yourProjectPath/node_modules/@babel/core/lib/transformation/index.js:96:27)
        at transformFile.next (<anonymous>)
        at run (/Users/yourProjectPath/node_modules/@babel/core/lib/transformation/index.js:35:12)
        at run.next (<anonymous>)
        at Function.transform (/Users/yourProjectPath/node_modules/@babel/core/lib/transform.js:27:41)
        at transform.next (<anonymous>)
        at step (/Users/yourProjectPath/node_modules/gensync/index.js:254:32)
        at /Users/yourProjectPath/node_modules/gensync/index.js:266:13
        at async.call.result.err.err (/Users/yourProjectPath/node_modules/gensync/index.js:216:11)
        at /Users/yourProjectPath/node_modules/gensync/index.js:184:28
        at /Users/yourProjectPath/node_modules/@babel/core/lib/gensync-utils/async.js:72:7
        at /Users/yourProjectPath/node_modules/gensync/index.js:108:33
        at step (/Users/yourProjectPath/node_modules/gensync/index.js:280:14)
        at /Users/yourProjectPath/node_modules/gensync/index.js:266:13
        at async.call.result.err.err (/Users/yourProjectPath/node_modules/gensync/index.js:216:11)
    复制代码

    缘由:

    因为已经将 Babel 升级到 7.x,可是 .babelrc 仍在引用适用于 Babel 6.xbabel-plugin-transform-runtime

    如何解决:

    卸载 babel-plugin-transform-runtime

    npm un babel-plugin-transform-runtime
    复制代码

    安装 @babel/plugin-transform-runtime

    npm i -D @babel/plugin-transform-runtime
    复制代码

    .babelrc 中移除 babel-preset-env,改用 @babel/plugin-transform-runtime

    - { "plugins": ["babel-plugin-transform-runtime"] }
    + { "plugins": ["@babel/plugin-transform-runtime"] }
    复制代码
  7. ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.

    报错日志:

    ERROR in ./node_modules/element-ui/lib/theme-chalk/index.css (./node_modules/css-loader/dist/cjs.js??ref--11-1!./node_modules/element-ui/lib/theme-chalk/index.css)
    Module build failed (from ./node_modules/css-loader/dist/cjs.js):
    ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.
    - options has an unknown property 'minimize'. These properties are valid:
    object { url?, import?, modules?, sourceMap?, importLoaders?, localsConvention?, onlyLocals? }
        at validate (/Users/yourProjectPath/node_modules/css-loader/node_modules/schema-utils/dist/validate.js:50:11)
        at Object.loader (/Users/yourProjectPath/node_modules/css-loader/dist/index.js:34:28)
    @ ./node_modules/element-ui/lib/theme-chalk/index.css 4:14-81 14:3-18:5 15:22-89
    @ ./src/main.ts
    @ multi ./build/dev-client ./src/main.ts
    复制代码

    缘由:

    minimize 配置项被移除致使

    如何解决:

    删除 css-loaderminimize 选项

  8. The 'mode' option has not been set

    报错日志:

    WARNING in configuration
    The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
    You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
    复制代码

    缘由:

    webpack4 开始,提供了 mode 选项用来启用 webpack 提供的内置选项,没有设置时,默认值为 production

    如何解决:

    开发环境设置:development,生成环境设置:production

至此已经能够跑通开发环境打包了

跑通生成环境打包

运行过程当中遇到的问题:

  1. webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

    报错日志:

    /Users/yourProjectPath/node_modules/webpack/lib/webpack.js:189
    		throw new RemovedPluginError(errorMessage);
    		^
    
    Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
        at Object.get [as CommonsChunkPlugin] (/Users/yourProjectPath/node_modules/webpack/lib/webpack.js:189:10)
        at Object.<anonymous> (/Users/yourProjectPath/build/webpack.prod.conf.js:85:26)
        at Module._compile (module.js:643:30)
        at Object.Module._extensions..js (module.js:654:10)
        at Module.load (module.js:556:32)
        at tryModuleLoad (module.js:499:12)
        at Function.Module._load (module.js:491:3)
        at Module.require (module.js:587:17)
        at require (internal/module.js:11:18)
        at Object.<anonymous> (/Users/yourProjectPath/build/build.js:12:23)
        at Module._compile (module.js:643:30)
        at Object.Module._extensions..js (module.js:654:10)
        at Module.load (module.js:556:32)
        at tryModuleLoad (module.js:499:12)
        at Function.Module._load (module.js:491:3)
        at Function.Module.runMain (module.js:684:10)
    复制代码

    缘由:

    webpack.js.org/migrate/4/#…

    根据错误提示信息能够知道,webpack4 开始 CommonsChunkPlugin 被删除

    如何解决:

    CommonsChunkPlugin 相关的配置删除,改用 optimization.splitChunks 配置项

    The default configuration was chosen to fit web performance best practices, but the optimal strategy for your project might differ. If you're changing the configuration, you should measure the impact of your changes to ensure there's a real benefit. webpack.js.org/plugins/spl…

    根据插件文档的描述,这里咱们没有额外增长配置,使用的是 optimization.splitChunks 配置项的默认值。

    // webpack.config.js
    module.exports = {
      // ...
      optimization: {
        splitChunks: {
          chunks: "async",
          minSize: 30000,
          maxSize: 0,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: "~",
          automaticNameMaxLength: 30,
          name: true,
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true,
            },
          },
        },
      },
    };
    复制代码
  2. Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

    报错日志:

    /Users/yourProjectPath/node_modules/webpack/lib/Chunk.js:866
    	throw new Error(
    	^
    
    Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
        at Chunk.get (/Users/yourProjectPath/node_modules/webpack/lib/Chunk.js:866:9)
        at /Users/yourProjectPath/node_modules/extract-text-webpack-plugin/dist/index.js:176:48
        at Array.forEach (<anonymous>)
        at /Users/yourProjectPath/node_modules/extract-text-webpack-plugin/dist/index.js:171:18
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/yourProjectPath/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
        at AsyncSeriesHook.lazyCompileHook (/Users/yourProjectPath/node_modules/tapable/lib/Hook.js:154:20)
        at Compilation.seal (/Users/yourProjectPath/node_modules/webpack/lib/Compilation.js:1342:27)
        at compilation.finish.err (/Users/yourProjectPath/node_modules/webpack/lib/Compiler.js:675:18)
        at hooks.finishModules.callAsync.err (/Users/yourProjectPath/node_modules/webpack/lib/Compilation.js:1261:4)
        at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/yourProjectPath/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:24:1)
        at AsyncSeriesHook.lazyCompileHook (/Users/yourProjectPath/node_modules/tapable/lib/Hook.js:154:20)
        at Compilation.finish (/Users/yourProjectPath/node_modules/webpack/lib/Compilation.js:1253:28)
        at hooks.make.callAsync.err (/Users/yourProjectPath/node_modules/webpack/lib/Compiler.js:672:17)
        at _done (eval at create (/Users/yourProjectPath/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
        at _err1 (eval at create (/Users/yourProjectPath/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:32:22)
        at _addModuleChain (/Users/yourProjectPath/node_modules/webpack/lib/Compilation.js:1185:12)
    复制代码

    缘由:

    extract-text-webpack-pluginwebpack4 的时候被废弃,改用mini-css-extract-plugin

    如何解决:

    卸载 extract-text-webpack-plugin

    npm un extract-text-webpack-plugin
    复制代码

    安装 mini-css-extract-plugin

    npm i -D mini-css-extract-plugin
    复制代码

    extract-text-webpack-plugin 相关的配置删除,改用 mini-css-extract-plugin

    // utils.js
    -const ExtractTextPlugin = require('extract-text-webpack-plugin');
    +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    if (options.extract) {
    - return ExtractTextPlugin.extract({
    - use: loaders,
    - fallback: 'vue-style-loader'
    - });
    + return [
    + {
    + loader: MiniCssExtractPlugin.loader,
    + options: {
    + hmr: process.env.NODE_ENV === 'development'
    + }
    + }
    + ].concat(loaders);
    } else {
      return ['vue-style-loader'].concat(loaders);
    }
    复制代码
    // webpack.prod.conf.js
    -const ExtractTextPlugin = require('extract-text-webpack-plugin');
    +const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      // ...
      plugins: [
    - new ExtractTextPlugin({
    + new MiniCssExtractPlugin({
          filename: utils.assetsPath('css/[name].[contenthash].css'),
        }),
      ]
    }
    复制代码

    若是不是使用 vue-cli 2.x 搭建的项目,可能须要这样修改:

    详情见:webpack.js.org/plugins/min…

    // webpack.prod.conf.js
    // ***
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
      module: {
        rules: [
          // ***
          {
            test: /\.css$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
                options: {
                  hmr: process.env.NODE_ENV === "development",
                },
              },
              "css-loader",
            ],
          },
        ],
      },
      plugins: [
        // ***
        new MiniCssExtractPlugin({
          filename: "[name].[contenthash].css",
        }),
      ],
    };
    复制代码
  3. DefaultsError: warnings is not a supported option

    报错日志:

    ERROR in static/js/170.b2935281265dd9ec23b7.js from UglifyJs
    
    DefaultsError: `warnings` is not a supported option
    at DefaultsError.get (eval at <anonymous> (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/node_modules/uglify-js/tools/node.js:18:1), <anonymous>:71:23)
    at Function.buildError (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/index.js:105:54)
    at results.forEach (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/index.js:258:52)
    at Array.forEach (<anonymous>)
    at taskRunner.run (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/index.js:233:17)
    at step (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:85:9)
    at done (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:96:30)
    at boundWorkers (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:101:13)
    at TaskRunner.boundWorkers (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:70:11)
    at enqueue (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:91:14)
    at tasks.forEach (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:111:9)
    at Array.forEach (<anonymous>)
    at TaskRunner.run (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/TaskRunner.js:89:11)
    at UglifyJsPlugin.optimizeFn (/Users/yourProjectPath/node_modules/uglifyjs-webpack-plugin/dist/index.js:227:18)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/yourProjectPath/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:31:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/yourProjectPath/node_modules/tapable/lib/Hook.js:154:20)
    复制代码

    缘由:

    因为 UglifyJs 升级致使的,uglifyjs-webpack-plugin 依赖于 UglifyJs

    详情见:github.com/mishoo/Ugli…

    如何解决:

    uglifyOptions.compress 选项删除

    // webpack.prod.conf.js
    new UglifyJsPlugin({
      uglifyOptions: {
    - compress: {
          warnings: false,
          drop_console: true,
          drop_debugger: true
    - }
      }
    }),
    复制代码
  4. Unexpected token: keyword «const»

    报错日志:

    ERROR in static/js/app.2c7ff4a31971e22c9397.js from UglifyJs
    Unexpected token: keyword «const» [static/js/app.2c7ff4a31971e22c9397.js:3865,0]
    复制代码

    缘由:

    uglifyjs-webpack-plugin 不支持 es6 语法

    如何解决:

    卸载 uglifyjs-webpack-plugin

    npm un uglifyjs-webpack-plugin
    复制代码

    uglifyjs-webpack-plugin 相关的配置删除,不用额外增长配置,由于 production 模式下,webpack 默认使用 terser-webpack-plugin 来最小化 JavaScript 文件

总结

至此经历了一系列的各类问题以后,开发和生产环境打包都已经能够跑通了。这篇文章记录了的两个 webpack 3.x 项目升级到 webpack 4.x 时遇到的问题、缘由和解决方法,但愿对大家有帮助。

升级后生产环境打包速度有所提高,可是文件大小并不理想,下一篇我会讲如何对 webpack 的打包进行优化。

参考连接

相关文章
相关标签/搜索