如何将同构的 commonJS 代码与 webpack 捆绑在一起
How to bundle isomorphic commonJS code with webpack
我有一个使用nodeJS模块格式(commonJS(的项目,也应该(部分(在浏览器中运行。
我确实有非同构代码路径,其中我有条件地包含模块:
var impl;
try {
// in node, use node-impl
impl = require('../node-impl');
} catch (err) {
// running in browser, use browser-impl
impl = require('../browser-impl');
}
现在,我想使用 webpack
创建一个在浏览器中运行的捆绑包。因此,我需要将外部(特定于nodeJS(模块定义为webpack.config.js
中的external
模块,以便它们不会包含在捆绑包中:
external: {
'../node-impl': true
}
我验证了"../node-impl' 代码实际上不包含在捆绑包中,但发出的代码如下所示:
/***/ },
/* 33 */
/***/ function(module, exports) {
module.exports = ../node-impl;
/***/ },
这是语法错误的JS,浏览器将在那里抛出语法错误。
如何使用 webpack.js 正确处理这种情况?请注意,我不希望使用 webpack 来运行 nodeJS,只应该使用 webpack 创建浏览器捆绑包。
// Your actual situation:
var impl;
try {
impl = require('../node-impl');
} catch(e) {
impl = require('../browser-impl');
}
您需要将此代码段重构为:
var impl = require('../node-impl');
在此返工之后,您的代码只能在节点 js 环境中工作,这很好,因为我们将在捆绑浏览器时模拟此请求......
// webpack.browser.config.js
module.exports = {
resolve: {
alias: {
'../node-impl': '../browser-impl'
}
}
};
Webpack - Resolve.Alias或使用package.json#browser
或 https://webpack.github.io/docs/configuration.html#resolve-packagealias
我不认为这是外部配置的预期目的。根据文档,
指定不应由 webpack 解析的依赖项,但应成为生成的捆绑包的依赖项。依赖关系的类型取决于 output.libraryTarget。
所以你告诉 webpack 你的构建需要那个模块,而不是捆绑它。它省略了它,但试图要求它。
可能有几种方法可以做你想做的事情。值得一提的是,您可以轻松地让 webpack 从单个配置文件生成具有不同/共享配置的多个构建,这开辟了很多可能性。但我建议的方法是使用 DefinePlugin 定义一个表示执行上下文的布尔"常量"(例如 IN_BROWSER = true
(。在require()
周围的条件中检查该常量。Webpack 的解析器不是那么聪明,但它可以评估布尔变量,因此它将正确解析条件并且只需要适当的模块。(使用非布尔值,如 CONTEXT = 'browser'
对于 webpack 来说太混乱了,它会解析每个 require 语句。然后,您可以使用 Uglify 插件删除条件中的"死代码",这样它就不会使您的生产构建膨胀。
在@Hitmands的帮助下,我可以想出一个仍然不完美但符合我需求的解决方案。我引入一个虚构的nonexistingmodule
并将其声明为外部;然后,我将node-impl
特定模块声明为nonexistingmodule
:
externals: {
'nonexistingmodule': true,
'../node-impl': 'nonexistingmodule'
}
这样,我可以保留try/catch
模式来加载特定的实现,并且它仍然可以在节点上运行。在浏览器中,nonexistingmodule
加载失败,并且加载了browser-impl
模块 - 正如我所希望的那样。
我是"不要重构代码以匹配工具"的忠实粉丝,所以我使用这个解决方案。
- 将依赖外部库的UMD模块与browserfy捆绑在一起
- 如何将具有相同功能的两个select html标签的两个JS组合在一起
- 将3个函数合并在一起
- 使用javascript将两个输入的日期添加在一起
- 避免将lib依赖项与webpack+handlebas加载程序捆绑在一起
- PHP、Javascript和SQL代码混杂在一起
- 有没有办法把它们串在一起,这样它们基本上可以同时工作
- PHP:同时循环元素粘在一起
- 把两个数字加在一起,得到5+10=510,而不是15
- 我怎样把这些剧本写在一起
- 安全地包装JS文件,这样当它们连接在一起时,它们仍然可以工作
- 如何将遗留的js文件与webpack捆绑在一起
- 在 JavaScript 中使用侦听器将输入字段链接在一起
- 如何将表链接在一起
- 如何有效地匹配两个不同 JavaScript 对象上的 id,并将它们合并在一起
- 我想通过单击按钮将 2 个 php 文件链接在一起
- 如何修复 Webpack 在生产中篡改我的代码
- 将js应用程序与webpack捆绑在一起,以获得wordpress插件
- 如何将同构的 commonJS 代码与 webpack 捆绑在一起
- 当将 JavaScript 与 Webpack 捆绑在一起时,require/import URL 开头的 @ 符号是什