如何使用 Google 的 Closure Compiler 将我的 javascript 拆分为模块?

Posted

技术标签:

【中文标题】如何使用 Google 的 Closure Compiler 将我的 javascript 拆分为模块?【英文标题】:How do I split my javascript into modules using Google's Closure Compiler? 【发布时间】:2012-05-10 20:50:39 【问题描述】:

我想在我们正在使用的 javascript 源代码上使用 google 闭包编译器。 在开发模式下,我们倾向于将功能分解为大量文件,但生产环境希望将它们组合成模块。

当调用编译器时,我可以给它一个要包含的文件列表以供编译,但它的输出显示编译器没有保存文件列表的顺序。

我搜索了一下,发现可以使用goog.provide/good.require来控制不同js文件之间的依赖关系。 问题在于它向我的 js 添加了我不需要或不想要的代码,例如:

goog.provide("mainFile")

将添加这个:

var mainFile = ;

到编译的js文件,我不想要的东西。 我们根本没有使用 google 闭包库,我只想使用编译器。

有没有办法告诉编译器文件的顺序,而不包括更多我不需要的“闭包库”功能? 我当然可以创建自己的工具,它首先会获取所有文件,将它们组合成一个,然后作为编译器的输入,但如果它可以由编译器本身完成,我更愿意取消它。


编辑

我们的目标是能够像这个线程中的答案一样生成模块:Using the --module option in Closure Compiler to create multiple output files

因此,我想添加控制哪些文件进入哪个模块的能力,同时还可以控制它们的顺序。 目前我不使用通配符,但我计划在未来使用通配符(如果可能的话)。

只需“cat file1.js file2.js > combined.js && compile...”就可以了,但在我们的例子中它有点复杂,我们必须编写一个基于一些逻辑。 如果我们能以某种方式提前告诉编译器文件的顺序,它可能只是节省了实现这样一个程序的时间。

谢谢。

【问题讨论】:

cat file1 file2 > temp && compile -js temp 怎么样? 调用编译器时是使用通配符(*.js)还是按顺序声明每个文件? 我编辑了我的问题,因为它太大而无法发表评论。谢谢。 控制顺序是指编译器处理给定模块中每个源文件的顺序吗?它应该是您列出它们的顺序。 如果将相同的源文件编译成一个巨大的文件有效,那么您应该在code.google.com/p/closure-compiler/issues/list 发布问题。无论哪种方式,如果您能提供可重现的样本,都会有所帮助。 【参考方案1】:

Closure-compiler 创建多个输出文件的能力提供了一个强大的工具来将输入文件分成不同的输出块。它的设计使得可以根据所需的功能在不同的时间加载不同的块。有多个与块有关的编译器标志。

每次使用 --chunk 标志都描述了一个输出文件及其依赖项。每个块标志遵循以下语法:

--js inputfile.js
--chunk name:num_files:dependency

生成的输出文件将是 name.js 并包含由前面的 --js 标志指定的文件。

dependency 选项是您最感兴趣的。它指定父块是什么。块选项必须描述一个有效的依赖树(你必须有一个基本块)。

这是一个例子:

--js commonfunctions.js
--chunk common:1
--js page1functions.js
--js page1events.js
--chunk page1:2:common
--js page2function.js
--chunk page2:1:common
--js page1addons.js
--chunk page1addons:1:page1

在这种情况下,您是在告诉编译器 page1 和 page2 块依赖于公共块,而 page1addons 块依赖于 page1 块。

请记住,如果编译器确定仅由该块使用,则编译器可以并且确实将代码从一个块移动到其他块输出文件中。

这些都不需要闭包库或使用 goog.require/provide 调用,也不会将任何代码添加到您的输出中。如果您希望编译器自动确定依赖关系或能够为您管理这些依赖关系,则需要使用模块格式,例如 CommonJS、ES2015 模块或 goog.require/provide/module 调用。

更新说明:在 20180610 版本之前,chunk 标志被命名为 module。它们被重命名以减少与正确的 JS 模块的混淆。答案已更新以反映新名称。

更新说明 2:现在有一个实用程序可以为您自动计算和生成这些标志:https://github.com/ChadKillingsworth/closure-calculate-chunks

【讨论】:

赞成。这是一个很好的简洁答案,有一个很好的例子。完美的。在测试您的答案时,我无法创建名称中包含句点或破折号的模块。这可能吗,还是我做错了什么?示例:--module common.min:1 对我不起作用。 (当我说没有工作时,我的意思是没有创建任何模块。) 我在我的博客中写了一个简单的例子来说明如何做到这一点。分享以防其他人感兴趣:syntaxsuccess.com/viewarticle/… 如何为生成的模块创建源映射? 这适用于明确指定的 .js 文件,但是当使用来自 entry_point 的自动依赖检查时呢?你能为一组依赖指定一个模块吗? 如果你有多个依赖项怎么办?【参考方案2】:

你也可以设置输出路径,例如:

--module_output_path_prefix ./public/js/

另请参阅: Using the --module option in Closure Compiler to create multiple output files

【讨论】:

以上是关于如何使用 Google 的 Closure Compiler 将我的 javascript 拆分为模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将 google-closure javascript 转换为现代 ES6?

Google Closure:如何渲染 2 个组件

在带有属性的ES6模块上使用Closure Compiler

使用 Google Closure Compiler 编译的 jQuery

为啥 Google 的 Closure 库不在他们的 CDN 上托管?

让 browserify 与 Google Closure Compiler 一起工作