首頁  >  文章  >  web前端  >  Grunt入門教學(自動任務運行器)_javascript技巧

Grunt入門教學(自動任務運行器)_javascript技巧

WBOY
WBOY原創
2016-05-16 15:46:421382瀏覽

在Javascript的開發過程中,常常會遇到一些重複性的任務,例如合併檔案、壓縮程式碼、檢查語法錯誤、將Sass程式碼轉換成CSS程式碼等等。通 常,我們需要使用不同的工具,來完成不同的任務,既重複勞動又非常耗時。 Grunt就是為了解決這個問題而發明的工具,可以幫助我們自動管理和運行各種任 務。

簡單說,Grunt是一個自動任務運行器,會按照預先設定的順序自動執行一系列的任務。這可以簡化工作流程,減輕重複性工作帶來的負擔。



## 安裝


Grunt是基於Node.js,安裝前要先安裝Node.js,再執行下面的指令。


sudo npm install grunt-cli -g


grunt-cli表示安裝的是grunt的命令列介面,參數g表示全域安裝。

Grunt使用模組結構,除了安裝命令列介面以外,還要根據需要安裝相應的模組。這些模組應該採用局部安裝,因為不同項目可能需要同一個模組的不同版本。

首先,在專案的根目錄下,建立一個文字檔案package.json,指定目前專案所需的模組。下面就是一個例子。


{ “name”: “my-project-name”, “version”: “0.1.0”, “author”: “Your Name”, “devDependencies”: { “grunt”: “0.x.x”, “grunt-contrib-jshint”: “<em>“, “grunt-contrib-concat”: “~0.1.1”, “grunt-contrib-uglify”: “~0.1.0”, “grunt-contrib-watch”: “~0.1.4” } }</em>


上面這個package.json檔案中,除了註明專案的名稱和版本以外,還在devDependencies屬性中指定了專案依賴的grunt模組和版本:grunt核心模組為最新的0.x.x版,jshint外掛程式為最新版本, concat插件不低於0.1.1版,uglify插件不低於0.1.0版,watch插件不低於0.1.4版。

然後,在專案的根目錄下執行下面的命令,這些插件就會自動安裝在node_modules子目錄。


npm install


上面這種方法是針對已有package.json的情況。如果想要自動產生package.json文件,可以使用npm init指令,依照螢幕提示回答所需模組的名稱和版本即可。


npm init


如果已有的package.json檔案不包含Grunt模組,可以在直接安裝Grunt模組的時候,加上—save-dev參數,該模組就會自動被加入package.json檔案。


npm install <module> —save-dev


例如,對應上面package.json檔案指定的模組,需要執行以下npm指令。


npm install grunt —save-dev npm install grunt-contrib-jshint —save-dev npm install grunt-contrib-concat —save-dev npm install grunt-contrib-uglify —save-dev npm install grunt-contrib-watch —save-dev




## 指令腳本檔Gruntfile.js


模組安裝完以後,下一步在專案的根目錄下,新建腳本檔案Gruntfile.js。它是grunt的設定文件,就好像package.json是npm的設定檔一樣。 Gruntfile.js就是一般的Node.js模組的寫法。


