我尝试做一些我认为应该可行的事情,但我真的无法通过webpack文档了解如何做到这一点。
我正在编写一个包含多个模块的JavaScript库,这些模块可能相互依赖,也可能不相互依赖。最重要的是,jQuery被所有模块使用,其中一些可能需要jQuery插件。然后,该库将用于几个可能需要部分或全部模块的不同网站。
定义我的模块之间的依赖关系非常简单,但定义他们的第三方依赖关系似乎比我预期的更难。
我想要实现的目标:对于每个应用,我希望有两个捆绑文件,一个包含必要的第三方依赖项,另一个包含我库中必需的模块。
示例: 让我们想象一下我的图书馆有以下模块:
我有一个应用程序(将其视为唯一的条目文件),需要模块a,b和c。此案例的Webpack应生成以下文件:
最后,我更倾向于将jQuery作为全局文件,因此我不需要在每个文件上都需要它(例如,我只能在主文件上要求它)。 jQuery插件只会在需要时扩展$ global(如果它们不适用于其他不需要它们的模块,则不会出现问题)。
假设这是可能的,那么这个案例的webpack配置文件的例子是什么?我在我的配置文件中尝试了几种加载器,外部和插件的组合,但我真的不知道他们在做什么以及我应该使用哪些。谢谢!
答案 0 :(得分:135)
在我的webpack.config.js(版本1,2,3)文件中,我有
function isExternal(module) {
var context = module.context;
if (typeof context !== 'string') {
return false;
}
return context.indexOf('node_modules') !== -1;
}
在我的插件数组中
plugins: [
new CommonsChunkPlugin({
name: 'vendors',
minChunks: function(module) {
return isExternal(module);
}
}),
// Other plugins
]
现在我有一个文件,只根据需要将第三方库添加到一个文件中。
如果您希望在分离供应商和入口点文件的位置获得更多细化:
plugins: [
new CommonsChunkPlugin({
name: 'common',
minChunks: function(module, count) {
return !isExternal(module) && count >= 2; // adjustable
}
}),
new CommonsChunkPlugin({
name: 'vendors',
chunks: ['common'],
// or if you have an key value object for your entries
// chunks: Object.keys(entry).concat('common')
minChunks: function(module) {
return isExternal(module);
}
})
]
请注意,插件的顺序非常重要。
此外,这将在版本4中发生变化。当我正式发布时,我会更新此答案。
更新: indexOf对Windows用户的搜索更改
答案 1 :(得分:51)
我不确定我是否完全理解你的问题,但由于我最近有类似的问题,我会尽力帮助你。
供应商捆绑。
您应该使用CommonsChunkPlugin。在配置中,您可以指定块的名称(例如vendor
),以及将生成的文件名(vendor.js
)。
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),
现在重要的是,您必须现在指定vendor
库的含义,并在条目部分执行此操作。还有一个项目到条目列表,其名称与新声明的块名称相同(即,在这种情况下为“#39; vendor'”)。该条目的值应该是您要移动到vendor
包的所有模块的列表。
在你的情况下,它应该看起来像:
entry: {
app: 'entry.js',
vendor: ['jquery', 'jquery.plugin1']
}
JQuery为全球
遇到同样的问题并用ProvidePlugin解决了。在这里,您不是要定义全局对象,而是模块化的类型。即你可以这样配置:
new webpack.ProvidePlugin({
$: "jquery"
})
现在您可以在代码中的任何位置使用$
- webpack会自动将其转换为
require('jquery')
我希望它有所帮助。您还可以查看我的webpack配置文件here
我喜欢webpack,但我同意文档不是世界上最好的文档...但是嘿..人们在开头就对Angular文档说了同样的话:)。
修改强>
让入口点特定的供应商块多次使用CommonsChunkPlugins:
new webpack.optimize.CommonsChunkPlugin("vendor-page1", "vendor-page1.js", Infinity),
new webpack.optimize.CommonsChunkPlugin("vendor-page2", "vendor-page2.js", Infinity),
然后为不同的文件声明不同的extenral库:
entry: {
page1: ['entry.js'],
page2: ['entry2.js'],
"vendor-page1": [
'lodash'
],
"vendor-page2": [
'jquery'
]
},
如果某些库在入口点之间重叠(对于大多数库),那么您可以使用相同的插件将它们提取到公共文件,只是使用不同的配置。请参阅this示例。
答案 2 :(得分:39)
如果您有兴趣自动将脚本与供应商分开捆绑:
<?php
header("Access-Control-Allow-Origin: *");
您可以在official documentation中了解有关此功能的更多信息。
答案 3 :(得分:11)
还不确定我是否完全理解您的情况,但这里是配置代码段为每个捆绑包创建单独的供应商块:
entry: {
bundle1: './build/bundles/bundle1.js',
bundle2: './build/bundles/bundle2.js',
'vendor-bundle1': [
'react',
'react-router'
],
'vendor-bundle2': [
'react',
'react-router',
'flummox',
'immutable'
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor-bundle1',
chunks: ['bundle1'],
filename: 'vendor-bundle1.js',
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor-bundle2',
chunks: ['bundle2'],
filename: 'vendor-bundle2-whatever.js',
minChunks: Infinity
}),
]
并链接到CommonsChunkPlugin
文档:http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin