如何分开捆绑供应商脚本,并根据需要使用Webpack?

我试图做一些我认为应该可能的事情,但是我真的不明白如何从webpack文档(在我看来这是一个解密和理解的地狱)中做到这一点。

我正在编写一个JavaScript库,其中有几个模块可能不相互依赖。 最重要的是,jQuery被所有模块使用,其中一些可能需要jQuery插件。 这个图书馆将被用于几个不同的网站,这可能需要一些或所有的模块。

定义我的模块之间的依赖关系非常简单,但是定义他们的第三方依赖关系似乎比我想象的要困难得多。

我想达到什么目的 :对于每个网站,我想有两个捆绑文件,其中一个具有必要的第三方依赖关系,另一个具有来自我的库的必要模块。

示例 :让我们想象一下,我的库有以下模块:

  • 一个(需要:jquery,jquery.plugin1)
  • b(需要:jquery,a)
  • c(需要:jquery,jquery.ui,a,b)
  • d(需要:jquery,jquery.plugin2,a)

我有一个网站(见它作为一个独特的入口文件),需要模块a,b和c。 这种情况下的Webpack应该生成以下文件:

  • 供应商捆绑 :与jquery,jquery.plugin1和jquery.ui;
  • 网站包 :模块a,b和c;

最后,我宁愿将jQuery作为一个全局的,所以我不需要在每个单独的文件(例如,我可能只需要在主文件,例如)要求它。 而且jQuery插件只会扩展$ global,以防需要它们(如果其他模块不需要这些模块,则不会有问题)。

假设这是可能的,这种情况下的webpackconfiguration文件的例子是什么? 我在configuration文件上尝试了几个加载器,外部和插件的组合,但是我并没有真正明白他们在做什么,应该使用哪些。 谢谢!

在我的webpack.config.js文件中,我有

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); } }) ] 

请注意,插件的顺序很重要。

更新: indexOfsearch更改为Windows用户

我不知道我是否完全理解你的问题,但由于我最近有类似的问题,我会尽力帮助你。

供应商捆绑。

你应该使用CommonsChunkPlugin 。 在configuration中指定块(例如vendor )的名称和将生成的文件名( vendor.js )。

 new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity), 

现在重要的部分,你现在必须指定什么是vendor库,你在一个入口部分。 一个多一个入口列表,其名称与新声明的块(即本例中的“供应商”)名称相同。 该条目的值应该是您要移动到vendor捆绑的所有模块的列表。 在你的情况下,它应该看起来像这样:

 entry: { app: 'entry.js', vendor: ['jquery', 'jquery.plugin1'] } 

JQuery作为全球

有同样的问题,并与ProvidePlugin解决它。 在这里你没有定义全局对象,而是模块的一个shurtcut。 即你可以像这样configuration它:

 new webpack.ProvidePlugin({ $: "jquery" }) 

现在你可以在你的代码中任何地方使用$ – webpack会自动将其转换为

 require('jquery') 

我希望它有帮助。 你也可以看看我在这里的 webpackconfiguration文件

我喜欢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' ] }, 

如果某些库在入口点之间重叠(以及大多数库),则可以使用相同的插件将其提取到通用文件,只是使用不同的configuration。 看到这个例子。

如果你有兴趣自动捆绑你的脚本与供应商分开:

 var webpack = require('webpack'), pkg = require('./package.json'), //loads npm config file html = require('html-webpack-plugin'); module.exports = { context : __dirname + '/app', entry : { app : __dirname + '/app/index.js', vendor : Object.keys(pkg.dependencies) //get npm vendors deps from config }, output : { path : __dirname + '/dist', filename : 'app.min-[hash:6].js' }, plugins: [ //Finally add this line to bundle the vendor code separately new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.min-[hash:6].js'), new html({template : __dirname + '/app/index.html'}) ] }; 

您可以在官方文档中阅读有关此function的更多信息。

也不知道如果我完全理解你的情况,但这里是configuration片段为您的每个捆绑包创build单独的供应商块:

 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 : CommonsChunkPlugin

Interesting Posts