【发布时间】:2017-12-29 14:14:23
【问题描述】:
所以经过一天的测试后,我快到了:使用 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 缩小了对导入模块属性的调用!
您会收到经典的“嗨。我是高级模式的新手”错误: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) {}
【问题讨论】:
-
出于好奇,您为什么使用
mod对象而不是仅使用命名导出?除其他外,这将防止树摇晃。 -
为什么需要
Object.defineProperty?您可以通过这种方式轻松定义您的模块:var mod = {foobar}; -
@T.J.Crowder 部分原因是为了防止 treeshaking;如果我想创建一个以缩小版本分发的库 - 那会是可取的吗?另一件事是,我想测试如何实际导出和访问对象。当然,这里没有任何意义!使用 foobar 函数。
-
@Andy 我绝对可以做到!它是 ES5 的遗物,以这种方式定义它会自动使其成为非枚举、非配置、不可写的。使用不再需要的模块。接得好。 :)
-
@JonasM.Schlatter:不,treeshaking 是您希望您的库启用的一件好事。如果使用您的库的应用不需要函数 X,则 treeshaking 可以将函数 X 排除在包之外。
标签: javascript ecmascript-6 gulp google-closure-compiler es6-modules