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 的打包進行優化。

參考連接

相關文章
相關標籤/搜索