将 CommonJS 转换为 AMD
Converting CommonJS to AMD
我在 NPM 和 Bower 上发布了一个简单的 CommonJS 模块,基本上看起来像这样:
function Foo(){}
module.exports = new Foo();
现在转换为 AMD 格式的最简单方法就是发布与 AMD 兼容的第二个版本,如下所示:
define(function (require, exports, module) {
function Foo(){}
module.exports = new Foo();
});
但我认为有一种方法可以使用 requirejs.config 填充 CommonJS 模块,如下所示:
requirejs.config({
paths:{
'foo':'assets/vendor/foo'
},
shim:{
'foo' :{
exports: 'Foo'
}
}
});
但这似乎不起作用。我认为 shim 工具会完成我上面为您所做的包装,但我不完全确定。
问题
shim
无法如您所愿。当 RequireJS 评估你在 exports
中给出的符号时,它会在全局 space 中评估它。因此,如果您可以访问要从全局 space 导出的变量,则使用 exports
可以正常工作。如果库 foo
将 Foo
导出到全局 space,那工作正常。
您想要做的是让一个模块通过 module
导出其 API 并与 shim
一起工作。这是行不通的,因为 RequireJS 无法猜测正在加载的模块需要全局 module
对象已经可用于正在加载的模块。在最简单的情况下,加载此类模块将导致 ReferenceError
,因为 module
不存在。有一些方法可以伪造 module.exports
可以在最微不足道的情况下使用的东西,但它不能作为通用解决方案。
一个解决方案
您可以使用r.js
将以CommonJS 格式编写的文件转换为RequireJS 需要的文件。是documented here。该文档提供了以下概要:
node r.js -convert path/to/commonjs/modules/ path/to/output
您还应该阅读自述文件的 this part 以了解一些注意事项。
我在 NPM 和 Bower 上发布了一个简单的 CommonJS 模块,基本上看起来像这样:
function Foo(){}
module.exports = new Foo();
现在转换为 AMD 格式的最简单方法就是发布与 AMD 兼容的第二个版本,如下所示:
define(function (require, exports, module) {
function Foo(){}
module.exports = new Foo();
});
但我认为有一种方法可以使用 requirejs.config 填充 CommonJS 模块,如下所示:
requirejs.config({
paths:{
'foo':'assets/vendor/foo'
},
shim:{
'foo' :{
exports: 'Foo'
}
}
});
但这似乎不起作用。我认为 shim 工具会完成我上面为您所做的包装,但我不完全确定。
问题
shim
无法如您所愿。当 RequireJS 评估你在 exports
中给出的符号时,它会在全局 space 中评估它。因此,如果您可以访问要从全局 space 导出的变量,则使用 exports
可以正常工作。如果库 foo
将 Foo
导出到全局 space,那工作正常。
您想要做的是让一个模块通过 module
导出其 API 并与 shim
一起工作。这是行不通的,因为 RequireJS 无法猜测正在加载的模块需要全局 module
对象已经可用于正在加载的模块。在最简单的情况下,加载此类模块将导致 ReferenceError
,因为 module
不存在。有一些方法可以伪造 module.exports
可以在最微不足道的情况下使用的东西,但它不能作为通用解决方案。
一个解决方案
您可以使用r.js
将以CommonJS 格式编写的文件转换为RequireJS 需要的文件。是documented here。该文档提供了以下概要:
node r.js -convert path/to/commonjs/modules/ path/to/output
您还应该阅读自述文件的 this part 以了解一些注意事项。