admin管理员组文章数量:1335386
I have a Node.js project that I want to pile 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 piler to work correctly using the following:
java -jar piler.jar -W VERBOSE
--language_in ECMASCRIPT5_STRICT
--externs closure-externs.js
--js="lib/**.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 = {};
[...]
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 piler will plain that it doesn't exist (depending on the machine, depending on the pile order). I then found out I was doing it all wrong and should be using --process_mon_js_modules
so the piler will do dependency tracking where I require("foo")
. I am currently invoking the piler like so:
java -jar piler.jar -W VERBOSE
--language_in ECMASCRIPT5_STRICT
--externs externs/fs.js
--js="lib/**.js"
--process_mon_js_modules
--mon_js_entry_module app.js
But this is failing with:
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
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 piler, so I know I need to set up externs
file(s) for them. I know there is .js-closure-piler-externs for mon Node.js externs, and I know how to invoke them on the piler, but for some reason when I do something like --externs externs/fs.js
the error for module$fs
remains. What am I doing wrong?
I know there's other flags like --module
and --mon_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 e up with any answers on the correct incantation here. :(
I have a Node.js project that I want to pile 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 piler to work correctly using the following:
java -jar piler.jar -W VERBOSE
--language_in ECMASCRIPT5_STRICT
--externs closure-externs.js
--js="lib/**.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 = {};
[...]
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 piler will plain that it doesn't exist (depending on the machine, depending on the pile order). I then found out I was doing it all wrong and should be using --process_mon_js_modules
so the piler will do dependency tracking where I require("foo")
. I am currently invoking the piler like so:
java -jar piler.jar -W VERBOSE
--language_in ECMASCRIPT5_STRICT
--externs externs/fs.js
--js="lib/**.js"
--process_mon_js_modules
--mon_js_entry_module app.js
But this is failing with:
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
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 piler, so I know I need to set up externs
file(s) for them. I know there is https://github./dcodeIO/node.js-closure-piler-externs for mon Node.js externs, and I know how to invoke them on the piler, but for some reason when I do something like --externs externs/fs.js
the error for module$fs
remains. What am I doing wrong?
I know there's other flags like --module
and --mon_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 e up with any answers on the correct incantation here. :(
- 2 Many of the externs you need are officially maintained in the piler project: github./google/closure-piler/tree/master/contrib/nodejs. The contrib externs are now also distributed as part of the official npm package for the piler: npmjs./package/google-closure-piler – Chad Killingsworth Commented May 15, 2015 at 14:41
-
I know these files exist. My question is how do I use these files correctly with
piler.jar
as--externs
doesn't seem to be working as I think it should. – Dororo Commented May 15, 2015 at 17:30 - That's why I posted it as a ment - I'm interested in an answer as well. – Chad Killingsworth Commented May 15, 2015 at 18:56
2 Answers
Reset to default 6 +100The issue is that you wish for the piler to somehow recognize that certain require
calls are internal, namely that the required module should be processed by the piler as source, and others are external so should be left alone. There isn't a good way to handle this situation currently.
Workarounds
Use Post-processing to Add External Require Statements
In this scenario you would pletely omit any require
statements to external modules. The piler would only process code with internal require statements and modules. After pilation, you would prepend the external require statements:
Header JS To Be Prepended
var crypto = require('crypto');
Source To Be Compiled
console.log(crypto);
Because crypto
is declared in an extern, the piler will correctly recognize the type and symbol name.
Alias Require Calls
When the --process_mon_js_modules
is specified, the piler 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 piler will not recognize them and thus not expand them.
Source To Be Compiled
var externalRequire = require;
/** @suppress {duplicate} this is already defined in externs */
var crypto = externalRequire('crypto');
console.log(crypto)
If you're using the Closure Compiler only for type-checking—i.e., with the --checks-only
option—there is another workaround which has the advantage (over the ones mentioned in Chad's answer) of working correctly with unmodified third-party NPM modules which in turn import built-in modules.
Using Stubs
The trick is to create stub NPM modules to stand in for the built-in ones. These can be minimal; they only need to declare the parts of the API you're actually using.
Here's an example for the path
built-in module.
In externs/path/path.js
I have the "externs" declarations (not actually externs, so e.g. you can't use @nosideeffects) for the part of path
that I need:
/** @const */
var path = {};
/**
* @param {string} path
* @return {string}
*/
path.dirname = function(path) {};
/**
* @param {string} path
* @return {string}
*/
path.extname = function(path) {};
/**
* @param {...string} var_args
* @return {string}
*/
path.join = function(var_args) {};
module.exports = path;
In externs/path/package.json
, I have a minimal NPM package config:
{
"description": "Fake package.json for require('path')",
"main": "path.js",
"name": "path",
}
Then create a symlink from node_modules/path
to externs/path
, and add the following to my piler flags:
node_modules/path/package.json
node_modules/path/path.js
(You could put the stub implementation directly in to node_modules
but I prefer to keep my stubs separate from the real modules managed by npm
. I just need to remember to manually add the symlinks to my Git repo, because it's otherwise configured to ignore node_modules
.)
本文标签: javascriptHow do you define nodemodules as externs in Closure CompilerStack Overflow
版权声明:本文标题:javascript - How do you define node_modules as externs in Closure Compiler? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742376160a2463206.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论