Webpack有两个常见的块:一个是导出的,一个是本地的

Bru*_*uno 16 javascript webpack

我想在多页面应用程序中使用Webpack,这样一些预先确定的依赖项被捆绑到一个"供应商"块中,其余的依赖项被捆绑到一个"commons"块中.

例如,假设有两个入口点(有效地代表每个不同的页面),pageA.jspageB.js包含这个代码(在EC6中,通过Babel处理),然后是他们自己的代码:

import $ from 'jquery';
require('bootstrap/dist/css/bootstrap.css');
import angular from 'angular';
import uitree from 'angular-ui-tree';
Run Code Online (Sandbox Code Playgroud)

我希望将jQuery和Bootstrap捆绑到一个"供应商"块中,然后将其余的(无论是什么)捆绑到一个"commons"块中.

目标是:

  • 我希望能够拥有另一个能够依赖相同供应商块的独立构建,而不需要重新包含供应商库(我会明确声明这组供应商库,以使其可用于任何供应商库)需要它的子构建).
  • 每次我更改页面的脚本时,我也不想重新处理供应商块.

这是我尝试过的配置:

module.exports = {
    entry : {
        "vendor" : [ "jquery", "bootstrap" ],
        "pageA" : "./src/pageA.js",
        "pageB" : "./src/pageB.js"
    },
    output : {
        path : path.join(__dirname, "./dest"),
        filename : "[name].chunk.js"
    },
    module : {
        loaders : [ {
            test : /bootstrap\/js\//,
            loader : 'imports?jQuery=jquery'
        },
        /* ... Some modules for angular and CSS processing ... */

        {
            test : /\.js?$/,
            include : [ path.resolve(__dirname, "./src") ],
            loader : 'babel',
            query : {
                presets : [ 'es2015' ]
            }
        }
        /* ... Some other settings for the fonts ... */ ]
    },
    plugins : [
        new webpack.ProvidePlugin({
            $ : "jquery",
            jQuery : "jquery"
        }),
        new webpack.optimize.UglifyJsPlugin({
            sourceMap : false,
            mangle : false,
            compress : false
        }),
        new CommonsChunkPlugin({
            name : "vendor",
            minChunks : Infinity
        }),
        new CommonsChunkPlugin({
            name : "commons",
            minChunks : 2
        })
    ]
};
Run Code Online (Sandbox Code Playgroud)

通过上面的配置中,我得到的jQuery和引导中vendor.chunk.js,根据需要,但commons.chunk.js文件几乎是空的,一个什么样的普遍使用的所有的休息pageA.jspageB.js再投入pageA.chunk.jspageB.chunk.js(有效复制的代码).

如果我交换最后两个插件的顺序,commons.chunk.js现在几乎包含所有内容(除非实际上特定于pageA.jspageB.js),并且vendor.chunk.js几乎为空:

plugins : [
    // ...,
    new CommonsChunkPlugin({
        name : "commons",
        minChunks : 2
    }),
    new CommonsChunkPlugin({
        name : "vendor",
        minChunks : Infinity
    })
]
Run Code Online (Sandbox Code Playgroud)

有没有办法捆绑一个预定义的库列表(例如,[ "jquery", "jquery-ui", "bootstrap" ]一个特定的块(以完全独立的脚本可以使用的方式),并且还有另一个常见的块,用于条目之间常用的任何其他内容点?

所有这一切的目的是能够在以后为另一个页面构建完全独立的代码片段,并告诉它不需要重新捆绑这些预定义的库.

这是一个表示我想要实现的目标的图表:

依赖关系图

然后,我将使用生成的脚本,如下页A所示:

<script src="vendor.js"></script>
<script src="common.js"></script>
<script src="pageA.chunk.js"></script>
Run Code Online (Sandbox Code Playgroud)

在页面C(完全独立于页面A和B构建):

<script src="vendor.js"></script>
<script src="common2.js"></script>
<script src="pageC.chunk.js"></script>
Run Code Online (Sandbox Code Playgroud)

(我使用的是Webpack 1.12.14.)


到目前为止,我已经尝试了唯一答案中提出的解决方案.虽然这使得确实可以将供应商块与公共块分开,但是由两个单独的构建制成的供应商块(具有相同的定义)通常不能在彼此之间交换.这使得只能在两个构建中使用这些供应商块中的一个(即使它们实际上是相同的).

jon*_*wig 10

我正在做类似的事情.我通过这种配置观察了你想要的行为:

const entryPath = path.resolve(__dirname, "src", "modules"),
    entryPoints = {
        vendor: ["babel-polyfill", "react", "react-dom", "react-pure-render", "react-simpletabs", "react-redux", "redux", "redux-thunk"],
        a: entryPath + "/a.js",
        b: entryPath + "/b.js",
        c: entryPath + "/c.js",
        d: entryPath + "/d.js",
        ...
    }, plugins = [
        new CommonsChunkPlugin({
            name: "commons",
            filename: "commons.bundle.js",
            minChunks: 2,
            chunks: Object.keys(entryPoints).filter(key => key !== "vendor")
        }),
        new CommonsChunkPlugin("vendor", "vendor.bundle.js"),
        new ExtractTextPlugin("[name].bundle.css", {
            //allChunks: true
        })
    ];
Run Code Online (Sandbox Code Playgroud)

所以上面的代码留在b.bundle.js中仍然有一些React和其他React库的导入.在我将"fixed-data-table"添加到供应商列表后,消失了,唯一的反应源代码是在vendor.bundle.js中我认为这就是你要找的东西?(最后,每个供应商列表中未列出的供应商最终都在每个自己的module.bundle.js或commons.bundle.js中,如果它在多个包中重复使用的话)

关心乔纳斯