你如何在Closure Compiler中将node_modules定义为extern?
我有一个Node.js项目,我想用Closure编译器进行编译。 我不希望它运行在浏览器/使用browserify。 我主要希望types检查的效用。 我最初得到编译器使用以下正确工作:
java -jar compiler.jar -W VERBOSE --language_in ECMASCRIPT5_STRICT --externs closure-externs.js --js="lib/**.js"
其中closure-externs.js
手动定义了我从Node.js中使用的variables和函数:
// closure-externs.js /** @constructor */function Buffer(something){} function require(path){} var process = {}; [...]
事实certificate,这只是通过运气好运。 在文件之间没有依赖关系跟踪,所以你可以有返回types{Foo}
,编译器会抱怨它不存在(取决于机器,取决于编译顺序)。 然后我发现我所做的一切都是错误的,应该使用--process_common_js_modules
这样编译器就会在require("foo")
地方执行依赖关系跟踪。 我目前正在调用编译器像这样:
java -jar compiler.jar -W VERBOSE --language_in ECMASCRIPT5_STRICT --externs externs/fs.js --js="lib/**.js" --process_common_js_modules --common_js_entry_module app.js
但是这是失败的:
ERROR - required entry point "module$crypto" never provided ERROR - required entry point "module$dgram" never provided ERROR - required entry point "module$extend" never provided ERROR - required entry point "module$fs" never provided ERROR - required entry point "module$net" never provided ERROR - required entry point "module$q" never provided
其中一些模块是Node.js(例如fs
)的本地模块,而其他模块则包含在node_modules
如q
。 我不想通过编译器运行这些外部模块,所以我知道我需要为它们设置externs
文件。 我知道对于常见的Node.js externs,有https://github.com/dcodeIO/node.js-closure-compiler-externs ,而且我知道如何在编译器上调用它们,但由于某种原因,当我做类似--externs externs/fs.js
module$fs
的错误依然存在。 我究竟做错了什么?
我知道还有其他的标志,如 – 模块和--common_js_module_path_prefix
但我不知道是否需要使用它们来得到这个工作与否。 我的Google-fu在这里没有提出任何正确的咒语的答案。 🙁
问题是你希望编译器能够以某种方式认识到某些require
调用是内部的,即所需的模块应该由编译器作为源处理,而其他模块则是外部的,所以应该单独保留。 目前没有一种好的办法来处理这种情况。
解决方法
使用后处理添加外部需求语句
在这种情况下,您可以完全省略任何对外部模块的require
语句。 编译器只会处理带有内部require语句和模块的代码。 编译之后,你可以预先configuration外部的require语句:
标题JS将被预置
var crypto = require('crypto');
来源编译
console.log(crypto);
由于crypto
是在extern中声明的,因此编译器将正确识别types和符号名称。
别名需要调用
当指定了--process_common_js_modules
,编译器会识别require
语句,并以与macros在其他语言中工作的方式类似的方式进行扩展。 通过混淆应该保持外部的require
语句,编译器将不会识别它们,因此不会扩展它们。
来源编译
var externalRequire = require; /** @suppress {duplicate} this is already defined in externs */ var crypto = externalRequire('crypto'); console.log(crypto)