webpack 4 - 用于多个条目的拆分块插件
Posted
技术标签:
【中文标题】webpack 4 - 用于多个条目的拆分块插件【英文标题】:webpack 4 - split chunks plugin for multiple entries 【发布时间】:2018-10-18 00:32:00 【问题描述】:将split chunks plugin 与以下配置一起使用:
entry:
entry1: [entry1.js],
entry2: [entry2.js],
entry3: [entry3.js],
...
optimization:
splitChunks:
chunks: "all"
代码将被完美地分成:
vendors-entry1-entry2-entry3.js // common for all
vendors-entry1-entry3.js // vendors only required by both entry1, entry3
entry1-entry2.js // common code of entry1 and entry2
entry1.js // unique entry's code
entry2.js
entry3.js
问题是,我现在如何在我的 html(或在我的特定情况下为 ejs)中的每个条目使用特定供应商?
按照推荐使用htmlWebpackPlugin 只会创建一个加载所有上述内容的 index.html,尽管用例很明显:
渲染 entry1 页面时 - 加载:
vendors-entry1-entry2-entry3.js
vendors-entry1-entry3.js
entry1-entry2.js
entry1.js
渲染 entry2 页面时 - 加载:
vendors-entry1-entry2-entry3.js
entry1-entry2.js
entry2.js
等等。
【问题讨论】:
@RavitejaCommonsChunkPlugin
已在 webpack 4 中删除。SplitChunksPlugin
是它的继任者。
请解释反对意见,我想知道我是否在这里遗漏了一个非常基本的东西..
我有同样的问题,我不明白反对意见。
丹尼尔或@A。 Matías Quezada 我很好奇你是否找到了解决方案。很难获得关于具有多个入口点的 splitChunks 的类似问题和信息。
@EgorNepomnyaschih - 它并不总是用于多个条目,你想将你的包分成块,以防它太大而不管条目的数量。对于单个条目,插件可以完美运行。
【参考方案1】:
HtmlWebpackPlugin 第 4 版(目前为 alpha 版)自动包含所有条目生成的块。所以只需设置chunks: 'entry1'
就可以了:
new HtmlWebpackPlugin(
template: 'entry1.ejs',
filename: 'entry1.html',
chunks: ['entry1']
),
... 并导致在 html 文件中注入所有依赖块:
<script src="/vendors-entry1-entry2-entry3.js">
<script src="/vendors-entry1-entry3.js">
<script src="/entry1-entry2.js">
<script src="/entry1.js">
你可以安装它
npm install --save-dev html-webpack-plugin@next
【讨论】:
我使用的是 webpack 4.29.5,但它并不能完全以这种方式工作。仍然需要像这样指定要加载的块:chunks: ['vendors-entry1-entry2-entry3', 'vendors-entry1-entry3', 'entry1-entry2', 'entry1']
。否则(就像在答案中一样)它将仅加载 entry1.js 文件。
刚刚发现它仍然计划在@next 发布! github.com/jantimon/html-webpack-plugin/issues/1152
这不起作用。它只注入一次作为入口文件的文件,但没有注入任何块。【参考方案2】:
我遇到了类似的问题,并且使用我找到的 here 的配置设置取得了一些小成功。不确定它是否适用于您的特定用例,但我想我会分享。
webpack 配置中的优化哈希如下所示:
optimization:
splitChunks:
cacheGroups:
commons:
name: "commons",
chunks: "initial",
minChunks: 2,
minSize: 0
,
occurrenceOrder: true
,
所以使用这些入口点:
entry:
app: './src/app.js',
home: './src/home.js',
product: './src/product.js'
这是我的 HtmlWebpackPlugin 设置:
// base template common to all pages
new HtmlWebpackPlugin(
hash: true,
inject: true,
template: './src/jinja-templates/base.html.j2',
filename: `$templates/base.html.j2`,
chunks: ['commons', 'app']
),
// JUST the homepage
new HtmlWebpackPlugin(
hash: true,
inject: true,
template: './src/jinja-templates/index.html.j2',
filename: `$templates/index.html.j2`,
chunks: ['home']
),
// JUST the product template
new HtmlWebpackPlugin(
hash: true,
inject: true,
template: './src/jinja-templates/product.html.j2',
filename: `$templates/product.html.j2`,
chunks: ['product']
),
我成功地将“commons”和“app”块添加到所有页面,并且在主页上添加了“home”块(仅),在产品页面上,“product”块(仅)是添加。以下是“主页”页面来源的示例:
<body>
...
<script type="text/javascript" src="/static/commons.7ca91fd78182a8eb23f6.js?7ca91fd78182a8eb23f6"></script>
<script type="text/javascript" src="/static/app.7ca91fd78182a8eb23f6.js?7ca91fd78182a8eb23f6"></script>
<script type="text/javascript" src="/static/home.7ca91fd78182a8eb23f6.js?7ca91fd78182a8eb23f6"></script>
</body>
我不知道是否/如何使用此设置拆分供应商模块。我认为这是可能的,但如果是这样的话,一个由 webpack 精英组成的秘密阴谋集团会妥善保护这些信息:P
但鉴于它已经将代码分成几个非常小的块,我不确定是否有必要(无论如何对我来说)。
【讨论】:
谢谢,我实际上得到了一个非常相似的解决方案,不幸的是它不是真正的解决方案,因为它不能针对 N 个条目进行扩展,也没有充分利用拆分块插件 关于可扩展性,您可以创建一个函数,为每个条目创建HtmlWebpackPlugin
,然后使用 .concat(entryHtmlPlugins) 将它们添加到 plugins
数组中。以上是关于webpack 4 - 用于多个条目的拆分块插件的主要内容,如果未能解决你的问题,请参考以下文章