在带有属性的ES6模块上使用Closure Compiler
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在带有属性的ES6模块上使用Closure Compiler相关的知识,希望对你有一定的参考价值。
经过一天的测试后,我几乎就在那里:使用google-closure-compiler-js和gulp.js来缩小/编译基于“库”的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缩小了对导入模块属性的调用!
你得到了经典的“嗨。我是ADVANCED模式的新手”错误:TypeError: a.a is not a function
。
我该如何防止这种情况? (假设出于现实世界的原因,我们假设直接输出foobar是不可行的。)
- 我需要一个导出文件吗?我到底该怎么做?我在那个方向上的第一次冒险并没有把我带走......是否有一个特定于google-closure-compiler-js的技巧?
- 在Closure Compiler添加一个自动不重命名对导入属性的调用的功能之前,是否存在某种允许点表示法的hack?
- 这篇closure-compiler/wiki关于JS-Modules #type-references的文章建议我做什么?这是我未能实现的答案吗?
/** @param {foo.Foo} Foo */ function(Foo) {}
答案
对于ADVANCED模式兼容性,请使用Object.defineProperties
来避免引用字符串。
Object.defineProperties(mod, {
foobar: {value: foobar}
});
无论何时使用带引号的字符串,您都需要使用括号(或其他技术)或冒险违反一致的属性访问规则。
以上是关于在带有属性的ES6模块上使用Closure Compiler的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Google 的 Closure Compiler 将我的 javascript 拆分为模块?