简单的解决scheme可以通过多个Browserify或Webpack软件包共享通过NPM加载的模块

将我的头发拉到这里寻找一个简单的解决scheme,通过NPM,跨多个Browserify或Webpack包共享代码。 思考,是否有文件“桥梁”这样的事情?

这不是由于编译时间(我意识到watchify),而是希望将所有供应商特定库vendor.jsvendor.js以便保持我的app.js文件大小,并且不会使浏览器崩溃sourcemaps。 另外,如果需要查看编译后的js,我觉得它更清洁。 所以:

 // vendor.js require('react'); require('lodash'); require('other-npm-module'); require('another-npm-module'); 

非常重要的一点是,代码必须从NPM加载而不是Bower加载,或者保存到某个“供应商”目录中,以便通过相对path导入并通过填充程序标识。 我想保留通过NPM拉除每个库参考,除了我的实际应用程序源。

app.js我保留了所有的源代码,并通过externals数组,从编译中排除了上面列出的供应商库:

 // app.js var React = require('react'); var _ = require('lodash'); var Component = React.createClass() // ... 

然后在index.html ,我需要这两个文件

 // index.html <script src='vendor.js'></script> <script src='app.js'></script> 

使用Browserify或Webpack,我怎样才能使app.js能够“看到”通过npm加载的模块? 我知道创build一个与外部的捆绑,然后通过别名引用直接文件(在,例如node_modules ),但我希望find一个更自动的解决scheme,更less的“Require.js”像。

基本上,我想知道是否有可能桥接两个,以便app.js可以查看内部vendor.js为了解决依赖关系。 这似乎是一个简单,直接的操作,但我似乎无法在这个宽广的networking上的任何地方find答案。

谢谢!

使用webpack你可以使用多个入口点和CommonChunkPlugin 。

采取从webpack文档 :


要将您的应用分成两个文件,比如app.jsvendor.js ,您可以要求vendor.js的供应商文件。 然后将此名称传递给CommonChunkPlugin,如下所示。

 module.exports = { entry: { app: "./app.js", vendor: ["jquery", "underscore", ...], }, output: { filename: "bundle.js" }, plugins: [ new webpack.optimize.CommonsChunkPlugin( /* chunkName= */"vendor", /* filename= */"vendor.bundle.js" ) ] }; 

这将从应用程序块中删除供应商块中的所有模块。 bundle.js现在只包含你的应用程序代码,没有任何依赖关系。 这些在vendor.bundle.js

在你的HTML页面中,在vendor.bundle.js之前加载bundle.js

 <script src="vendor.bundle.js"></script> <script src="bundle.js"></script> 

列出所有供应商文件/模块并使用CommonChunkPlugin确实是推荐的方法。 这虽然很乏味,而且容易出错。

考虑这些NPM模块: fastclickmprogress 。 由于他们还没有采用CommonJS模块格式,所以你需要给webpack一个手,就像这样:

 require('imports?define=>false!fastclick')(document.body); require('mprogress/mprogress.min.css'); var Mprogress = require('mprogress/mprogress.min.js'), 

现在假设你想在你的供应商块中同时使用fastclickmprogress ,你可能会试试这个:

 module.exports = { entry: { app: "./app.js", vendor: ["fastclick", "mprogress", ...] 

唉,这是行不通的。 您需要将调用与require()匹配:

 module.exports = { entry: { app: "./app.js", vendor: [ "imports?define=>false!fastclick", "mprogress/mprogress.min.css", "mprogress/mprogress.min.js", ...] 

它变老,即使有一些resolve.alias欺骗。 这是我的解决方法。 CommonChunkPlugin允许你指定一个callback函数,不pipe你是否想要一个模块被包含在供应商块中。 如果您的源代码位于特定的src目录中,而其余的位于node_modules目录中,则只需根据其path拒绝这些模块:

 var node_modules_dir = path.join(__dirname, 'node_modules'), app_dir = path.join(__dirname, 'src'); module.exports = { entry: { app: "./app.js", }, output: { filename: "bundle.js" }, plugins: [ new webpack.optimize.CommonsChunkPlugin( /* chunkName= */"vendor", /* filename= */"vendor.bundle.js" function (module, count) { return module.resource && module.resource.indexOf(app_dir) === -1; } ) ] }; 

其中module.resource是正在考虑的模块的path。 你也可以做相反的事情,只包含模块,如果它在node_modules_dir ,即:

  return module.resource && module.resource.indexOf(node_modules_dir) === 0; 

但在我的情况下,我宁愿说:“ 把不在我的源代码树中的所有东西放在供应商块中 ”。

希望有所帮助。

 // vendor anything coming from node_modules minChunks: module => /node_modules/.test(module.resource) 

资料来源: https : //github.com/webpack/webpack/issues/2372#issuecomment-213149173