如何在Closure Compiler中将node_modules定义为externs? [英] How do you define node_modules as externs in Closure Compiler?

查看:102
本文介绍了如何在Closure Compiler中将node_modules定义为externs?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Node.js项目,我想用Closure Compiler编译。我不希望它在浏览器中运行/使用browserify。我主要想要类型检查的实用程序。我最初使用以下代码使编译器正常工作:

I have a Node.js project that I want to compile with Closure Compiler. I do not want it to run in the browser/use browserify. I mainly want the utility of type checking. I originally got the compiler to work correctly using the following:

java -jar compiler.jar -W VERBOSE 
                       --language_in ECMASCRIPT5_STRICT 
                       --externs closure-externs.js 
                       --js="lib/**.js"

其中 closure-externs.js 我以相当粗略的方式从Node.js手动定义的变量和函数:

Where closure-externs.js manually defined variables and functions which I was using from Node.js in a rather crude way:

// closure-externs.js

/** @constructor */function Buffer(something){}
function require(path){}
var process = {};
[...]

事实证明,这只能通过纯粹的运气来实现。文件之间没有依赖关系跟踪,因此您可以在这种情况下返回类型 {Foo} ,并且编译器会抱怨它不存在(取决于机器) ,取决于编译顺序)。然后我发现我做错了,应该使用 - process_common_js_modules 所以编译器会在我 require(foo)的地方进行依赖关系跟踪)。我目前正在调用这样的编译器:

It turns out that this worked only through sheer luck. There is no dependency tracking between files, so you can have cases where you return a type {Foo} and the compiler will complain that it doesn't exist (depending on the machine, depending on the compile order). I then found out I was doing it all wrong and should be using --process_common_js_modules so the compiler will do dependency tracking where I require("foo"). I am currently invoking the compiler like so:

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_module中s 喜欢 q 。我不想通过编译器运行这些外部模块,所以我知道我需要为它们设置 externs 文件。我知道有 https://github.com/dcodeIO/node.js-closure常见Node.js externs的-compiler-externs ,我知道如何在编译器上调用它们,但出于某些原因,当我执行类似的操作时 - externs externs / fs.js 模块$ fs 的错误仍然存​​在。我做错了什么?

Some of these modules are native to Node.js (e.g. fs) whereas others are contained in node_modules like q. I don't want to run these external modules through the compiler, so I know I need to set up externs file(s) for them. I know there is https://github.com/dcodeIO/node.js-closure-compiler-externs for common Node.js externs, and I know how to invoke them on the compiler, but for some reason when I do something like --externs externs/fs.js the error for module$fs remains. What am I doing wrong?

我知道还有其他标志,如 - 模块 --common_js_module_path_prefix 但我不确定是否需要使用它们才能使其工作。我的Google-fu未能在这里找到关于正确咒语的任何答案。 :(

I know there's other flags like --module and --common_js_module_path_prefix but I'm not sure if I need to use them to get this to work or not. My Google-fu has failed to come up with any answers on the correct incantation here. :(

推荐答案

问题是您希望编译器以某种方式识别某些 require 调用是内部的,即所需的模块应该由编译器作为源处理,而其他的是外部的,所以应该保持独立。目前没有一种好方法来处理这种情况。

The issue is that you wish for the compiler to somehow recognize that certain require calls are internal, namely that the required module should be processed by the compiler as source, and others are external so should be left alone. There isn't a good way to handle this situation currently.

在这种情况下,您将完全省略任何 require 语句到外部模块。编译器只处理带有内部require语句和模块的代码。编译之后,您将预先设置外部需求声明:

In this scenario you would completely omit any require statements to external modules. The compiler would only process code with internal require statements and modules. After compilation, you would prepend the external require statements:

var crypto = require('crypto');



要编译的来源



Source To Be Compiled

console.log(crypto);

因为 crypto 在extern中声明,编译器将正确识别类型和符号名称。

Because crypto is declared in an extern, the compiler will correctly recognize the type and symbol name.

当指定 - process_common_js_modules 时,编译器会识别 require 声明并以与宏在其他语言中工作的方式类似的方式扩展它们。通过别名应保留在外部的 require 语句,编译器将无法识别它们,因此不会扩展它们。

When the --process_common_js_modules is specified, the compiler recognizes require statements and expands them in a similar fashion to the way macros work in other languages. By aliasing the require statements that should remain external, the compiler will not recognize them and thus not expand them.

var externalRequire = require;
/** @suppress {duplicate} this is already defined in externs */
var crypto = externalRequire('crypto');
console.log(crypto)

这篇关于如何在Closure Compiler中将node_modules定义为externs?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