Javascript 包含两个常用块的网页包:一个导出,一个本地
我希望在多页应用程序中使用Webpack,将一些预先确定的依赖项绑定到“供应商”块中,其余依赖项绑定到“公共”块中 例如,假设两个入口点(有效地分别表示不同的页面),Javascript 包含两个常用块的网页包:一个导出,一个本地,javascript,webpack,Javascript,Webpack,我希望在多页应用程序中使用Webpack,将一些预先确定的依赖项绑定到“供应商”块中,其余依赖项绑定到“公共”块中 例如,假设两个入口点(有效地分别表示不同的页面),pageA.js和pageB.js包含这两个代码(在EC6中,通过Babel处理),然后是它们自己的代码: import $ from 'jquery'; require('bootstrap/dist/css/bootstrap.css'); import angular from 'angular'; import uitree
pageA.js
和pageB.js
包含这两个代码(在EC6中,通过Babel处理),然后是它们自己的代码:
import $ from 'jquery';
require('bootstrap/dist/css/bootstrap.css');
import angular from 'angular';
import uitree from 'angular-ui-tree';
我希望jQuery和Bootstrap被绑定到一个“供应商”块中,其余的(不管是什么)被绑定到一个“公共”块中
目标是:
- 我希望能够有另一个独立的构建,能够依赖同一个供应商区块,而不需要重新包含供应商库(我将明确声明这组供应商库,以使其可用于任何需要它的子构建)
- 我也不希望每次更改页面脚本时都必须重新处理供应商区块
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
})
]
};
通过上面的配置,我根据需要在vendor.chunk.js
中获得jQuery和Bootstrap,但是commons.chunk.js
文件几乎是空的,然后将pageA.js
和pageB.js
常用的所有其他内容放入pageA.chunk.js
和pageB.chunk.js
(有效地复制了该代码)
如果我交换最后两个插件的顺序,commons.chunk.js
现在几乎包含了所有内容(除非实际特定于pageA.js
和pageB.js
),而vendor.chunk.js
几乎是空的:
plugins : [
// ...,
new CommonsChunkPlugin({
name : "commons",
minChunks : 2
}),
new CommonsChunkPlugin({
name : "vendor",
minChunks : Infinity
})
]
是否有一种方法可以将预定义的库列表(例如,[“jquery”、“jquery ui”、“bootstrap”]
捆绑到一个特定的块中(以这样一种方式,它可以被完全独立的脚本使用),并且对于入口点之间常用的任何其他块,还有另一个公共块
所有这些的目的是能够为以后的另一个页面构建一段完全独立的代码,并告诉它不需要重新绑定那些预定义的库
下面是一个图表,表示我正在努力实现的目标:
然后,我将在A页上使用生成的脚本,如下所示:
<script src="vendor.js"></script>
<script src="common.js"></script>
<script src="pageA.chunk.js"></script>
第C页(完全独立于A页和B页):
(我正在使用网页1.12.14。)
我已经尝试了中建议的解决方案。虽然这确实可以将供应商区块与公共区块分开,但从两个独立构建中生成的供应商区块(具有相同定义)通常不能相互交换。这不可能在两个构建中仅使用其中一个供应商区块(尽管它们实际上是相同的)。我正在做一些类似的事情。我通过以下配置观察到了您想要的行为:
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
})
];
因此,b.bundle.js中的上述代码仍然导入了React和其他React库。在我将“fixed data table”添加到供应商列表后,它消失了,并且唯一的React源代码出现在vendor.bundle.js中,我想这就是您要寻找的?(最终,未在供应商列表中列出的每个供应商都会出现在各自的module.bundle.js或commons.bundle.js中(如果在多个bundle中重复使用)
问候
Jonas如果您要求能够使用在一个webpack构建中创建的供应商区块和另一个构建中的捆绑包,我发现唯一的方法是通过和
外部
的组合
在我的例子中,我成功地将jQuery(和引导)捆绑到一个构建中的“common.js”中,然后在属于另一个构建的模块中使用该jQuery,如下所示:
1.从构建块中公开jQuery
2.在构建B模块中使用jQuery
当然,这样做的缺点是,您通过使用手动管理的全局变量在两组bundle之间架桥,您可能开始使用webpack来避免:-)
但是,鉴于每个webpack构建都在内部为引用模块创建自己的“私有”ID命名空间,而不保证稳定性或全局唯一性,我不知道还有其他方法。旁注:使用新的CommonChunkPlugin({name:“vendor”,filename:“vendor.bundle.js”,chunks:[“vendor”],minChunks:Infinity})而不是新的CommonChunkPlugin(“vendor”,“vendor.bundle.js”)不起作用。谢谢。它似乎在分离vendor和commons库方面起作用,但仍然缺少一个方面(或者至少我无法让它起作用):能够从单独的子项目(“C页”)中重复使用相同的
vendor.bundle.js
在我的示例中)。我尝试构建两个子项目(重命名“供应商”和“公共”输出),并使一个页面使用另一个的“供应商”文件,但不起作用。我似乎无法获得任何可用的供应商捆绑包,与webpack项目无关。@jonas.hartwig您提到您添加了“固定数据表”添加到您的供应商列表以解决common.js中显示的一些react代码的问题。您能否详细说明添加“fixed data table”的含义?谢谢!是的,在webpack中您有条目配置。其中一部分是供应商列表(如果您需要,将npm包列表添加到vendor.js中):
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
})
];
module: {
loaders: [
{
// export jQuery globals for other modules to use as externals
test: require.resolve('jquery'),
loader: 'expose?$!expose?jQuery'
}
]
}
externals: {
'jquery': 'jQuery'
}