库依赖项中的匿名 define() 模块导致库的依赖项损坏
Anonymous define() module in library's dependencies causes breakage for library's dependents
我正在开发一个用于许多 Web 应用程序的库。该库本身不使用 RequireJS——它是用 node 编写的,然后与 browserify 捆绑在一起——但是,它的一些依赖项正在使用 RequireJS shim 来包含该库。
我们发现,如果我们的库依赖于包含匿名定义模块的库,例如来自 lodash 的这个库,我们的依赖者使用的 RequireJS shim 就会中断并出现 "mismatched anonymous define()" 错误来源:
// Define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module.
define(function() {
return _;
});
我找到了关于这个问题的RequireJS documentation;但它的所有解决方案似乎都假设使用匿名模块导入库的库正在使用 RequireJS,但这里不是这种情况。
我该如何处理才能让下游库不需要做任何特殊处理来请求我们的库?理想情况下,如果我们不必为每个使用匿名模块定义的库添加自定义逻辑,那就太好了。
您可以尝试使用 Browserify standalone
选项和 derequire.
捆绑您的应用程序
也许您在 lodash 上使用了 derequire,然后使用 standalone
选项捆绑了您的应用程序。
以下内容来自Browserify documentation:
When opts.standalone
is a non-empty string, a standalone module is
created with that name and a
umd wrapper. You can use
namespaces in the standalone global export using a .
in the string
name as a separator. For example: 'A.B.C'
Note that in standalone mode the require()
calls from the original
source will still be around, which may trip up AMD loaders scanning
for require()
calls. You can remove these calls with
derequire:
$ npm install -g derequire $ browserify main.js --standalone Foo |
derequire > bundle.js
opts.insertGlobalVars
will be passed to
insert-module-globals
as the opts.vars
parameter.
opts.externalRequireName
defaults to 'require'
in expose
mode
but you can use another name.
Note that if files do not contain javascript source code then you also
need to specify a corresponding transform for them.
All other options are forwarded along to
module-deps and
browser-pack directly.
您还可以在 http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds
找到有关独立选项的很好的教程
所以我最终做的是将 requirejs 优化器导入 browserify 项目,运行 所有包含匿名的文件都通过 requirejs 优化器定义模块,然后通过 browerify transform
函数。
代码看起来像这样:
//Kept an explicit list of things to requirejs optimize, to avoid running every file through the optimizer
var modulesToRequireJSOptimize = ["lodash"];
var lib = browserify();
//...
lib.transform(requireJSOptimize, {global: true}); //global true to apply it to the modules
function requireJSOptimize(file) {
var moduleName;
//Determine if the file is one of the modules we need to optimize
modulesToRequireJSOptimize.forEach(function(mod) {
if(require.resolve(mod) === file) {
moduleName = mod;
}
}
if(!moduleName) {
return through(); //do nothing
}
var end = function() {
var pipe = this;
var optimizerConfig = {
name: moduleName
optimize: "none" //don't minify
paths: {}
out: function(optimizedJS) {
this.queue(optimizedJS);
this.queue(null);
}
}
//strip off .js
optimizerConfig.paths[moduleName] = file.substr(0, file.length-3)
requirejs.optimize(optimizerConfig,
function() {}, //success handled in optimizerConfig.out
function(err) {} //handle err here
);
};
return through(function () {}, end);
}
它不是很漂亮,但它对我们的目的有用。我建议其他人首先尝试 OweR ReLoaDeD 的独立+取消要求,但我想为了完整起见我会分享我的最终解决方案。
我正在开发一个用于许多 Web 应用程序的库。该库本身不使用 RequireJS——它是用 node 编写的,然后与 browserify 捆绑在一起——但是,它的一些依赖项正在使用 RequireJS shim 来包含该库。
我们发现,如果我们的库依赖于包含匿名定义模块的库,例如来自 lodash 的这个库,我们的依赖者使用的 RequireJS shim 就会中断并出现 "mismatched anonymous define()" 错误来源:
// Define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module.
define(function() {
return _;
});
我找到了关于这个问题的RequireJS documentation;但它的所有解决方案似乎都假设使用匿名模块导入库的库正在使用 RequireJS,但这里不是这种情况。
我该如何处理才能让下游库不需要做任何特殊处理来请求我们的库?理想情况下,如果我们不必为每个使用匿名模块定义的库添加自定义逻辑,那就太好了。
您可以尝试使用 Browserify standalone
选项和 derequire.
也许您在 lodash 上使用了 derequire,然后使用 standalone
选项捆绑了您的应用程序。
以下内容来自Browserify documentation:
When
opts.standalone
is a non-empty string, a standalone module is created with that name and a umd wrapper. You can use namespaces in the standalone global export using a.
in the string name as a separator. For example:'A.B.C'
Note that in standalone mode the
require()
calls from the original source will still be around, which may trip up AMD loaders scanning forrequire()
calls. You can remove these calls with derequire:
$ npm install -g derequire $ browserify main.js --standalone Foo | derequire > bundle.js
opts.insertGlobalVars
will be passed to insert-module-globals as theopts.vars
parameter.
opts.externalRequireName
defaults to'require'
inexpose
mode but you can use another name.Note that if files do not contain javascript source code then you also need to specify a corresponding transform for them.
All other options are forwarded along to module-deps and browser-pack directly.
您还可以在 http://www.forbeslindesay.co.uk/post/46324645400/standalone-browserify-builds
找到有关独立选项的很好的教程所以我最终做的是将 requirejs 优化器导入 browserify 项目,运行 所有包含匿名的文件都通过 requirejs 优化器定义模块,然后通过 browerify transform
函数。
代码看起来像这样:
//Kept an explicit list of things to requirejs optimize, to avoid running every file through the optimizer
var modulesToRequireJSOptimize = ["lodash"];
var lib = browserify();
//...
lib.transform(requireJSOptimize, {global: true}); //global true to apply it to the modules
function requireJSOptimize(file) {
var moduleName;
//Determine if the file is one of the modules we need to optimize
modulesToRequireJSOptimize.forEach(function(mod) {
if(require.resolve(mod) === file) {
moduleName = mod;
}
}
if(!moduleName) {
return through(); //do nothing
}
var end = function() {
var pipe = this;
var optimizerConfig = {
name: moduleName
optimize: "none" //don't minify
paths: {}
out: function(optimizedJS) {
this.queue(optimizedJS);
this.queue(null);
}
}
//strip off .js
optimizerConfig.paths[moduleName] = file.substr(0, file.length-3)
requirejs.optimize(optimizerConfig,
function() {}, //success handled in optimizerConfig.out
function(err) {} //handle err here
);
};
return through(function () {}, end);
}
它不是很漂亮,但它对我们的目的有用。我建议其他人首先尝试 OweR ReLoaDeD 的独立+取消要求,但我想为了完整起见我会分享我的最终解决方案。