Javascript 如何通过grunt contrib uglify按顺序缩小js文件?
我有一个目录,如下所示: /文件夹/b.jsJavascript 如何通过grunt contrib uglify按顺序缩小js文件?,javascript,node.js,gruntjs,uglifyjs,grunt-contrib-uglify,Javascript,Node.js,Gruntjs,Uglifyjs,Grunt Contrib Uglify,我有一个目录,如下所示: /文件夹/b.js /文件夹/jQuery.js /文件夹/a.js /文件夹/sub/c.js 我想将所有这些js文件缩小为一个js文件,顺序如下: jQuery.js->a.js->b.js->c.js Q: 1.如何通过grunt contrib uglify实现?(事实上,有很多文件,单独指定所有源文件路径是不切实际的) 2.顺便说一句,如何在调试时获得未统一的文件,在发布时获得缩小的单个文件,而不需要更改html中的脚本标记(以及如何编写脚本标记)?您可能不会
/文件夹/jQuery.js
/文件夹/a.js
/文件夹/sub/c.js
我想将所有这些js文件缩小为一个js文件,顺序如下: jQuery.js->a.js->b.js->c.js Q:
1.如何通过grunt contrib uglify实现?(事实上,有很多文件,单独指定所有源文件路径是不切实际的)
2.顺便说一句,如何在调试时获得未统一的文件,在发布时获得缩小的单个文件,而不需要更改html中的脚本标记(以及如何编写脚本标记)?您可能不会喜欢这样,但最好的方法是将js源文件定义为AMD模块,并使用Requirejs管理加载顺序。grunt contrib requirejs任务将递归您的依赖关系树,并按必要的顺序将js文件连接成一个大js文件。然后使用uglify(实际上r.js内置了uglify)缩小大文件 有一个很好的GrunFile和模板js文件示例 编辑 我最近开始使用CommonJS模块而不是AMD,因为它更接近ES6模块规范。通过运行CommonJS模块,您可以获得相同的结果(1个大的编译+连接的js文件)。有用于和的插件,可以为您管理任务 编辑
我想补充一点,如果你的站点是使用ES6编写的,那就是最好的新连接包。除了绑定文件外,它还将执行树抖动,删除通过
import
语句包含的部分库。这将使您的代码库减少到您所需要的程度,而不会产生您永远不会使用的大量代码。我认为单凭丑陋的任务是无法做到这一点的,但您有许多选择,这些选择可能会导致您想要的结果
一个可能的工作流程是首先将文件按顺序连接(grunt contrib concat)到一个文件中,然后通过uglify将这个连接的文件放在一起。您可以在Gruntfile中定义concat的顺序,也可以在以下插件中使用:
第一个是,您可以在HTML文件中指定顺序,并在脚本块周围添加一些注释。谷歌的人做了它,它的使用非常甜蜜
第二种是,您可以使用require定义一些依赖项,但不需要require.js。它需要修改JS代码,所以可能不喜欢它。我选择选项一。这可以通过以下Grunt任务来完成:
uglify: {
options: {
sourceMap: true
},
build: {
files: {
'public/all.min.js': ['public/js/vendor/jquery-1.10.2.min.js', 'public/js/*.js'],
}
}
}
2) 我不认为有一个明确的方法来实现这一点。这取决于什么样的web框架、模板框架以及您有什么样的需求。我使用express+jade,在我的主要jade布局中,我有:
if process.env.NODE_ENV === 'production'
script(src='/all.min.js')
else
script(src='/js/vendor/jquery-1.10.2.min.js')
script(src='/js/someScript.js')
script(src='/js/otherScript.js')
在my package.json中,我有:
"scripts": {
"postinstall": "grunt"
},
这意味着,当我在部署(Heroku)上运行npm install
时,grunt会运行以缩小/concat文件,当应用程序启动时,会使用缩小的客户端javascript。在本地,我得到了原始的客户端Java脚本,以便于调试
两个不利因素是:
- 我必须保持两个脚本文件列表同步(在Gruntfile和layout.js中),我通过在Gruntfile中使用
来解决这个问题,但这可能不适合所有人。您可以将javascripts列表放在Gruntfile中,并从中创建jade模板,但对于大多数项目来说,这似乎有些过分*.js
- 如果您不信任Grunt配置,那么您基本上必须在本地使用
测试运行应用程序,以验证缩小是否按预期方式工作NODE\u ENV=production
['vendor/***/.js']
)加载所有供应商文件(angular、jquery及其各自的相关插件)。但有些插件的名称使它们在angular和jquery之前加载。解决方案是首先手动加载它们
['vendor/angular.js', 'vendor/jquery.js', 'vendor/**/*.js]
幸运的是,angular和jquery句柄加载两次就足够了编辑:虽然两次加载如此大的库并不是最佳做法,但会导致缩小的文件不必要的膨胀。(感谢@Kano指出这一点!)
另一个问题是客户端js。顺序很重要,它要求在加载所有依赖项之后,最后加载主应用程序文件。解决方案是排除,然后包括:
['app/**/*.js', '!app/app.js', 'app/app.js']
这将阻止
app.js
与所有其他文件一起加载,并且只有在最后才包括它。如果您的问题是需要按顺序加载供应商(比如说在任何jquery插件之前加载jquery)。我把jquery放在它自己的名为“!jquery’,有效地将其放在堆栈的顶部。
然后我就用了concat,就像你平时用的一样:
concat: {
options: {
separator: ';',
},
build: {
files: [
{
src: ['js/vendor/**/*.js', 'js/main.min.js'],
dest: 'js/global.min.js'
}
]
}
},
这是@1469的答案,但他没有说明为什么会这样。使用concat将所有js文件放在一个文件中,这个模块按照文件名的顺序来做,所以我根据顺序为文件名添加前缀。我相信它甚至有o
concat: {
js: {
options: {
block: true,
line: true,
stripBanners: true
},
files: {
'library/dist/js/scripts.js' : 'library/js/*.js',
}
}
},
uglify: {
dist: {
files: {
'library/dist/js/scripts.min.js': [
'library/js/scripts.js'
]
},
options: {
}
}
},
<!-- build:js:dist big-ugly.js -->
<script src="js1.js"></script>
<script src="js2.js"></script>
<!-- etc etc -->
<script src="js100.js"></script>
<!-- /build -->
<script src="big-ugly.js"></script>