module.exports = function(grunt) { // 配置Grunt各种模块的参数 grunt.initConfig({ jshint: { / jshint的参数 <em>/ }, concat: { /</em> concat的参数 <em>/ }, uglify: { /</em> uglify的参数 <em>/ }, watch: { /</em> watch的参数 <em>/ } }); // 从node_modules目录加载模块文件 grunt.loadNpmTasks(‘grunt-contrib-jshint'); grunt.loadNpmTasks(‘grunt-contrib-concat'); grunt.loadNpmTasks(‘grunt-contrib-uglify'); grunt.loadNpmTasks(‘grunt-contrib-watch'); // 每行registerTask定义一个任务 grunt.registerTask(‘default', [‘jshint', ‘concat', ‘uglify']); grunt.registerTask(‘check', [‘jshint']); };</em>


上面的程式碼用到了grunt程式碼的三個方法: grunt.initConfig:定義各種模組的參數,每個成員項目對應一個同名模組。
grunt.loadNpmTasks:載入完成任務所需的模組。 grunt.registerTask:定義具體的任務。第一個參數為任務名,第二個參數是一個數組, 表示該任務需要依序使用的模組。 default任務名稱表示,如果直接輸入grunt指令,後面不跟任何參數,這時所呼叫的模組(此例為 jshint,concat和uglify);此例的check任務則表示使用jshint外掛程式對程式碼進行語法檢查。
上面的程式碼總共載入了四個模組:jshint(檢查語法錯誤)、concat(合併檔案)、uglify(壓縮程式碼)和watch(自動執行)。接下來,有兩種使用方法。

(1)命令列執行某個模組,例如


grunt jshint


上面程式碼表示運行jshint模組。

(2)命令列執行某個任務。如


grunt check


上面程式碼表示運行check任務。如果運行成功,就會顯示「Done, without errors.」。

如果沒有給予任務名,只鍵入grunt,就表示執行預設的default任務。



## Gruntfile.js實例:grunt-contrib-cssmin模組


下面透過cssmin模組,示範如何撰寫Gruntfile.js檔案。 cssmin模組的作用是最小化CSS檔。

首先,在專案的根目錄下安裝該模組。


npm install grunt-contrib-cssmin —save-dev


然後,新建檔案Gruntfile.js。


module.exports = function(grunt) { grunt.initConfig({ cssmin: { minify: { expand: true, cwd: ‘css/‘, src: [‘<em>.css', ‘!</em>.min.css'], dest: ‘css/‘, ext: ‘.min.css' }, combine: { files: { ‘css/out.min.css': [‘css/part1.min.css', ‘css/part2.min.css'] } } } }); grunt.loadNpmTasks(‘grunt-contrib-cssmin'); grunt.registerTask(‘default', [‘cssmin:minify','cssmin:combine']); };


以下詳細解釋上面程式碼中的三個方法,下面一個個來看。

(1)grunt.initConfig

grunt.initConfig方法用於模組配置,它接受一個物件作為參數。該物件的成員與使用的同名模組一一對應。由於我們要配置的是cssmin模組,所以裡面有一個cssmin成員(屬性)。

cssmin(屬性)指向一個對象,該對象又包含多個成員。除了一些系統設定的成員(如options),其他自訂的成員稱為目標 (target)。一個模組可以有多個目標(target),上面程式碼裡面,cssmin模組共有兩個目標,一個是“minify”,用於壓縮css檔案;另一個是“combine”,用於將多個css檔案合併一個文件。

每個目標的具體設置,需要參考該模板的文檔。就cssmin來講,minify目標的參數具體意義如下:

expand:如果設為true,就表示下面檔名的佔位符(即號)都要擴充成具體的檔名。
cwd:需要處理的檔案(input)所在的目錄。 src:表示需要處理的檔案。如果採用數組形式,數組的每一項就是一個檔名,可以使用通配符。
dest:表示處理後的檔案名稱或所在目錄。 ext:表示處理後的檔案後綴名。
除了上面這些參數,還有一些參數也是grunt所有模組通用的。

filter:一個傳回布林值的函數,用來過濾檔案名稱。只有傳回值為true的文件,才會被grunt處理。 dot:是否符合以點號(.)開頭的系統檔案。
makeBase:如果設定為true,就只符合檔案路徑的最後一部分。例如,a?b可以匹配/xyz/123/acb,而不匹配/xyz/acb/123。
關於通配符,意義如下:
:匹配任意數量的字符,不包括/。 ?:匹配單一字符,不包括/。
**:匹配任意數量的字符,包括/。 {}:允許使用逗號分隔的列表,表示「or」(或)關係。
!:用於模式的開頭,表示只回傳不符的情況。
例如,foo/
.js匹配foo目錄下面的文件名以.js結尾的文件,foo//.js匹配foo目錄和它的所有子目錄下面的文件名以.js結尾的文件,!.css表示符合所有後綴名不為「.css」的檔案。

使用通配符設定src屬性的更多範例:
(2)grunt.loadNpmTasks

grunt.loadNpmTasks方法載入模組檔案。
(3)grunt.registerTask

grunt.registerTask方法定義如何呼叫特定的任務。 “default”任務表示如果不提供參數,直接輸入grunt指令,則先執行 “cssmin:minify”,然後再執行“cssmin:combine”,即先壓縮再合併。如果只執行壓縮,或只執行合併,則需要在grunt指令後 面指明「模組名:目標名」。
grunt-contrib-clean:刪除檔案。
*
grunt-contrib-compass:使用compass編譯sass檔。
*
grunt-contrib-concat:合併檔案。
*
grunt-contrib-copy:複製檔案。
*
grunt-contrib-cssmin:壓縮以及合併CSS檔案。
*
grunt-contrib-imagemin:影像壓縮模組。
*
grunt-contrib-jshint:檢查JavaScript語法。
*
grunt-contrib-uglify:壓縮以及合併JavaScript檔案。
*
grunt-contrib-watch:監視文件變動,做出對應動作。
模組的前綴如果是grunt-contrib,就表示該模組由grunt開發團隊維護;如果前綴是grunt(例如grunt-pakmanager),就表示由第三方開發者維護。

以下選幾個模組,看看它們配置參數的寫法,也就是說如何在grunt.initConfig方法中配置各個模組。

### grunt-contrib-jshint

jshint用來檢查文法錯誤,例如分號的使用是否正確、有沒有忘記寫括號等等。它在grunt.initConfig方法裡面的設定碼如下。
/.js'] },

上面程式碼先指定jshint的檢查項目,eqeqeq表示要用嚴格相等運算符取代相等運算符,trailing表示行尾不得有多餘的空格。然後,指定files屬性,表示檢查目標是Gruntfile.js文件,以及lib目錄的所有子目錄下面的JavaScript檔案。

### grunt-contrib-concat

concat用來合併同類文件,它不僅可以合併JavaScript文件,還可以合併CSS文件。
.js', dest : ‘js/‘ } },

上面代码中的options属性指定压缩后文件的文件头,以及sourceMap设置;target目标指定输入和输出文件。

### grunt-contrib-copy

copy模块用于复制文件与目录。


copy: { main: { src: ‘src/<em>‘, dest: ‘dest/‘, }, },</em>


上面代码将src子目录(只包含它下面的第一层文件和子目录),拷贝到dest子目录下面(即dest/src目录)。如果要更准确控制拷贝行为,比如只拷贝文件、不拷贝目录、不保持目录结构,可以写成下面这样:


copy: { main: { expand: true, cwd: ‘src/‘, src: ‘*‘, dest: ‘dest/‘, flatten: true, filter: ‘isFile', }, },

grunt-contrib-watch

watch模块用来在后台运行,监听指定事件,然后自动运行指定的任务。


watch: { scripts: { files: ‘<strong>/*.js', tasks: ‘jshint', options: { livereload: true, }, }, css: { files: ‘</strong>/<em>.sass', tasks: [‘sass'], options: { livereload: true, }, }, },</em>


设置好上面的代码,打开另一个进程,运行grunt watch。此后,任何的js代码变动,文件保存后就会自动运行jshint任务;任何sass文件变动,文件保存后就会自动运行sass任务。

需要注意的是,这两个任务的options参数之中,都设置了livereload,表示任务运行结束后,自动在浏览器中重载(reload)。这需要在浏览器中安装livereload插件。安装后,livereload的默认端口为localhost:35729,但是也可以用livereload: 1337的形式重设端口(localhost:1337)。

### 其他模块

下面是另外一些有用的模块。

(1)grunt-contrib-clean

该模块用于删除文件或目录。


clean: { build: { src: [“path/to/dir/one”, “path/to/dir/two”] } }


(2)grunt-autoprefixer

该模块用于为CSS语句加上浏览器前缀。


autoprefixer: { build: { expand: true, cwd: ‘build', src: [ ‘**/.css' ], dest: ‘build' } },


(3)grunt-contrib-connect

该模块用于在本机运行一个Web Server。


connect: { server: { options: { port: 4000, base: ‘build', hostname: ‘<em>‘ } } }</em>


connect模块会随着grunt运行结束而结束,为了使它一直处于运行状态,可以把它放在watch模块之前运行。因为watch模块需要手动中止,所以connect模块也就会一直运行。

(4)grunt-htmlhint

该模块用于检查HTML语法。


htmlhint: { build: { options: { ‘tag-pair': true, ‘tagname-lowercase': true, ‘attr-lowercase': true, ‘attr-value-double-quotes': true, ‘spec-char-escape': true, ‘id-unique': true, ‘head-script-disabled': true, }, src: [‘index.html'] } }


上面代码用于检查index.html文件:HTML标记是否配对、标记名和属性名是否小写、属性值是否包括在双引号之中、特殊字符是否转义、HTML元素的id属性是否为唯一值、head部分是否没有script标记。

(5)grunt-contrib-sass模块

该模块用于将SASS文件转为CSS文件。


sass: { build: { options: { style: ‘compressed' }, files: { ‘build/css/master.css': ‘assets/sass/master.scss' } } }


上面代码指定输出文件为build/css/master.css,输入文件为assets/sass/master.scss。

(6)grunt-markdown

该模块用于将markdown文档转为HTML文档。


markdown: { all: { files: [ { expand: true, src: ‘.md', dest: ‘docs/html/‘, ext: ‘.html' } ], options: { template: ‘templates/index.html', } } },


上面代码指定将md后缀名的文件,转为docs/html/目录下的html文件。template属性指定转换时采用的模板,模板样式如下。


<!DOCTYPE html> <html> <head> <title>Document</title> </head> <body> <div id=”main” class=”container”> <%=content%> </div> </body> </html>


{src: ‘foo/th<em>.js'}grunt-contrib-uglify {src: ‘foo/{a,b}</em>.js'} {src: [‘foo/a<em>.js', ‘foo/b</em>.js']}


至于combine目标,就只有一个files参数,表示输出文件是css子目录下的out.min.css,输入文件则是css子目录下的part1.min.css和part2.min.css。

files参数的格式可以是一个对象,也可以是一个数组。


files: { ‘dest/b.js': [‘src/bb.js', ‘src/bbb.js'], ‘dest/b1.js': [‘src/bb1.js', ‘src/bbb1.js'], }, // or files: [ {src: [‘src/aa.js', ‘src/aaa.js'], dest: ‘dest/a.js'}, {src: [‘src/aa1.js', ‘src/aaa1.js'], dest: ‘dest/a1.js'}, ],


如果minify目标和combine目标的属性设置有重合的部分,可以另行定义一个与minify和combine平行的options属性。


 grunt.initConfig({ cssmin: { options: { /<em> … </em>/ }, minify: { /<em> … </em>/ }, combine: { /<em> … </em>/ } } });


grunt # 默认情况下,先压缩后合并 grunt cssmin:minify # 只压缩不合并 grunt css:combine # 只合并不压缩


如果不指明目标,只是指明模块,就表示将所有目标依次运行一遍。


grunt cssmin




## 常用模块设置


grunt的模块已经超过了2000个,且还在快速增加。下面是一些常用的模块(按字母排序)。

*


jshint: { options: { eqeqeq: true, trailing: true }, files: [‘Gruntfile.js', ‘lib/
## 参考链接

同时推荐:http://www.w3cplus.com/tools/writing-awesome-build-script-grunt.html


concat: { js: { src: [‘lib/module1.js', ‘lib/module2.js', ‘lib/plugin.js'], dest: ‘dist/script.js' } css: { src: [‘style/normalize.css', ‘style/base.css', ‘style/theme.css'], dest: ‘dist/screen.css' } },


js目标用于合并JavaScript文件,css目标用语合并CSS文件。两者的src属性指定需要合并的文件(input),dest属性指定输出的目标文件(output)。

### grunt-contrib-uglify

uglify模块用来压缩代码,减小文件体积。


uglify: { options: { banner: bannerContent, sourceMapRoot: ‘../‘, sourceMap: ‘distrib/‘+name+'.min.js.map', sourceMapUrl: name+'.min.js.map' }, target : { expand: true, cwd: ‘js/origin', src : ‘

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn