【问题标题】:How to code-split webpack's vendor chunk?如何对 webpack 供应商块进行代码拆分?
【发布时间】:2021-01-23 11:49:14
【问题描述】:

由于代码拆分,我有一个 webpack main.bundle.js,其重量为 287kb,但我的 vendor.js5mb。当用户第一次访问网站时,他将不得不下载5.2mb,这个太大了。

拆分供应商的正确方法是什么,以便用户只下载运行页面所需的包,然后 webpack 在后台预取所有剩余的包?

我正在使用 webpack 4(我正在等待 Storybook 支持 webpack 5 再升级。如果在 W5 中有新的方法,请告诉我)。

这是我的配置:

/* eslint-env node */
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const Dotenv = require("dotenv-webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const isProductionMode = (mode) => mode === "production";

module.exports = () => {
  const env = require("dotenv").config({ path: __dirname + "/.env" });
  const nodeEnv = env.parsed.NODE_ENV;
  return {
    mode: "development",
    entry: "./src/index.tsx",
    output: {
      path: path.join(__dirname, "./dist"),
      filename: "[name].[hash].bundle.js",
      publicPath: "/",
    },
    resolve: {
      extensions: [".ts", ".tsx", ".js", "jsx", ".json"],
    },
    module: {
      rules: [
        {
          test: /\.(ts|js)x?$/,
          exclude: /node_modules/,
          use: { loader: "babel-loader" },
        },
        { test: /\.css$/, use: ["style-loader", "css-loader"] },
        { test: /\.(png|jpg|jpeg|gif)$/, use: ["file-loader"] },
        {
          test: /\.svg$/,
          use: [
            {
              loader: "babel-loader",
            },
            {
              loader: "react-svg-loader",
              options: {
                jsx: true,
              },
            },
          ],
        },
      ],
    },
    devServer: {
      historyApiFallback: true,
      port: 3000,
      inline: true,
      hot: true,
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: "./src/index.html",
      }),
      new Dotenv(),
    ],
    optimization: {
      minimize: isProductionMode(nodeEnv),
      minimizer: isProductionMode(nodeEnv) ? [new TerserPlugin()] : [],
      splitChunks: { chunks: "all" },
    },
  };
};

【问题讨论】:

  • 我想你可能想使用 'webpack-bundle-analyzer' npmjs.com/package/webpack-bundle-analyzer 来查看是哪个模块增加了大小。之后,您可以使用代码拆分技术延迟导入更大的模块。另一种应用技术是摇树。

标签: reactjs webpack


【解决方案1】:

这有助于我拆分供应商捆绑包。

来源:https://gist.github.com/davidgilbertson/c9af3e583f95de03439adced007b47f1

splitChunks: {
  chunks: 'all',
  enforce: true,
  cacheGroups: {
    vendor: {
      test: /[\\/]node_modules[\\/]/,
      name(module) {
        // get the name. E.g. node_modules/packageName/not/this/part.js
        // or node_modules/packageName
        const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

        // npm package names are URL-safe, but some servers don't like @ symbols
        return `npm.${packageName.replace('@', '')}`;
      },
    },
  },
},

【讨论】:

    【解决方案2】:

    这个讨论https://github.com/facebook/create-react-app/discussions/9161 包含一些配置(Webpack 5,应该不需要太多的调整来使用 Webpack 4),如果你想学习和重用单个分块策略,它们可能会给你一个很好的默认值。

    如果您喜欢简单的东西,您可以在config.optimization.splitChunks 下添加 1-2 个自定义 cacheGroups,如下所示:

         firebase: { // Internal identifier, just any unique name.
            test: /@firebase|redux-fire/, // This will match any file path containing @firebase or redux-fire (base and store) which is massive.
            name: "firebase", // Add a name to easily spot this chunk among outputs, or remove the `name` property to get a number instead which seems to be best-practice.
            priority: 10, // Higher prio = gets processed earlier. Defaults are on below 0.
          },
    

    据我所知,以上与 Webpack 4 和 5 兼容:https://v4.webpack.js.org/plugins/split-chunks-plugin/

    如果您想要更多控制权,您还可以取消默认组:

        cacheGroups: {
          firebase: {
            test: /@firebase|redux-fire/,
            name: "firebase",
            priority: 20,
          },
          defaultVendors: false,
          default: false,
          // Add more groups here
        },
    

    【讨论】:

      猜你喜欢
      • 2019-08-19
      • 2017-11-30
      • 2019-09-11
      • 2018-04-28
      • 2022-07-10
      • 2016-11-26
      • 1970-01-01
      • 2015-02-19
      • 1970-01-01
      相关资源
      最近更新 更多