Problems encountered in webpack3. X upgrading 4. X

Time:2020-10-6

background

stayvue-cli3Before publishing, usevue-cli2ConstructedvueThe project is based onwebpack3.xWith the iteration of the project version, the functions and files are gradually increased, and the packaging time is from the original5Minutes, the longest time19Minutes and a half.

Because of the use oftsEvery time you packts-loaderType checking is required, resulting in a dramatic increase in time. Weighing the pros and cons, thets-loaderAfter type checking is disabled for(transpileOnlyOption set totrue), packing time reduced to2Minutes and a half.

As time goes on, the project iterates further, and the packaging time rises again9Minutes, just in timewebpack4For the improvement of packaging performance, there is this upgrade log:

start

Overall thinking:

  1. Upgrade project dependencies
  2. Run through development environment package
  3. Run through build environment package

Upgrade project dependencies

At the beginning, the idea of project dependency upgrade was to upgrade firstwebpackGo to the latest version and upgrade step by steploaderpluginbabelAnd so on. But based on the previous project upgradewebpack4Experience, found that the gradual upgrade will take a part of the time inOld and new dependenceSo I decided to be radical and use itncuOne timepackage.jsonThe project dependencies contained in are upgraded to the latest version and can be modified selectively due to uncertaintypackage.jsonDo not upgrade some dependencies, such as those with changed major version numbers (eg: 0. X.x = > 1. X.x).

#Install NCU
npm i -g ncu

#Check the version and the latest version that the project depends on and make a list
ncu

#Will` package.json `The version number of the dependency contained in, updated to the latest
ncu -u

#Remove old dependencies and install new ones
rm -rf node_modules
rm package-lock.json
npm i

<!– more –>

Run through development environment package

npm run dev

Problems encountered during operation:

  1. TypeError: proxyMiddleware is not a function

    Error log:

    /Users/look/work/fe/xadmin-re/build/dev-server.js:47
      app.use(proxyMiddleware(options.filter || context, options));
            ^
    
    TypeError: proxyMiddleware is not a function
        at /Users/look/work/fe/xadmin-re/build/dev-server.js:47:11
        at Array.forEach (<anonymous>)
        at Object.<anonymous> (/Users/look/work/fe/xadmin-re/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

    reason:

    Because HTTP proxy middleware is upgraded tov1.xResulting in:

    - "http-proxy-middleware": "~0.17.3",
    + "http-proxy-middleware": "~1.0.3",

    v1.xIt needs to be imported activelycreateProxyMiddlewareThe way to use middleware is as follows:

// 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
```

**How to solve:**

Active import ` createproxymiddleware`

```diff
- const proxyMiddleware = require('http-proxy-middleware');
+ const { createProxyMiddleware } = require('http-proxy-middleware');
```

Change 'proxymiddleware' to 'create proxymiddleware'`

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

    How to migrate Vue loader from V14 to V15

    Error log:

    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

    reason:

    vue-loaderUpgrade tov15.xIn the future, it needs to be matchedVueLoaderPluginuse

    How to solve:

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

    Error log:

    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.

    reason:

    Quoted fromvue-loaderfile:

    Note that some template loaders export a compiled template function instead of normal HTML, such as Pug loader. In order to pass the correct content to Vue’s template compiler, you must switch to a loader that outputs plain HTML. For example, to support<template lang="pug">You can use Pug plain loader:

    How to solve:

    It is used in the projectpugGrammar, becausevue-loaderWe need to introduce it nowpug-plain-loader

    // webpack.base.confg.js
    
    module.exports = {
      // ...
      module: {
        rules: [
         // ...
          {
            test: /\.pug$/,
            loader: "pug-plain-loader"
          }
        ];
      }
    };
  3. Cannot find module ‘@babel/core’

    Error log:

    ERROR in ./src/store/mutation/util.js
    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    Error: Cannot find module '@babel/core'
    [email protected] requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install '[email protected]'.
        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

    reason:

    According to the error prompt, you can know that,[email protected]rely onBabel 7.x(i.e@babel/core)。

    How to solve:

    uninstallbabel-core

    npm un babel-core

    install@babel/core

    npm i -D @babel/core
  4. Cannot read property ‘bindings’ of null

    Error log:

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

    reason:

    SinceBabelUpgrade to7.x, but.babelrcStill referencing applies toBabel 6.xOfbabel-preset-env

    How to solve:

    uninstallbabel-preset-env

    npm un babel-preset-env

    install@babel/preset-env

    npm i -D @babel/preset-env

    from.babelrcRemove frombabel-preset-env, use@babel/preset-env

    - { "presets": ["env"] }
    + { "presets": ["@babel/preset-env"] }
  5. ValidationError: Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema.

    Error log:

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
```

**Reasons:**

`The "minimize" configuration item was removed

**How to solve:**

Delete the 'minimize' option for 'CSS loader'
  1. The ‘mode’ option has not been set

    Error log:

    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/

    reason:

    webpack4Start, offermodeOption to enablewebpackIf it is not set, the default value isproduction

    How to solve:

    Development environment settings:development, build environment settings:production

At this point, you can run through the development environment package

Run through build environment package

Problems encountered during operation:

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

    Error log:

    /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)

    reason:

    https://webpack.js.org/migrat…

    According to the error message, you can know that,webpack4startCommonsChunkPluginDeleted

    How to solve:

    takeCommonsChunkPluginDelete the related configuration and useoptimization.splitChunksConfiguration item

    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.
    https://webpack.js.org/plugin…

    According to the description of the plug-in document, we do not add additional configuration here, but useoptimization.splitChunksThe default value of the configuration item.

    // 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

    Error log:

    /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)

    reason:

    Extract text webpack plugin inwebpack4Instead, use mini CSS extract plugin instead

    How to solve:

    uninstallextract-text-webpack-plugin

    npm un extract-text-webpack-plugin

    installmini-css-extract-plugin

    npm i -D mini-css-extract-plugin

    takeextract-text-webpack-pluginDelete the related configuration and usemini-css-extract-plugin

    // utils.js
    if (options.extract) {
    -  return ExtractTextPlugin.extract({
    -    use: loaders,
    -    fallback: 'vue-style-loader'
    -  });
    +  return [
    +    {
    +      loader: MiniCssExtractPlugin.loader,
    +      options: {
    +        hmr: process.env.NODE_ENV === 'development'
    +      }
    +    }
} else {
  return ['vue-style-loader'].concat(loaders);
}
```

If the project is not built with 'Vue cli 2. X', it may need to be modified as follows:

For details, please refer to: https://webpack.js.org/plugins/mini-css-extract-plugin/

```js
// 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"
    })
  ]
};
```
  1. DefaultsError: warnings is not a supported option

    Error log:

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

    reason:

    becauseUglifyJsDue to the upgrade,uglifyjs-webpack-pluginRely onUglifyJs

    For details, please refer to: https://github.com/mishoo/Ugl…

    How to solve:

    takeuglifyOptions.compressOption delete

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

    Error log:

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

    reason:

    uglifyjs-webpack-pluginI won’t support ites6grammar

    How to solve:

    uninstalluglifyjs-webpack-plugin

    npm un uglifyjs-webpack-plugin

    takeuglifyjs-webpack-pluginThe relevant configuration is deleted, and no additional configuration is needed becauseproductionIn mode,webpackDefault useterser-webpack-pluginTo minimizeJavaScriptfile

At this point, the production environment packaging can run through, and the next article will talk about how to optimizewebpackpack

Reference link

  • How to migrate Vue loader from V14 to V15
  • Execution order of webpack loader