gpt4 book ai didi

javascript - Webpack:将动态导入的模块拆分为单独的 block ,同时将库保留在主包中

转载 作者:行者123 更新时间:2023-12-02 09:49:09 26 4
gpt4 key购买 nike

我正在开发一个网络应用程序,其中包含应该使用dynamic imports延迟加载的小部件。 。每个小部件都应该收到其单独的包,并且它们的依赖项只有在用户请求时才由浏览器获取。有一个异常(exception):流行的小部件应该包含在主包以及它们使用或扩展的库类中。下面您可以看到我想要实现的文件夹结构以及我想要的输出:

File Structure                       Desired chunk

src/
├── widgets/
│ ├── popular-widget/index.ts main
│ ├── edge-case-widget/index.ts edge-case-widget
│ └── interesting-widget/index.ts interesting-widget
├── library/
│ ├── Widget.ts main
│ └── WidgetFactory.ts main
└── index.ts main (incl. entry point)

dist/
├── edge-case-widget.app.js edge-case-widget
├── interesting-widget.app.js interesting-widget
└── main.app.js main (incl. entry point)

为了延迟加载小部件,我在 create 中使用以下表达式WidgetFactory中的方法。这工作正常,小部件模块会被 Webpack 神奇地拾取。

const Widget = await import(`../widgets/${name}/index`)

我试图通过配置 optimization.splitChunks.cacheGroups 来解决代码分割挑战在 Webpack 中。提供test函数我将模块分配到 librarywidgets缓存组。

module.exports = {
entry: './src/index.ts',
[...]
optimization: {
splitChunks: {
cacheGroups: {
library: {
test: module => isInLibrary(module.identifier()),
name: 'library',
chunks: 'all',
minSize: 0
},
widgets: {
test: module => isWidgetBundle(module.identifier()),
name: module => widgetNameFromModuleId(module.identifier()),
chunks: 'async',
minSize: 0
}
}
}
}
}

我被困住了!

  • 如何在小部件包中包含小部件依赖项?
  • 使用chunks: 'async'关于library缓存组使一些库类转到 main block 而其他人留在 library block 。为什么?
  • 当我使用chunks: 'all'时关于library缓存组所有模块都正确地组合在其中,但我丢失了 main 上的入口点 block 并获得一个空白页。怎么办?
  • 当我重命名library时将组缓存到 main我丢失了入口点,as documented here 。我不太明白为什么会出现这种情况以及我如何设法将 main 结合起来入口点为library打包成一个包。

希望您能帮助我了解我陡峭的 Webpack 学习曲线。

最佳答案

创建了一个简单的github repo具有您需要的配置。

  1. SplitChunks 配置(如果需要,请将 testname 函数更改为您的):
    splitChunks: {
cacheGroups: {
widgets: {
test: module => {
return module.identifier().includes('src/widgets');
},
name: module => {
const list = module.identifier().split('/');
list.pop();
return list.pop();
},
chunks: 'async',
enforce: true
}
}
}
  • 如果您希望PopularWidget位于main中,则不应动态导入它。使用常规 import 语句。因为 webpack 总是会为任何动态导入创建一个新 block 。那么请看一下this文件。
  •     import { Widget } from '../widgets/popular-widget';

    export class WidgetFactory {
    async create(name) {
    if (name === 'popular-widget') return await Promise.resolve(Widget);
    return await import(`../widgets/${name}/index`)
    }
    }

    UPD
    更改了配置以保留相关的 node_modules 和小部件。
    我为新的小部件 block 创建编写了两个简单的函数。
    这里的技巧是 module.issuer 属性,它意味着谁导入了这个文件。因此,函数 isRelativeToWidget 将为在小部件文件结构的任何深度导入的任何依赖项(无论是否为 node_modules)返回 true。
    代码可查here .
    结果配置:

    splitChunks: {
    chunks: 'all',
    cacheGroups: {
    vendors: false,
    default: false,
    edgeCaseWidget: getSplitChunksRuleForWidget('edge-case-widget'),
    interestingWidget: getSplitChunksRuleForWidget('interesting-widget')
    }
    }

    function isRelativeToWidget(module, widgetName) {
    if (module.identifier().includes(widgetName)) return true;

    if (module.issuer) return isRelativeToWidget(module.issuer, widgetName)
    }

    function getSplitChunksRuleForWidget(widgetName) {
    return {
    test: module => isRelativeToWidget(module, widgetName),
    name: widgetName,
    chunks: 'async',
    enforce: true,
    }
    }

    关于javascript - Webpack:将动态导入的模块拆分为单独的 block ,同时将库保留在主包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58901229/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com