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

等等。

【问题讨论】:

@Raviteja CommonsChunkPlugin 已在 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 - 用于多个条目的拆分块插件的主要内容,如果未能解决你的问题,请参考以下文章

Webpack:从条目和子块中提取公共模块以分离公共块

使用 webpack 构建在插件中注册多个自定义古腾堡块

使用 webpack 将供应商库拆分为多个块

webpack mini-css-extract-plugin => 在单个条目上输出多个 css 文件

前端自动化构建工具Webpack开发模式入门指南

使用 webpack 代码拆分,如何加载块和 HTML 布局?