使用 GCC 连接多个 JS 模块,从 ES2015 转译并注入带有 @define 注释的变量

Concat several JS modules using GCC with transpiling from ES2015 and injecting variables annotated with @define

本文关键字:注入 @define 变量 注释 ES2015 连接 GCC JS 模块 使用      更新时间:2023-09-26

我正在尝试创建一个Java Web服务,该服务为JavaScript文件提供服务,并根据请求将一些信息注入到这些文件中。以下是我在javascript目录中的示例:

主.js:

import {log} from "./lib";
/** @define {string} */
const SCRIPT_ID = "SCRIPT_ID"
let foo = "bar";
log(foo);
// Rest of code

库.js

export function log(str) {
    console.log(">>>", str);
};

我希望这些脚本

  1. 连接在一个文件中;
  2. (function() { /* concatenated scripts */ })();包裹,防止污染全局命名空间;
  3. 修改以用 Java 中的一些变量替换某些代码段(如 main.js 中的SCRIPT_ID(。

我正在使用Google闭包编译器和以下Java代码:

CompilerOptions options = new CompilerOptions();
options.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT6);
options.setLanguageOut(CompilerOptions.LanguageMode.ECMASCRIPT5);
options.setInlineVariables(CompilerOptions.Reach.ALL);
options.setDefineToStringLiteral("SCRIPT_ID", "12345");

好吧,它不起作用。SCRIPT_ID没有注入(因为我一次编译两个文件(,并且我无法将组合结果包装在自调用函数中,因为我在使用 Java 的 GCC 时找不到这样做的方法。如果您使用的是 GCC 命令行工具,您可以为此提供--output_wrapper选项,但它似乎仅适用于 cli 工具。

有人知道如何解决这个问题吗?也许有一个更好的JavaScript编译器?GCC似乎非常擅长优化JavaScript,但它不适合我的情况。

更新

关于@define语句,我可以解决它,将所有要用@define注释的变量放在一个不使用 ES6 模块关键字的单独文件中,即 importexport

全局.js

/** @define {string} */
let SCRIPT_ID = "";
/** @define {boolean} */
let DEBUG = true;

如果将此文件与其他文件一起发送到编译器,则一切按预期工作,注释变量替换为 Java 代码中的相应值。

作为工作对象,您可以将JS文件读入内存,连接并包装它们,然后使用JSSourceFile.fromCode构建单个源文件并将其馈送到编译器中。