在具有属性的 ES6 模块上使用闭包编译器

Using Closure Compiler on ES6 Modules with Properties

所以经过一天的测试我几乎完成了:使用 google-closure-compiler-js and gulp.js 缩小/编译我基于 "library".

的 ES6 模块

只剩下一个问题了。如何调用导入模块的属性?

我的测试用例包含 3 个文件:

gulpfile.js

const gulp = require("gulp");
const compiler = require("google-closure-compiler-js").gulp();
const sourcemaps = require("gulp-sourcemaps");

gulp.task("default", function() {
// wildcards don't seem to work yet with the js version
// files need to be in reverse order of dependency...
return gulp.src(["src/boilerplate/main.js", "src/app.js"])
    .pipe(sourcemaps.init())
    .pipe(compiler({
        jsOutputFile: "app.min.js",
        compilationLevel: "ADVANCED",
        warningLevel: "VERBOSE",
        createSourceMap: true
    }))
    .pipe(sourcemaps.write("/"))
    .pipe(gulp.dest("./dist"));
});

src/boilerplate/main.js

var mod = {};
export default mod;

var foo = "FOO";
var bar = "BAR";

function foobar(join) {
    join = (typeof join === "string") ? join : "";
    return foo + join + bar;
}
Object.defineProperty(mod, "foobar", {value: foobar});

src/app.js

import boilerplate from "./boilerplate/main.js";

console.log(boilerplate["foobar"]("+"));
console.log(boilerplate.foobar("+"));

如果您在此处登录 boilerplate,您会看到它有 属性 "foobar"。符号完好无损。太棒了!

因此 app.js' 第一次调用 - 括号表示法 ["foobar"] - 工作得很好。但是,点符号没有。 Closure Compiler 缩小了对导入模块 属性 的调用!
你得到了经典的 "Hi. I'm new to ADVANCED mode" 错误:TypeError: a.a is not a function.

如何防止这种情况发生? (假设直接导出 foobar 是不可行的,看在现实世界的份上。)

为了与 ADVANCED 模式兼容,请使用 Object.defineProperties 避免带引号的字符串。

Object.defineProperties(mod, {
  foobar: {value: foobar}
});

任何时候使用带引号的字符串,都需要使用方括号(或其他技术),否则就有违反一致的 属性 访问规则的风险。