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

22

我想在我们使用的JavaScript源代码上使用Google Closure编译器。 在开发模式下,我们倾向于将功能拆分成许多文件,但是在生产环境中希望将它们组合成模块。

调用编译器时,我可以提供要包含在编译中的文件列表,但其输出显示编译器未保存文件列表的顺序。

我搜索了一下,发现可以使用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...”很好,但在我们的情况下,它会变得更加复杂,我们将不得不编写一个基于某些逻辑的程序/脚本来完成这项工作。如果我们能以某种方式预先告诉编译器文件的顺序,那么它可能只是节省实现这样一个程序所需的时间。

谢谢。


1
cat file1 file2 > temp && compile -js temp 这个怎么样? - georg
你在调用编译器时是使用通配符(*.js)还是逐个列出每个文件? - GillesC
我编辑了我的问题,因为它太长了,无法在评论中发表。谢谢。 - Nitzan Tomer
1
如果将相同的源文件编译成一个巨大的文件可以正常工作,那么您应该在http://code.google.com/p/closure-compiler/issues/list上发布问题。无论哪种方式,如果您能提供可重现的示例,都会有所帮助。 - Chad Killingsworth
是的,顺序有点变化,但并没有像我想象的那样导致任何错误,错误是由糟糕的代码引起的。 - Nitzan Tomer
显示剩余6条评论
2个回答

42
Closure-compiler的多文件输出功能提供了一个强大的工具,可以将输入文件分成不同的输出块。它被设计成这样,不同的块可以在不同的时间加载,具体取决于所需的功能。有多个与块相关的编译器标志。
每个--chunk标志的使用描述了一个输出文件及其依赖项。每个块标志都遵循以下语法:
--js inputfile.js
--chunk name:num_files:dependency

生成的输出文件将命名为name.js,并包括前面指定的--js标志所指定的文件。
依赖项选项是您最感兴趣的内容。它指定了父块是什么。块选项必须描述一个有效的依赖树(您必须有一个基本块)。
以下是一个示例:
--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

在这种情况下,您告诉编译器页面1和页面2块依赖于公共块,并且页面1addons块依赖于页面1块。
请记住,如果编译器确定某个代码仅由该块使用,则它可以将代码从一个块移动到其他块输出文件中。
所有这些都不需要closure-library或使用goog.require/provide调用,也不会向您的输出添加任何代码。如果您希望编译器自动确定依赖项或能够为您管理这些依赖项,则需要使用CommonJS、ES2015模块或goog.require/provide/module调用等模块格式。
更新说明:在20180610版本之前,chunk标志的名称为module。它们已被重命名以减少与适当的JS模块混淆。本答案已更新以反映新名称。
更新说明2:现在有一个实用程序可以自动计算并生成这些标志:https://github.com/ChadKillingsworth/closure-calculate-chunks

3
点赞。这是一个很好的简洁回答,带有一个很好的例子。完美。在测试您的答案时,我无法创建包含句点或破折号的模块名称。这是否可能,还是我做错了什么?例如:--module common.min:1 对我没有起作用。(当我说没有起作用时,我的意思是没有创建任何模块。) - Karl
我在我的博客中写了一篇文章,提供了一个简单的示例,说明如何做到这一点。分享给其他有兴趣的人:http://www.syntaxsuccess.com/viewarticle/lazy-loading-with-the-closure-compiler - TGH
你如何为生成的模块创建源代码映射? - Scribblemacher
这适用于明确指定的.js文件,但是当使用入口点的自动依赖项检查时怎么办?您能否为一组依赖项指定一个模块? - Stephen Edwards
当你有多个依赖项时怎么办? - Ally
@Scribblemacher 当你传递 --create_source_map %outname%.map 选项时,源映射应该自动生成。 - zavr

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接