多个脚本标签和合并 + 压缩 + 预处理

4
我有一个包含多个脚本标签(近20个)的HTML文件。我决定将所有JS文件连接成一个文件,然后对连接后的文件进行缩小处理。我使用ant tasks来进行连接,并且也会使用该工具对其进行缩小处理。我知道需要提供未连接/未缩小处理版本的选项,以便在调试时使用(即在开发环境中)。
我想知道如何实现这一点。例如,文件main.html有20个脚本标签,我想到的一种方法是使用HTML预处理器并有条件地包括脚本标签:
#ifdef perf
    <script src="main.min.js"></script> 
#else 
    <script src="ctrl.js"></script>
    <script src="services.js"></script>
    <script src="directives.js"></script>
    <script src="model.js"></script>
    .
    .
    .P.S
    <script src="file_no_20.js"></script>
#endif

main.min.js是使用ant进行构建过程中合并和压缩的文件。

有更好的方法吗?这种方法的缺点是什么?

谢谢, Chris。 附言:考虑使用http://fmpp.sourceforge.net/进行html预处理,欢迎提出其他建议。

2个回答

1

我建议使用标签库,例如http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags4.html#67771来实现这个功能。在其中包含你的脚本,如下:

<script:include src="myscript1.js" />
<script:include src="myscript2.js" />
<script:include src="myscript3.js" />
..

并使用页面参数让您的系统决定是否需要将脚本连接和压缩。类似以下内容:

www.yourapp.com/app?debugMode=true

默认情况下,脚本会被合并和压缩。如果您是项目开发人员,只需添加一个页面参数,如debugMode=true。当debugMode为true时,只需按原样呈现脚本。

市场上有许多服务,例如http://developer.yahoo.com/yui/compressor/,可以与您的项目集成,为您完成此工作。

不要每次加载页面时都压缩脚本。第一次执行此操作并将其缓存,以便您无需每次都执行此操作。随时重新构建最新的脚本文件,只需添加另一个参数,如?rebuild=true,以使所有最新文件都被压缩和缓存。您也可以对CSS执行相同的操作。


1
Chrome支持一项称为“源映射”的强大功能,非常适合此类操作。我建议您在此处阅读指南以获取更多信息:

http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

如果您在使用AngularJS时涉及到缩小代码的问题,那么有一些需要注意的地方。根据文档:

Since angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not being able to identify services correctly.

To overcome issues caused by minification, just assign an array with service identifier strings into the $inject property of the controller function, just like the last line in the snippet (commented out) suggests:

PhoneListCtrl.$inject = ['$scope', '$http'];

There is also one more way to specify this dependency list and avoid minification issues — using the bracket notation which wraps the function to be injected into an array of strings (representing the dependency names) followed by the function to be injected:

var PhoneListCtrl = ['$scope', '$http', function($scope, $http) { /* constructor body */ }];

Both of these methods work with any function that can be injected by Angular, so it's up to your project's style guide to decide which one you use.

http://docs.angularjs.org/tutorial/step_05


谢谢,我会看一下。是的,我知道 Angular 的 DI 是如何工作的。我们一直都在使用显式的 .$inject 机制。 - ChrisOdney
我已经了解了这个,真的很喜欢这个想法。而且似乎非常相关于我在这里所问的问题。我现在正在处理Angularjs + Closure编译器,很快就会尝试一下这个。再次感谢。 - ChrisOdney
没问题。祝你好运! - btford

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