Gruntjs 为什么建议使用concat then uglify,而后者可以同时做到这两个方面?

Gruntjs 为什么建议使用concat then uglify,而后者可以同时做到这两个方面?,gruntjs,uglifyjs,grunt-contrib-concat,Gruntjs,Uglifyjs,Grunt Contrib Concat,我一直在看关于让JS文件为生产做好准备的建议 例如,在约曼的呼噜声任务中 默认情况下,流程为:concat->uglifyjs 考虑到UglifyJS可以同时进行连接和缩小,为什么您会同时需要这两种功能呢 谢谢。在您提到的示例中(我在下面引用),文件首先与concat连接,然后通过uglify进行uglified/minified: { concat: { '.tmp/concat/js/app.js': [ 'app/js/app.js', 'app/js/

我一直在看关于让JS文件为生产做好准备的建议

例如,在约曼的呼噜声任务中

默认情况下,流程为:concat->uglifyjs

考虑到UglifyJS可以同时进行连接和缩小,为什么您会同时需要这两种功能呢


谢谢。

在您提到的示例中(我在下面引用),文件首先与
concat
连接,然后通过
uglify
进行uglified/minified:

{
  concat: {
    '.tmp/concat/js/app.js': [
      'app/js/app.js',
      'app/js/controllers/thing-controller.js',
      'app/js/models/thing-model.js',
      'app/js/views/thing-view.js'
    ]
  },
  uglifyjs: {
    'dist/js/app.js': ['.tmp/concat/js/app.js']
  }
}
同样可以通过以下方式实现:

{
  uglifyjs: {
    'dist/js/app.js': [
      'app/js/app.js',
      'app/js/controllers/thing-controller.js',
      'app/js/models/thing-model.js',
      'app/js/views/thing-view.js'
    ]
  }
}
通常,任务
clean
将在写入临时文件夹(在本例中为
concat
)的任务之后运行,并删除该文件夹中的任何内容。有些人还喜欢在执行任务之前运行
clean
,例如
compass
,删除随机命名的图像精灵(每次任务运行时新生成的)。即使对于最偏执的人来说,这也会让车轮继续转动

这完全取决于偏好和工作流程,以及何时运行
jshint
。有些人喜欢在编译之前运行它,另一些人喜欢在编译文件上运行它

复杂的项目中有大量的
JavaScript
文件,或者有越来越多的对等方和贡献者,可能会选择将
uglify
之外的文件连接起来,以使事情更具可读性和可维护性。我认为这就是耶曼选择转换流的原因

根据项目的配置,
uglify
的速度可能会非常慢,因此首先将其与
concat
连接可能会有一些小的好处,但这必须得到确认

concat
还支持分隔符,就
README.md
文件而言,
uglify
不支持分隔符

concat: {
  options: {
    separator: ';',
  }
}

运行基本测试,查看执行
concat
uglify
与只执行
uglify
之间是否存在性能差异

package.json

{
“名字”:“咕噜咕噜咕噜”和“丑八怪”,
“版本”:“0.0.1”,
“描述”:“一个基本测试,看看我们是否可以抛弃concat,只对JS文件使用uglify。”,
“依赖性”:{
“咕哝”:“^0.4.5”,
“grunt contrib concat”:“^0.5.0”,
“grunt contrib丑恶”:“^0.6.0”,
“加载grunt任务”:“^1.0.0”,
“时间咕噜”:“^1.0.0”
}
}
grunfile.js

module.exports=函数(grunt){
//显示grunt任务的执行时间
要求(“时间咕噜”)(咕噜);
//从package.json加载所有grunt-*包
要求('load-grunt-tasks')(grunt);
grunt.initConfig({
路径:{
src:{
js:'src/***.js'
},
目的地:{
js:'dist/main.js',
jsMin:'dist/main.min.js'
}
},
康卡特:{
js:{
选项:{
分隔符:';'
},
src:“”,
目标:“”
}
},
丑陋的:{
选项:{
是的,
曼格尔:没错,
sourceMap:true
},
目标:{
src:“”,
目标:“”
}
}
});
grunt.registerTask('default','concat vs.uglify',函数(concat){
//grunt默认值:true
if(concat){
//将丑陋目标更新为concat的结果
var dest=grunt.config('concat.js.dest');
grunt.config('uglify.target.src',dest);
grunt.task.run('concat');
}
//咕哝违约
grunt.task.run('uglify');
});
};
src
中,我把一堆JS文件,包括jQuery的未压缩源文件,复制了好几次,分散到子文件夹中。比普通网站/应用程序通常拥有的功能多得多

在这两种情况下,压缩所有这些文件所需的时间基本相同。
使用
concat
上的
sourceMap:true
选项时除外(见下文)

在我的计算机上:

grunt default      : 6.2s (just uglify)
grunt default:true : 6s   (concat and uglify)
值得注意的是,在这两种情况下,生成的
main.min.js
是相同的。
另外,
uglify
在组合文件时会自动注意使用适当的分隔符

唯一起作用的情况是将
sourceMap:true
添加到
concat
选项时

这将在
main.js
旁边创建一个
main.js.map
文件,结果如下:

grunt default      : 6.2s (just uglify)
grunt default:true : 13s  (concat and uglify)
但是,如果生产站点仅加载
min
版本,则此选项无效

uglify

当其中一个JS文件发生错误时,
sourcemap
将链接到连接的
main.JS
文件,而不是原始文件。而当
uglify
完成整个工作时,它将链接到原始文件

更新:
我们可以向
uglify
添加另外两个选项,将
uglify
sourcemap链接到
concat
sourcemap,从而解决我上面提到的“缺点”

uglify:{
选项:{
是的,
曼格尔:没错,
sourceMap:true,
sourceMapIncludeSources:true,
sourceMapIn:“.map”,
},
目标:{
src:“”,
目标:“”
}
}
但这似乎非常没有必要

结论 我认为,如果我们使用的是
uglify
,那么可以安全地得出这样的结论:我们可以放弃JS文件的
concat
,而将其用于ot