Thank you for pointing me toward that similar issue. If I use a hand-crafted telnet-client stub instead of the real telnet-client implementation, then Closure's command-line interface can ingest and process both the main program script and the stub. However, Closure's Java API fails, and I cannot figure out how to use the API to replicate whatever the command-line interface is doing.
My main program, stored as main.js:
const { Telnet } = require('telnet-client')
new Telnet().connect()
My stub, stored as node_modules/telnet-client.js:
class Telnet {
connect() {}
}
exports.Telnet = Telnet
When I run Closure from the command line, the output is about what I would expect, with the require call rewritten to use synthesized structures that represent module exports:
% java -jar ~/Downloads/closure-compiler-v20220301.jar --module_resolution=NODE --formatting=PRETTY_PRINT --process_common_js_modules node_modules/telnet-client.js main.js
var module$node_modules$telnet_client = {default:{}};
module$node_modules$telnet_client.default.Telnet = class {
connect() {
}
};
const {Telnet} = module$node_modules$telnet_client.default;
(new module$node_modules$telnet_client.default.Telnet()).connect();
Encouraging! So I tried to do the equivalent thing using Closure's Java API:
CompilerOptions compilerOptions = new CompilerOptions();
compilerOptions.setModuleResolutionMode(ResolutionMode.NODE);
compilerOptions.setPrettyPrint(true);
compilerOptions.setProcessCommonJSModules(true);
new Compiler()
.compile(
AbstractCommandLineRunner.getBuiltinExterns(BROWSER),
Arrays.asList(
SourceFile.fromFile("node_modules/telnet-client.js"),
SourceFile.fromFile("main.js")),
compilerOptions);
Unfortunately, this Java code fails:
Jul 08, 2022 3:11:37 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: main.js:1:19: ERROR - [JSC_JS_MODULE_LOAD_WARNING] Failed to load module "telnet-client"
1| const { Telnet } = require('telnet-client')
^
Jul 08, 2022 3:11:37 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 1 error(s), 0 warning(s)
My ultimate goal is to have programmatic access to an AST similar to the one that the command-line invocation produces, augmented with resolved names and inferred types to the best of Closure's ability. The error above suggests to me that I will not be getting deep enough into Closure's processing layers to have that information. What should I do differently so that my API-driven processing more closely resembles what the command-line interface does?
Thanks,
Ben