在多个Browserify或Webpack捆绑包中共享通过NPM加载的模块的简单解决方案
Simple solution to share modules loaded via NPM across multiple Browserify or Webpack bundles
我在这里寻找一个简单的解决方案,通过NPM在多个Browserify或Webpack捆绑包中共享代码。思考,有没有文件"桥"这样的东西?
这并不是因为编译时(我知道watchify),而是希望将所有特定于供应商的库提取到vendor.js
中,这样可以降低app.js
的文件大小,并且不会因为大量的源映射而导致浏览器崩溃。此外,如果需要查看编译后的js,我发现它会更干净。因此:
// vendor.js
require('react');
require('lodash');
require('other-npm-module');
require('another-npm-module');
与Bower相反,从NPM加载代码,或者将代码保存到某个"供应商"目录中,以便通过相对路径导入并通过填充程序进行识别,这一点非常重要。除了我的实际应用程序源之外,我想保留通过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加载的模块?我知道创建一个带有externals的bundle,然后通过别名引用直接文件(比如node_modules
),但我希望找到一个更自动、不那么像"Require.js"的解决方案。
基本上,我想知道是否有可能将两者桥接,以便app.js
可以查看vendor.js
内部以解决依赖关系。这似乎是一个简单、直接的操作,但我似乎在这个广阔的网络上找不到答案。
谢谢!
列出所有供应商文件/模块并使用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允许您指定一个回调,该回调将返回您是否希望模块包含在供应商区块中。如果你自己的源代码在一个特定的src
目录中,其余的在node_modules
目录中,只需根据它们的路径拒绝模块:
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
是到正在考虑的模块的路径。你也可以做相反的事情,如果模块在node_modules_dir
内,只包括它,即:
return module.resource && module.resource.indexOf(node_modules_dir) === 0;
但在我的情况下,我宁愿说:"将不在我的源代码树中的所有内容放在供应商块中"。
希望能有所帮助。
使用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页面中,在bundle.js
之前加载vendor.bundle.js
。
<script src="vendor.bundle.js"></script>
<script src="bundle.js"></script>
// vendor anything coming from node_modules
minChunks: module => /node_modules/.test(module.resource)
来源:https://github.com/webpack/webpack/issues/2372#issuecomment-213149173
- 如何使用url加载程序在webpack中导入多个图像
- 如何在生成下载文件时显示加载动画
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 无法在通过jQuery的ajax加载的页面中执行javascript
- Emberjs应用程序加载在除Index之外的所有路由上
- 在chrome.tabs.onCreated之后加载HTML页面
- 单击F5时如何停止页面加载
- Sails.js:我可以将一些服务/模型打包为npm并在Sails.jss应用程序中加载npm吗
- 在npm中加载一个包的多个版本
- 异步加载 NPM 模块
- "npm运行构建“;模块解析错误”;您可能需要一个适当的加载程序来处理此文件类型&”;
- 如何使用 ClosureCompiler.js 加载 npm 包
- 为什么我的外部托管的 React 组件在通过 NPM 加载时会中断
- NodeJS 服务器在加载页面时抛出“需要更新”,即使在更新到最新的 npm 版本后也是如此
- 使用Browserify加载海盗湾npm模块客户端
- 在多个Browserify或Webpack捆绑包中共享通过NPM加载的模块的简单解决方案
- 错误:加载firebase时出错.如果没有安装,请执行npm install -g firebase-bolt
- 在typescript项目中加载npm模块
- 不能将本地的jquery.js加载到node.js (NPM jsdom)
- 如何在基于 PHP 编辑器的包中从基于 NPM 的包加载资产