如何通过grunt-contrib-uglify来整理js文件?

我有一个如下所示的目录:

/folder/b.js
/folder/jQuery.js
/folder/a.js
/folder/sub/c.js

我想要将所有这些js文件按顺序放在一个js文件

jQuery.js – > a.js – > b.js – > c.js

问:
1.如何通过grunt-contrib-uglify来做到这一点(事实上,有很多文件,单独指定所有源文件path是不切实际的)

2.btw,如何在debugging的时候得到unminified文件,释放的时候得到缩小的单个文件,而不需要改变html中的脚本标签 (以及如何编写脚本标签)?

好问题!

1)Uglify将对目标文件中的函数进行重新sorting,以便函数定义在顶部,函数在底部执行,但似乎会保留函数执行的顺序。

这意味着如果你确定jQuery在Gruntfile的Uglifyconfiguration中首先被提到,那么jQuery运行定义它的全局函数的function将首先被放置。

我使用这个configuration:

 uglify: { options: { sourceMap: true }, build: { files: { 'public/all.min.js': ['public/js/vendor/jquery-1.10.2.min.js', 'public/js/*.js'], } } } 

2)我不认为有一个确定的方法来实现这一点。 这取决于什么web框架,模板框架和你有什么样的要求。 我使用快递+玉器,在我的主要玉器布局中有:

 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') 

在我的package.json中我有:

 "scripts": { "postinstall": "grunt" }, 

这意味着当我运行npm install (在Heroku上)时,运行grunt来缩小/ concat文件,当应用程序以NODE_ENV=production开始时,使用缩小的客户端javascript。 本地我得到原来的客户端JavaScript的debugging容易。

两个缺点是:

  • 我必须保持脚本文件的两个列表保持同步(在Gruntfile和layout.js中)我通过在Gruntfile中使用*.js来解决这个问题,但是这可能不适合所有人。 你可以把JavaScript的列表放在Gruntfile中,并从中创build一个jade-template,但是对于大多数项目来说这似乎过分了。
  • 如果你不信任你的Gruntconfiguration,你基本上必须在本地使用NODE_ENV=production来testing运行应用程序,以validationNODE_ENV=production工作是否按照你想要的方式工作。

这可以使用以下Grunt任务完成:

  1. https://github.com/gruntjs/grunt-contrib-concat连接文件
  2. https://github.com/gruntjs/grunt-contrib-uglify缩小连接的文件

编辑

我通常使用grunt-contrib-concat通过Grunt连接任务运行所有文件。 然后我有另一个任务,使用grunt-contrib-uglify uglify连接的文件。

你可能不会这样做,但最好的方法是将你的js源文件定义为AMD模块,并使用Requirejs来pipe理它们加载的顺序。 grunt-contrib-requirejs任务会缓解你的依赖关系树,并以必要的顺序连接js文件到一个大的js文件中。 然后您将使用uglify(实际上r.js已经uglify内置)来缩小大文件。

https://github.com/danheberden/yeoman-generator-requirejs有一个很好的例子gruntfile和模板js文件工作。

编辑

我最近开始使用CommonJS模块,而不是AMD,因为它更接近ES6模块规范。 您可以通过Browserify运行commonjs模块来实现相同的结果(1个大的编译的+连接的js文件)。 有咕噜声和吞咽的插件来pipe理你的任务。

编辑

我想补充一点,如果你的网站是用ES6编写的,那么Rollup就是最好的新连接包。 除了捆绑你的文件之外,它还会执行树震动,如果通过import语句包含的话,将删除部分库。 这可以减less你的代码库,而不会让你永远不会使用的代码膨胀。

我不认为你可以单独使用uglify任务,但是你有很多select可能导致你想要的结果。

一个可能的工作stream将首先连接(grunt-contrib-concat)文件到一个单一的文件,并通过uglify把这个连接的文件。 您可以在Gruntfile中定义concat的顺序,或者使用这些插件:

首先是https://github.com/yeoman/grunt-usemin ,你可以在HTML文件中指定顺序,在脚本块中添加一些注释。 谷歌的人做到了,使用起来非常的甜美。

第二个是https://github.com/trek/grunt-neuter ,在那里你可以用require定义一些依赖关系,但是没有require.js的大部分。 它需要改变你的JS代码,所以可能不喜欢它。 我会select一个。

我遇到了同样的问题。 快速修复只是改变文件名 – 我使用1.jquery.min.js2.bootstrap.min.js

看起来你的问题的第二部分仍然没有答案。 但让我一个一个尝试。

首先,你可以join并uglify大量的js文件到一个concat答案解释。 也应该可以使用https://github.com/gruntjs/grunt-contrib-uglify,因为它似乎有通配符。 您可能需要尝试使用“expand = true”选项和通配符。 这照顾你的第一个问题。

对于第二部分,假设你join并丑化成了丑陋的.js

现在在你的html中,你可以添加下面的指令:

 <!-- build:js:dist big-ugly.js --> <script src="js1.js"></script> <script src="js2.js"></script> <!-- etc etc --> <script src="js100.js"></script> <!-- /build --> 

然后通过https://www.npmjs.com/package/grunt-processhtml中的grunt html预处理器传递它,作为你的咕噜作业的一部分。

这个预处理器将会replace整个块

 <script src="big-ugly.js"></script> 

这意味着html文件在语义上是相同的 – 在咕噜作业之前和之后; 也就是说,如果页面以本地forms正常工作(用于debugging) – 那么转换后的页面必须在grunt之后正确工作 – 而不需要您手动更改任何标签。

这可能只是与你的问题有关,但我想要类似的东西。 只有我的订单在以下方面很重要:

我正在用通配符( ['vendor/**/*.js'] )加载所有供应商文件(angular,jquery和它们各自的相关插件)。 但是一些插件的名称使得它们在angular和jquery之前加载。 解决办法是先手动加载它们。

 ['vendor/angular.js', 'vendor/jquery.js', 'vendor/**/*.js] 

幸运的是angular度和jquery句柄被加载两次就足够了。 编辑:虽然这是不是最好的做法加载这样的大型库两次,导致你的缩小文件不必要的膨胀。 (感谢@Kano指出这一点!)

另一个问题是client-js的顺序是很重要的,它需要主应用程序文件最后加载,所有的依赖关系都被加载完毕。 解决scheme是排除,然后包括:

 ['app/**/*.js', '!app/app.js', 'app/app.js'] 

这可以防止app.js与所有其他文件一起被加载,并且只在最后包含它。

这是@ 1469的答案,但他没有说清楚为什么这个工作。 使用concat把所有的js文件合并成一个,这个模块按照文件名的顺序执行,所以我根据命令给文件名添加了一个前缀。 我相信它甚至还有其他的select。

 concat: { js: { options: { block: true, line: true, stripBanners: true }, files: { 'library/dist/js/scripts.js' : 'library/js/*.js', } } }, 

然后使用uglify创build缩小的丑陋版本:

 uglify: { dist: { files: { 'library/dist/js/scripts.min.js': [ 'library/js/scripts.js' ] }, options: { } } }, 

如果你的问题是你有需要加载的供应商(让我们说jQuery之前任何jQuery插件)。 我解决了这个问题,把jquery放在名为“!jquery”的文件夹中,把它放在堆栈的顶端。 然后我就像平常一样使用concat:

 concat: { options: { separator: ';', }, build: { files: [ { src: ['js/vendor/**/*.js', 'js/main.min.js'], dest: 'js/global.min.js' } ] } },