简单的解决scheme可以通过多个Browserify或Webpack软件包共享通过NPM加载的模块
将我的头发拉到这里寻找一个简单的解决scheme,通过NPM,跨多个Browserify或Webpack包共享代码。 思考,是否有文件“桥梁”这样的事情?
这不是由于编译时间(我意识到watchify),而是希望将所有供应商特定库vendor.js
到vendor.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.js
和vendor.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模块: fastclick
和mprogress
。 由于他们还没有采用CommonJS模块格式,所以你需要给webpack一个手,就像这样:
require('imports?define=>false!fastclick')(document.body); require('mprogress/mprogress.min.css'); var Mprogress = require('mprogress/mprogress.min.js'),
现在假设你想在你的供应商块中同时使用fastclick
和mprogress
,你可能会试试这个:
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