65.9K
CodeProject 正在变化。 阅读更多。
Home

分步迁移 - Webpack 3 到 Webpack 4

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2019年2月24日

CPOL

3分钟阅读

viewsIcon

20064

downloadIcon

60

本文详细介绍了从 Webpack 3 迁移到 Webpack 4 的步骤。

引言

从 Webpack 3 迁移到 Webpack 4 是一个非常繁琐的过程。我阅读了许多文章和博客,试图找到一种好的、简单且快速的方法。然而,我没有找到一篇能够解释所有内容并列出迁移痛点的文章。因此,我决定写一些东西来帮助其他正在考虑在不久的将来进行升级的开发者。

背景

首先要问的问题是,为什么我们需要升级到 webpack 4。我相信互联网上有大量的文章可以解释其好处。所以,我跳过这部分。

我将解释 react/angular/其他 js 包,less/Scss 包的升级。我相信一旦你掌握了这些资源,字体/图像将会变得轻而易举。

Using the Code

开始迁移之前需要考虑的一些事项如下

  1. 更新 npm 版本。它应该大于 8.9.0。运行命令 npm -v 检查当前版本,并在 Windows 机器上升级 - 只需从这里下载 node msi。对于 mac/linux,请访问 nodejs 站点并按照那里的升级步骤进行操作。
  2. 从一个新的 webpack.config.js 文件开始。从头开始,然后一次只迁移一种资源类型,这总是好的。将现有的 webpack.config.js 文件重命名为 webpack_old.config.js
  3. 始终尝试在迁移期间使用 webpack-bundle-analyzer 来可视化哪个包文件包含哪些包。它有助于决定将哪些包分组到哪个 chunk 中,因此有助于优化 chunk。
  4. Webpack 4 不使用 extract-text-css-plugincommon-chunks-pluginuglify-js-plugin(这个插件适用于早期版本的 webpack 4,不适用于最新版本),所以直接删除这些插件。这些插件的替代品分别是 mini-css-extract-plugin,splitChunksplugin(webpack 4 内置)和 terser-webpack-plugin
  5. 对于 sass/scss 转换,您需要在 root 文件夹中添加一个 postcss.config.js 文件。我会附上此文件以供参考
    //
    // postcss.config.js
    // 
    module.exports = {
        plugins: [
            require('autoprefixer')
        ]
    }
  6. 尝试先修改 package.json 文件,然后更新所有需要的迁移包。
  7. 我收到了一些与 cosmiconfig 相关的错误。因此,我必须将此包包含在 package.json 文件中。

package json 应该至少包含这些包才能运行 webpack 4 来处理 js/jsx/css/less/scss 文件。

Package.json

//
// minimum packages required to start with webpack 4 - define in package.json file
// 
    "autoprefixer": "^9.4.7",
    "babel-core": "^6.26.3",
    "babel-loader": "7.1.2",
    "babel-polyfill": "6.26.0",
    "babel-preset-env": "1.6.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "6.24.1",
    "babel-preset-stage-3": "6.24.1",
    "clean-webpack-plugin": "^0.1.16",
    "cosmiconfig": "4.0.0",
    "less": "^3.9.0",
    "less-loader": "4.1.0",
    "mini-css-extract-plugin": "0.5.0",
    "node-sass": "4.11.0",
    "npm": "^5.8.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "postcss-loader": "3.0.0",
    "sass-loader": "7.1.0",
    "style-loader": "0.23.1",
    "suppress-chunks-webpack-plugin": "0.0.4",
    "terser-webpack-plugin": "1.1.0",
    "toastr": "^2.1.4",
    "webpack": "4.29.0",
    "webpack-bundle-analyzer": "^3.0.4",
    "webpack-cli": "3.2.3",

Webpack.config.js

webpack.config.js 文件的顶部定义 const

'use strict';
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const SuppressChunksPlugin = require('suppress-chunks-webpack-plugin').default;
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const TerserPlugin = require('terser-webpack-plugin');

//Initialize PLUGINS
const MiniCssPlugin = new MiniCssExtractPlugin({
    filename: 'assets/css/[name].css'
});

// cleans 'dist' folder every time before a new build
//not required but nice to start with clean folder
const CleanPLugin = new CleanWebpackPlugin(
    ['./dist/js', './dist/css'], {
        verbose: false,
        dry: false
    });

从 webpack 模块导出开始,然后在内部定义 config 条目,如下所示

module.exports = (env) => {

    //Define variables
    const isDev = env === 'development';
    const jsIdentifier = './assets/js/[name].js';
    const plugins = isDev ? [CleanPLugin, MiniCssPlugin, 
                    new BundleAnalyzerPlugin()] : [CleanPLugin, MiniCssPlugin];
   
    // build WEBPACK config
    const config = {};
    config.mode = env;
    config.watch = isDev;
    config.resolve = {
        extensions: ['.js', '.jsx']
    };
    config.devtool = 'source-map';
    config.entry =
        {
            'angularapp.min': './angularapp/app.js',
            sassStyle: './assets/scss/main.scss',
            lessStyle: './assets/less/main.less',
            'reactapp.min': './reactapp/index.js'
        };
    config.output = {
        path: __dirname,
        filename: jsIdentifier,
        chunkFilename: jsIdentifier
    };
    // you can get more information about the splitchunks plugin from webpack site.
    // This plugin is very powerful as you can define more than one entry inside cacheGroups
    // and further split the vendor chunks in 
    // as many small bundles as you want depending upon the 'test' value
    config.optimization = {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendor.min',
                    chunks: 'initial'
                }
            }
        },
        minimizer: [
            new TerserPlugin({
                sourceMap: isDev,
                cache: true,
                parallel: true,
                terserOptions: {
                    mangle: false,
                    keep_classnames: true,
                    keep_fnames: true,
                    output: {
                        comments: false
                    }
                }
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    };
    config.plugins = plugins;config.module = {
        rules: [
            {
                test: /\.(js|jsx)$/, exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    query: {
                        presets: ['es2015', 'react', 'stage-3']
                    }
                }
            },
            {
                test: /\.scss$/,
                use: [MiniCssExtractPlugin.loader,
                    {
                        loader: "css-loader", options: {
                            sourceMap: true
                        }
                    },
                    'postcss-loader',
                    {
                        loader: "sass-loader", options: {
                            sourceMap: true
                        }
                    }]
            },
            { // less loader for webpack
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader']
            }
        ]
    };
    return config;
};

您可以通过两种方式在 webpack 中定义生产/开发 config

  1. 一种是使用 --mode production(在 package json 命令中)
  2. 另一种是我使用的 --env production 标志(参考附加的 package.json 文件中的 build 脚本命令)

没有对或错的方法。这完全取决于您想如何在 webpack.config.js 文件中定义配置。

这就是您迁移到 webpack 4 所需要做的全部更改。我已附上 package.jsonwebpack.config.js 文件以供参考。

关注点

您可以在这里了解更多关于 Webpack 4 配置的信息。

历史

  • 2019 年 2 月 25 日:初始版本
© . All rights reserved.