Grunt是構建Web開發的一個系統,但它建立比較困難。在這個指南中,你將學會如何配置Grunt建立一個現代的Web項目。當你完成教程中的配置以後,你的Gruntfile
將具備:javascript
Stylus
文件和給他們添加前綴;CoffeeScript
;CSS
和JavaScript
文件;Jade
;Grunt具備一箇中文版本官網,若是你對Grunt感興趣,能夠點擊這裏查閱相關中文文檔。css
開始html
若是你尚未開始使用Grunt,你須要先安裝「Node.js」和「NPM」。你還須要經過在命令端中輸入命令npm install -g grunt-cli
來安裝Grunt。這樣在你的系統中容許你在任何地方使用grunt
命令使用你的Grunt。前端
建立一個package.json
文件,並添加下面的內容:java
{
"name": "grunt_tutorial",
"description": "An example of how to set up Grunt for web development.",
"author": "Landon Schropp (http://landonschropp.com)",
"dependencies": {
"grunt": "0.x.x",
"grunt-autoprefixer": "0.2.x",
"grunt-contrib-clean": "0.5.x",
"grunt-contrib-coffee": "0.7.x",
"grunt-contrib-connect": "0.4.x",
"grunt-contrib-copy": "0.4.x",
"grunt-contrib-cssmin": "0.6.x",
"grunt-contrib-jade": "0.8.x",
"grunt-contrib-jshint": "0.6.x",
"grunt-contrib-stylus": "0.8.x",
"grunt-contrib-uglify": "0.2.x",
"grunt-contrib-watch": "0.5.x"
},
"engine": "node >= 0.10"
}
這個文件定義了您的項目做爲一個NPM
包和您的項目所依賴須要的聲明。每一個聲明都有本身的一個版本號。例如,grunt-contrib-copy:"0.4.x"
告訴NPM
安裝0.4最新的版本grunt-contrib-copy
包。在你的命令終端運行npm
安裝你須要管理插件。node
複製git
一個好的運行腳本老是能讓源碼和文件分開。這樣分離容許你修改源文件而不會影響腳本。github
開始,你會讓Grunt從source
目錄中複製文件到build
目錄中。須要建立一個Gruntfile.js
文件,並將下面的代碼複製到這個文件中:web
module.exports = function(grunt) { // 配置任務 grunt.initConfig({ copy: { build: { cwd: 'source', src: [ '**' ], dest: 'build', expand: true }, }, }); // 加載任務 grunt.loadNpmTasks('grunt-contrib-copy'); // 定義任務 };
讓咱們來分解一下。在Node
中,須要一個模塊,經過modules.exports
函數來調取並返回值。在Gruntfile
文件中經過modules.exports
告訴Node
定義Grunt配置,並返回一個函數。grunt.initConfig
是一個方法,他接受一個參數:一個對象的屬性配置一個Grunt任務。ajax
在Grunt配置中,您已添加了一個copy
任務。這個任務有一個子任務,叫build
。在Grunt中,多個任務稱爲多任務。對於copy
任務,你不須要此功能,但它仍然須要有至少一個子任務。
在Grunt建立子任務是文件數組格式。這種格式是Grunt提供源文件到一個任務的一個格式方法之一。cwd
指向源文件的目錄都是相對的,和src
指定源文件相似。**
是一個通配符,用來匹配Grunt任何文件。dest
是Grunt用來輸出結果任務。你將設置build
目錄,告訴Grunt將內容複製到build
目錄中。若是有一個source/index.html
文件,這個配置將輸出build/index.html
文件。最後,你設置expand
參籹爲true
來開啓這些選項。
grunt.loadNpmTasks("grunt-contrib-copy")
告訴Grunt從grunt-contrib-copy
包中加載任務。這給咱們一個copy
命令,您能夠在你的命令控制檯中經過grunt copy
命令實現複製功能。
Clean
如今你有一個build
目錄,他是用來完成clean
任務。而後你將下面的配置複製到裏面:
clean: { build: { src: [ 'build' ] }, },
就像copy
,你設置了一個clean
目標和任務配置,clean
配置了一個src
,設置了build
,用來移除build
目錄。
接下來使用grunt.loadNpmTask("grunt-contrib-clean")
,加載一個clean
任務,容許你在命令終端運行grunt clean
命令。
grunt.loadNpmTasks('grunt-contrib-clean');
Build
若是你有一個build
任務,在複製新的源文件以前須要先刪除舊的build
,這並非很好,讓咱們來添加一個任務。
// 定義任務 grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy' ] );
這個registerTask
方法建立了一個新的任務。第一參數,build
,定義了這個任務的名稱。第二個用來描述這個任務。最後一個參數是一個將要運行的任務數組,這個build
任務,先運行clean
任務,接着運行copy
任務。
Stylus
Stylus是一種CSS預處理語言。它在CSS上加強了幾個功能,包括添加變量、嵌套和函數等功能。
stylus: { build: { options: { linenos: true, compress: false }, files: [{ expand: true, cwd: 'source', src: [ '**/*.styl' ], dest: 'build', ext: '.css' }] } },
這個任務與其餘的任務稍有不一樣。這仍然是build
的一子任務,但他包含兩個屬性:options
和files
。options
指定了想要完成任務的行爲。咱們添加了兩個選擇項:compress
決定CSS輸出是否被壓縮和linenos
在Stylus源文件中選擇器添加行號。
files
在格式化文件以前設置了一些數組參數。運行這個任務後,source
目錄下的.styl
文件擴展編譯輸出文件.css
。
如今stylus
任務是將CSS文件輸出到build
目錄,沒有任何理由將Stylus文件複製到build
目錄任何地方。讓咱們修改copy
配置來阻止這樣的事情發生。
copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl' ], dest: 'build', expand: true }, },
在文件路徑的開始處能夠防止Grunt的匹配模式。別忘了在
build
任務中添加stylus
。
grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylus' ] );
Autoprefixer
Autoprefixer是Stylus尤物移人編譯成CSS後,給CSS3屬性添加前綴插件。他是一個強大的庫,正如Nib和Compass。
繼續添加autoprefixer
配置:
autoprefixer: { build: { expand: true, cwd: 'build', src: [ '**/*.css' ], dest: 'build' } },
注意到模式了嗎?這個配置很是相似於其餘任務。一個明顯的差別是cwd
和dest
兩個都設置爲build
。使用的autoprefixer
輸出的文件和讀取的文件在同一個目錄中。
和前面的同樣,你也須要加載autoprefixer
任務。
grunt.loadNpmTask('grunt-autoprefixer');
不是把全部的CSS任務添加到build
中,建立一個添加樣式的新任務和將任務添加到build
中。
// 配置任務 grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylesheets' ] );
CSS壓縮
客戶端加載一羣龐大的CSS文件文件,會真正的減慢網站加載時間。幸運的是grunt-contrib-cssmin
包能夠將CSS文件壓縮,並將多個文件合併成一個單一的文件。咱們再次開始配置。
cssmin: { build: { files: { 'build/application.css': [ 'build/**/*.css' ] } } },
使用文件數組格式,這個配置使用Grunt的文件對象格式,將幾個文件指定到一個目的地。全部build
目錄下的CSS文件壓縮後輸出到build/application.css
。
加載CSS壓縮任務包而且將stylesheets
添加到任務中。
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer', 'cssmin' ] );
CoffeeScript
CoffeeScript是編譯JavaScript一種奇特的語言。他有乾淨、漂亮的語法,包括類名和隱藏大量JavaScript不足的一面。
將CoffeeScript加入到項目中很是容易。首先,添加到配置中:
coffee: { build: { expand: true, cwd: 'source', src: [ '**/*.coffee' ], dest: 'build', ext: '.js' } },
將源文件中的CoffeeScript文件,改變他們的擴展名爲.js
,並將他們輸出到build
目錄中。接下來,經過grunt-contrib-coffee
加載任務包。
grunt.loadNpmTasks('grunt-contrib-coffee');
將scripts
任務加載到build
任務中:
grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylesheets', 'scripts' ] );
再次,你須要添加一個copy
擴展,由於CoffeeScript文件並無複製到build
目錄中。
copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee' ], dest: 'build', expand: true }, },
Uglify
像cssmin
同樣,Uglify壓縮JavaScript文件,並將壓縮成一個文件。這裏是他的配置:
uglify: { build: { options: { mangle: false }, files: { 'build/application.js': [ 'build/**/*.js' ] } } },
默認狀況之下,UglifyJS將使你的腳本用更短的名字來取代變量和函數名。若是你的項目代碼是自已的那仍是很方便的,若是要共享到另外一個項目中,會帶來問題。設置false
將會關掉這種行爲。
像cssmin
任務同樣,這個任務也須要添加文件對象格式。
加載任務包,並像scripts
任務將uglify
添加到任務中:
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee', 'uglify' ] );
清理
當你運行grunt build
,除了build/application.css
和build/application.js
以外,其餘全部的CSS和JavaScript文件都會掛在build
目錄下。既然你不須要他們,能夠添加子任務刪除它們,下面的是clean
配置:
clean: { build: { src: [ 'build' ] }, stylesheets: { src: [ 'build/**/*.css', '!build/application.css' ] }, scripts: { src: [ 'build/**/*.js', '!build/application.js' ] }, },
當你運行這個任務,哪果你沒有指定子任務,Grunt會運行這些任務。若是你運行grunt clean
,將執行clean:build
,clean:stylesheets
和clean:scripts
。若是clean
不能刪除一個文件,它只是會忽略它,這個並非什麼問題。
注意build/application.css
和build/application.js
排除了stylesheets
和scripts
的子任務。你並不想刪除他們,這些畢竟是努力工做得來的。
更新任務時,使用適應的子任務:
// define the tasks grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ] ); grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee', 'uglify', 'clean:scripts' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean:build', 'copy', 'stylesheets', 'scripts' ] );
Jade
Jade是HTML模板語言。經過grunt-contrib-jade
包將Jade
添加到你的項目中:
jade: { compile: { options: { data: {} }, files: [{ expand: true, cwd: 'source', src: [ '**/*.jade' ], dest: 'build', ext: '.html' }] } },
像stylus
和coffee
任務同樣,jade
配置也使用了文件數組。在options
內設置了data
對象。當Jade文件編譯時,這個對象傳遞到每一個模板中。這很是方便,例如建立單獨的開發或動態生成內容。
和前面的同樣,你須要在copy
添加擴展:
copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ], dest: 'build', expand: true }, },
別忘了在build
中添加grunt-contrib-jade
任務:
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade' ] );
Watch
你的Gruntfile如今已經很強大了,但不是很好,由於你每次都得去運行grunt build
。使用grunt-contrib-watch
,就不須要每次運行。讓咱們來配置一個這樣的任務,你會看到源代碼,並自動構建他們的變化。
watch: { stylesheets: { files: 'source/**/*.styl', tasks: [ 'stylesheets' ] }, scripts: { files: 'source/**/*.coffee', tasks: [ 'scripts' ] }, jade: { files: 'source/**/*.jade', tasks: [ 'jade' ] }, copy: { files: [ 'source/**', '!source/**/*.styl', '!source/**/*.coffee', '!source/**/*.jade' ], tasks: [ 'copy' ] } },
stylesheets
,scripts
和jade
子任務能夠監測到Stylus,CoffeeScript和Jade文件變化和運行各自的任務。在copy
任務中測試全部剩下文件並將其複製到build
目錄下。
再次,你須要加載Grunt任務。
grunt.loadNpmTasks('grunt-contrib-watch');
開發者服務器
沒有Web服務器開發環境是一個不完整的。grunt-contrib-connect
包是一個全功能的靜態文件服務器,用於你的項目中很是的完美。
connect: { server: { options: { port: 4000, base: 'build', hostname: '*' } } },
你配置的主機服務器build
目錄在4000端口上。默認狀況之下,在你本地主機上鍊接服務器是localhost
。你能夠設置hostname
爲*
能夠從任何地方訪問服務器。
和前面的同樣,你須要給NPM任務中添加載加任務項。
grunt.loadNpmTasks('grunt-contrib-connect');
若是你在命令終端嘗試運行grunt connect
,服務器運行,而後立刻中止。這是由於默認狀況下,Grunt connet
任務不會一直運行下去,你須要瞭解如何修改這個問題。
默認
在全部任務之中運行單個任務,並不很完美。default
任務是這樣設置:
grunt.registerTask( 'default', 'Watches the project for changes, automatically builds them and runs a server.', [ 'build', 'connect', 'watch' ] );
default
任務運行build
建立一個初始的build
,而後它開始鏈接服務器,最後它會運行watch
,監測文件變化和從新構建。由於watch
一直在運行,因此服務器一直在運行。在你的控制檯上運行grunt
,而後到http://localhost:4000查看你的項目。
總結
在這篇教程中咱們已經討論了不少,但Grunt還有不少事情能夠作。對於一個完整的Grunt列表插件,能夠查看Grunt插件網站。
擴展閱讀
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了我的對技術的理解。若是翻譯有不對之處,還煩請同行朋友指點。謝謝!
英文原文:http://www.sitepoint.com/writing-awesome-build-script-grunt/
中文譯文:http://www.w3cplus.com/tools/writing-awesome-build-script-grunt.html