升级webpack4

一、升级babel7

网上已经有很多不错升级babel7的文章了,这里写下主要步骤

  • 1、一键升级
npx babel-upgrade --write
  • 运行命令行后发现package.json.babelrc都自动发生了变化,升级完成!是的,不用怀疑!如果遇到报错可以百度下报错内容进行对应修改,我是没有遇到错误,直接升级成功,幸福来得太突然了
  • 2、polyfill
// .babelrc

  .... 
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
+        "useBuiltIns": "usage",
+        "corejs": "2"
      }
    ]
  ],
  ....
  • useBuiltIns修改为 usage, 表示按需加载polyfill,移除项目中的 import 'babel-polybill';
  • corejs不设置会有warning提示,默认为2.x
  • 3、transform-runtime使用多余Babel的帮助函数
// .babelrc

  "plugins": [
-    [
-      "@babel/plugin-transform-runtime",
-      {
-        "corejs": 2
-      }
-    ],
+    "@babel/plugin-transform-runtime",
  • 通过webpack-bundle-analyzer插件打包分析发现,在vendor.js有很多core-js/library目录的代码引用
  • 原因是transform-runtime会自动给js加上非全局的polyfill
  • npm i -D @babel/runtime安装依赖包,并修改.babelrc
  • 发现不支持module.exports,可以通过babel-plugin-add-module-exports这个插件解决,建议改为export default

友情链接:babel升级7官网文档

二、升级webpack4

  • 1、升级npm依赖包
  • webpack 升级 (npm i webpack@4 -D)
  • webpack-cli
  • webpack-dev-server@3
  • html-webpack-plugin (npm i [email protected] -D)
  • vue-loader(npm i vue-loader@15 -D)
  • style-loader 最新
  • vue-style-loader 最新
  • mini-css-extract-plugin
  • postcss-loader
  • uglifyjs-webpack-plugin
  • ....

上面列举的有的是新增的npm包,有的是旧的要更新的包,建议把和打包相关的包都更新到最新

  • 2、vue-loader
// webapck.base.conf.js

const VueLoaderPlugin = require('vue-loader/lib/plugin')
....
    module: {
        rules: utils.styleLoaders()
    },
    plugins: [
        new VueLoaderPlugin(),
        ....
    ]
... .
  • 添加VueLoaderPlugin、添加rules,具体参考vue-loader迁移官方文档
  • 这里rules直接从vue模板里的utils.js获取
  • 3、postcss
// .postcssrc.js

module.exports = {
    plugins: [
        require('autoprefixer'),
+        require('./build/plugins/px-convertor')({remUnit: 75}),
+        require('./build/plugins/svg-image-hex2rgb')(),
    ]
};
  • postcss之前是通过vue-loaderpostcss属性设置的
  • 现在单独为postcss-loader,把vue-loaderpostcss属性的插件转到.postcssrc.js
// build/utils.js

    function generateLoaders(loader, loaderOptions) {
+        let postcssLoader = {
+           loader: 'postcss-loader',
+        };
-        let loaders = [cssLoader, pathLoader];
+        let loaders = [cssLoader, pathLoader, postcssLoader];
  • vue模板的utils.js添加postcss-loader,具体参考vue-loader迁移postcss部分的官方文档
  • 4、CSS 提取
// build/utils.js

- const ExtractTextPlugin = require('extract-text-webpack-plugin');
+ var MiniCssExtractPlugin = require('mini-css-extract-plugin')
   ....
-            list = ExtractTextPlugin.extract({
-                use: loaders,
-                fallback: 'vue-style-loader'
-            });
+            list = [MiniCssExtractPlugin.loader].concat(loaders);

// webpack.prod.conf.js

- const ExtractTextPlugin = require('extract-text-webpack-plugin');
+ var MiniCssExtractPlugin = require('mini-css-extract-plugin')
  ....
-        new ExtractTextPlugin({
+        new MiniCssExtractPlugin({
            filename: utils.assetsPath('css/[name].[contenthash:29].css'),
            allChunks: true
        }),

  • 弃用之前的extract-text-webpack-plugin,改用mini-css-extract-plugin,具体参考css提取的官方文档
  • 5、删除json-loader
// webapck.base.conf.js

-            {
-                test: /\.json$/,
-                loader: 'json-loader'
-            }
  • json-loader内置了
  • 6、exclude使用绝对路径
// webapck.base.conf.js

            {
                test: /\.js$/,
                loader: 'babel-loader',
                include: [resolve('src'), resolve('test')],
-                exclude: ['node_modules']
+                exclude: [path.resolve(__dirname, '../node_modules')]
            },
  • 7、css-loader删除minimize
// build/utils.js

    let cssLoader = {
        loader: 'css-loader',
        options: {
-            minimize: process.env.NODE_ENV === 'production',
            sourceMap: options.sourceMap
        }
    };
  • 8、.styl文件加载出错
// build/utils.js

    return {
        css: generateLoaders(),
        postcss: generateLoaders(),
        less: generateLoaders('less'),
        sass: generateLoaders('sass', {indentedSyntax: true}),
        scss: generateLoaders('sass'),
-        stylus: generateLoaders('stylus'),
-        styl: generateLoaders('stylus')
+        'stylus|styl': generateLoaders('stylus')
    };
  • 9、添加mode
// webpack.dev.conf.js

const webpackConfig = merge(baseWebpackConfig, {
+    mode: 'development',
    module: {
        rules: utils.styleLoaders({sourceMap: true})
    },
  • webpack4 提供了developmentproduction2个mode值,默认是production.
  • 10、SplitChunksPlugin代替CommonChunkPlugin
// webapck.prod.conf.js

    plugins: [
-        new webpack.optimize.CommonsChunkPlugin({
-            name: 'vendor',
-            minChunks: function (module, count) {
-                return module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0;
-            }
-        }),
-        new webpack.optimize.CommonsChunkPlugin({
-            name: 'common',
-            chunks: ['vendor'],
-            minChunks: function (module, count) {
-                return module.resource.indexOf(path.join(__dirname, '../src')) === 0;
-            }
-        }),
-        new webpack.optimize.CommonsChunkPlugin({
-            name: 'manifest',
-            chunks: ['vendor', 'common']
-        }),
        ....
    ],
+    optimization: {
+        splitChunks: {
+            chunks: 'initial',
+            cacheGroups: {
+                common: {
+                    test: /src/,
+                    chunks: 'initial',
+                    name: 'common',
+                    priority: 9, // 优先
+                    enforce: true,
+                },
+                vendor: {
+                    test: /node_modules/,
+                    chunks: 'initial',
+                    name: 'vendor',
+                    priority: 10, // 优先
+                    enforce: true,
+                }
+            }
+        },
+        runtimeChunk: {
+            name: 'manifest'
+        }
+    },
  • 具体参考split-chunks-plugin官网文档
  • 11、UglifyJsPlugin
// webapck.prod.conf.js

+ var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
....
    plugins: [
-        new webpack.optimize.UglifyJsPlugin({
-            compress: {
-                warnings: false,
-                drop_console: process.env.WEHOTEL_ENV !== 'test'
-            },
-            comments: false,
-            sourceMap: false
-        }),
        ....
    ],
    optimization: {
+        minimizer: [
+            new UglifyJsPlugin({
+                uglifyOptions: {
+                    warnings: false,
+                    compress: {
+                       drop_console: process.env.WEHOTEL_ENV !== 'test'
+                    },
+                },
+                sourceMap: false,
+                extractComments: false,
+            }),
+        ],
  • 12、css顺序报错
WARNING in chunk common [mini-css-extract-plugin]
Conflicting order between:
 * *css ./node_modules/css-loader/dist/cjs.js??ref--11-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./build/rules/path-loader??ref--11-2!./node_modules/postcss-loader/src!./node_modules/stylus-loader??ref--11-4!./src/sdk/components/dialog/index.stylus?vue&type=style&index=0&lang=stylus&
 * css ./node_modules/css-loader/dist/cjs.js??ref--11-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./build/rules/path-loader??ref--11-2!./node_modules/postcss-loader/src!./node_modules/stylus-loader??ref--11-4!./src/sdk/components/calendar/index.stylus?vue&type=style&index=0&lang=stylus&

WARNING in chunk common [mini-css-extract-plugin]
Conflicting order between:
 * *css ./node_modules/css-loader/dist/cjs.js??ref--11-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./build/rules/path-loader??ref--11-2!./node_modules/postcss-loader/src!./node_modules/stylus-loader??ref--11-4!./src/sdk/components/calendar/index.stylus?vue&type=style&index=0&lang=stylus&
 * css ./node_modules/css-loader/dist/cjs.js??ref--11-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./build/rules/path-loader??ref--11-2!./node_modules/postcss-loader/src!./node_modules/stylus-loader??ref--11-4!./src/sdk/components/dialog/index.stylus?vue&type=style&index=0&lang=stylus&
  • 意思是/src/sdk/components/calendar/index.stylus/src/sdk/components/dialog/index.stylus这两个文件在两个地方,引用顺序不一样,导致要提取css不知道哪个文件的css放前面
  • 处理方法是找到引用的地方,把这两个文件的引用先后顺序调整为一致
  • 13、require第三方amd文件报错
// src/main.js

- const {VueLazyload} = require('src/lib/js/lazyload.js');
+ import VueLazyload from 'vue-lazyload';
Vue.use(VueLazyload);
  • 把第三方包vue-lazyloadcdn文件下载下来引用报错
  • 直接改用npm引用
  • 14、自定义组件
// build/my-plugin/index.js

- compiler.plugin('compilation', compilation => {
+ compiler.hooks.compilation.tap(this.constructor.name, compilation => {
  • webpack4自定义组件的钩子采用hooks写法,具体参考编写一个插件

三、总结

打完收工。友情链接:webpack4官方升级文档

你可能感兴趣的:(升级webpack4)