【问题标题】:How to load dynamic chunk without vendors splitting如何在不拆分供应商的情况下加载动态块
【发布时间】:2020-07-24 18:38:55
【问题描述】:

快速总结

如何动态导入 NPM 模块而不生成额外的 vendors~-prefixed 块?

详情

设置

webpack.config.js

const path = require("path");

module.exports = [{
    mode: "development",
    entry: path.resolve(__dirname, "js/index.js"),
}];

index.js

__webpack_public_path__ = "dist/";

loadMoment();

function loadMoment() {
    return require.ensure(
        "moment-timezone",
        require => {
            console.log("moment loaded");
            window.MY_GLOBAL = {
                moment: require("moment-timezone"),
            };
        },
        () => {},
        "lib/moment",
    );

    /*
    // Working on an existing project with an older version of ESLint, so the preferred import()
    // trips up the linter. Using the older require.ensure to avoid linter errors, but I tested
    // with async/await and import() and I get the same result.
    window.MY_GLOBAL = {
        moment: await import(
            /* webpackChunkName: "lib/moment" * /
            "moment-timezone"
        ),
    };
    */
}

结果

这是我目前得到的不想要的结果:

dist/
  lib/
    moment.js
  vendors~lib/
    moment.js

注意有 2 个moment.js 文件!

  • lib/moment.js 是 16 kb,当我检查它时,它只包含 ./node_modules/moment/locale 模块
  • vendors~lib/moment.js 是 938kb,当我检查它时,它包含 130 多个模块。所以,基本上,所有的 moment 和 moment-timezone 模块。

想要的结果:

dist/
  lib/
    moment.js

我想将我所有的 NPM 模块以及我可能想要加载的任何其他模块保存在一个块中,按照我指定的名称命名,没有任何自动前缀。

更多背景

我正在处理一个旧项目,该项目以前将整个缩小的时刻和时刻时区库复制/粘贴到名为“lib/moment.js”的 JS 资源中。我想从我们的代码库中删除它们并通过动态导入生成“lib/moment.js”文件。保留现有文件名和文件夹结构很重要。

动态导入代码看起来很简单 (webpack documentation),但我找不到任何关于 vendors~ 前缀或如何删除它的解释。当然,我可以在示例中看到它,但据我所知,该前缀从未直接寻址。

如果我无法摆脱前缀并将所有内容捆绑到 lib/moment 块中,那么我将不得不放弃这种方法,而继续使用存储在 lib 文件中的缩小库(这不是理想)。

【问题讨论】:

    标签: javascript webpack dynamic-import


    【解决方案1】:

    TL;DR

    简而言之,你需要禁用defaultVendors缓存组(或webpack 5之前的vendors):

    webpack.config.js

    const path = require("path");
    
    module.exports = [{
        mode: "development",
        entry: path.resolve(__dirname, "js/index.js"),
    
        // ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
        optimization: {
          splitChunks: {
            cacheGroups: {
                defaultVendors: false,
                // prior to webpack 5:
                //vendors: false,
            },
          },
        },
        // ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
    }];
    

    现在怎么样了?

    Webpack 为 optimization.splitChunks 属性提供了一个 default configuration,其中包括一个简单的“defaultVendors”规则(或 v4 中的“vendors”),它将 NPM 模块拆分为一个单独的块:

    cacheGroups: {
        defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            reuseExistingChunk: true,
        },
    },
    

    根据文档,如果您不想使用这些默认缓存组,那么you have to explicitly set them to false

    要禁用任何默认缓存组,请将它们设置为 false

    要禁用供应商缓存组,只需在 webpack 配置中将其设置为 false

    cacheGroups: {
        defaultVendors: false,
    },
    

    结果

    dist/
      lib/
        moment.js
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多