如何在 Webpack 中生成动态导入块名称

Posted

技术标签:

【中文标题】如何在 Webpack 中生成动态导入块名称【英文标题】:How to generate dynamic import chunk name in Webpack 【发布时间】:2019-02-19 16:31:29 【问题描述】:

我在我的 TypeScript 代码中动态调用导入语句,基于该 Webpack 将创建如下块:

可以看到 Webpack 正在自动生成文件名分别为123,该名称不是友好名称。

我尝试了一种通过注释提供块名称的方法,但它正在生成modulename1.bundle.js , modulename2.bundle.js

bootStrapApps(config) 

    config.apps.forEach(element => 

      registerApplication(
        // Name of our single-spa application
        element.name,
        // Our loading function
        () =>
          import(/* webpackChunkName: "modulename"*/  "../../" +
            config.rootfolder +
            "/" +
            element.name +
            "/" +

            "app.bootstrap.js"),
        // Our activity function
        () => true
      );
    );
    start();

有没有办法通过这条评论动态指定模块名称?我不知道这是特定于 TypeScript 或 Webpack 的。

【问题讨论】:

这是 Webpack 特有的,与 TypeScript 无关 【参考方案1】:

来自webpack docs:

webpackChunkName:新块的名称。从 webpack 2.6.0 开始,占位符 [index] 和 [request] 在给定的字符串中分别支持递增的数字或实际解析的文件名。

您可以使用[request] 占位符来设置动态块名称。 一个基本的例子是:

const cat = "Cat";
import(
  /* webpackChunkName: "[request]" */
  `./animals/$cat`
);  

所以块名称将是Cat。但是,如果您将字符串 Cat 放在路径中,[request] 将在构建过程中发出警告,说 request was undefined。 所以这行不通:

import(
  /* webpackChunkName: "[request]" */
  "./animals/Cat"
);  

最后,您的代码将如下所示:

bootStrapApps(config) 
    config.apps.forEach((element) => 
      registerApplication(
        // Name of our single-spa application
        element.name,
        // Our loading function
        () =>
          import(/* webpackChunkName: "[request]" */ `../../$config.rootfolder/$
            element.name
          /app.bootstrap.js`),
        // Our activity function
        () => true
      );
    );
    start();
    

查看这个 GitHub 问题以获得更多帮助。 https://github.com/webpack/webpack/issues/4807

PS:那些 cmets 被称为 webpack magic cmets

【讨论】:

这是完美的......有没有办法将文件名小写?现在我得到Team-Form.js,这仍然比拥有整个路径要好得多,但小写是首选。 @VinceKronlein 不太确定这是否可能。块名称将与文件名相同。 实际上现在使用 WebPack 5,您可以将 chunkFilename 输出为函数并在那里进行转换。 ``` chunkFilename: (pathData) => let name = pathData.chunk.name.toLowerCase() pathData.chunk.name = name return 'js/[name].js?id=[chunkhash]' ``` 【参考方案2】:

你也可以在 webpack 配置文件中使用chunkFilename

babel-plugin-syntax-dynamic-import 提供。

在我看来,配置中的chunkFilename 有时比每个文件中的webpackChunkName 更方便

详情见https://medium.com/@anuhosad/code-splitting-in-webpack-with-dynamic-imports-4385b3760ef8

【讨论】:

这是一个通过向文件添加哈希来破坏缓存的好策略,但它不会删除通过导入生成的文件的文件路径。例如,假设您的 js 文件位于 assets/js,并且您有一个名为 Layout 的 Vue 组件。分块将生成文件assets_js_Layout_vue.js,并且随着嵌套的深入,它会变得更长。使用魔术注释可以让您指定要命名的文件。

以上是关于如何在 Webpack 中生成动态导入块名称的主要内容,如果未能解决你的问题,请参考以下文章

vue + webpack:动态组件导入是如何工作的?

如何在块中生成组合

使用块导入/加载库

如何在列表中生成动态 url?

AWS Step Functions:如何访问在 catch 块中生成异常的状态的输入?

如何在 C# 中生成随机颜色名称