現在 watch 中已經集成了 livereload ,所以把它們放在一起說明。
watch 可以監控特定的文件,在添加文件、修改文件、或者刪除文件的時候自動執行自定義的任務,比如 livereload 等等。
1. 安裝
項目定義在 GitHub 上,地址:https://github.com/gruntjs/grunt-contrib-watch
可以通過 NPM 直接進行安裝
npm install grunt-contrib-watch --save-dev
安裝之后,需要在 Gruntfile.js 中添加任務的注冊。
grunt.loadNpmTasks('grunt-contrib-watch');
通過 grunt watch 運行 watch 任務。
2. 配置 watch
與 connect 類似,在 watch 下面定義自己的子任務,下面的示例將會監控 src 目錄下的任意 *.html 文件,在文件被修改之后,輸出被修改的文件名。
這里通過 watch 的事件進行處理。
'use strict'; module.exports = function (grunt) { // Project configuration. grunt.initConfig({ watch:{ start:{ files: ['src/*.html'] } } }); grunt.event.on('watch', function(action, filepath, target) { grunt.log.writeln(target + ': ' + filepath + ' has ' + action); }); grunt.loadNpmTasks('grunt-contrib-watch'); }
我們啟動 watch 任務,注意這個任務會持續監控。
PS C:\study\grunt> grunt watch Running "watch" task Waiting... start: src\index.html has changed >> File "src\index.html" changed. Completed in 0.001s at Sun Sep 06 2015 14:52:52 GMT+0800 (China Standard Time) - Waiting...
這里我們使用了 files 參數,這個參數可以為一個路徑字符串或者一個字符串的數組,作為監控的目標。路徑的寫法可以參考:Grunt 之通配符
多數情況下,我們希望在文件發生變化之后,直接執行特定的任務,比如在修改了 *.js 的腳本文件之后,自動進行文件檢查。這可以通過 tasks 來直接聲明。
這里的 jshint 是我們后面會講到的一個 javascript 語法檢查庫,現在還不能用呀。
watch: { scripts: { files: ['**/*.js'], tasks: ['jshint'] }, },
這里我們自定義一個名為 hello 的任務。
tasks 是一個任務名稱的字符串或者,一個任務名稱的字符串數組,作為我們執行的任務。
'use strict'; module.exports = function (grunt) { // Project configuration. grunt.initConfig({ watch:{ start:{ files: ['src/*.html'], tasks: ['hello'] } } }); grunt.registerTask('hello', 'Hello, world task description.', function() { grunt.log.writeln('Hello, world.'); }); grunt.loadNpmTasks('grunt-contrib-watch'); }
3. 高級選項
可以通過 options 配置更加詳細的設置。
1. options.spawn
boolean 類型,默認 true。默認會創建一個新的子進程來執行觸發的任務。通過設置為 false,可以使得觸發的任務可以共享進程上下文,並且提高速度。但是,這會導致監控任務容易崩潰,所以,請盡量使用這個特性,在新的子進程中執行任務。
watch: { scripts: { files: ['**/*.js'], tasks: ['jshint'], options: { spawn: false, }, }, },
2. options.interrupt
boolean 類型,默認為 false。還是和進程相關。
在文件發生修改的時候,會生成子進程來執行任務,默認的行為是對於每個目標來說,在上一個處理完成之后,僅僅生成一個新的子進程來執行任務。設置 interrupt 為 true,將會導致中止上一個進程,生成一個新進程來處理最后的變更。
watch: { scripts: { files: '**/*.js', tasks: ['jshint'], options: { interrupt: true, }, }, },
3. options.debounceDelay
這是整數類型的參數,如果同樣的文件或者路徑被修改,需要等待多長時間才觸發事件。默認 500 毫秒。
watch: { scripts: { files: '**/*.js', tasks: ['jshint'], options: { debounceDelay: 250, }, }, },
4. options.event
字符串或者數組,默認為 'all'
指定監控目標的特定事件類型,可以為 'all', 'changed', 'added' 和 'deleted'.
watch: { scripts: { files: '**/*.js', tasks: ['generateFileManifest'], options: { event: ['added', 'deleted'], }, }, },
5. options.reload
boolean 類型參數,默認為 false。
默認情況下,如果 Gruntfile.js 文件被監控,在這個文件被修改之后,會導致監控任務重新啟動。並且重新加載 Gruntfile.js。
如果 reload 設置為 true,任何被監控文件的修改都會導致監控任務重新啟動。除非你的 Gruntfile.js 依賴於其它文件,否則不使用這個參數。
watch: { configFiles: { files: [ 'Gruntfile.js', 'config/*.js' ], options: { reload: true } } }
6. options.forever
boolean 類型參數,默認為 true。
這個整個任務級別的參數,不能在單個目標上配置。默認情況下,監控任務會處理 grunt.fatal 和 grunt.warn ,防止導致的退出監控問題。如果你不希望監控任務覆蓋 grunt.fatal 和 grunt.warn ,可以將 forever 設置為 false。
options.atBegin
boolean 類型,默認為 false。
在監控任務啟動的時候,自動觸發對應的任務。
7. options.cwd
字符串或者對象類型,默認為 process.cwd()
設置當前的工作目錄,默認為 process.cwd(),可以設置為字符串的目錄來定義監控和產生的子任務的目錄,或者一個對象來描述各自獨立的路徑。
options: { cwd: { files: 'match/files/from/here', spawn: 'but/spawn/files/from/here' } }
4. livereload
這就是配合 connect 的 livereload 了。我們單獨拿出來說明。
它是 options 的一個屬性,類型為 boolean, 數值,或者配置對象。默認為 false
設置為 true 等價設置為 35729.
實際上,會啟用一個支持重新加載的服務器,這個服務器工作在上述端口號上,通過這個服務器可以獲取一個腳本,當文件被修改之后,通過這個腳本通知前端瀏覽器自動重新加載內容。
例如:
watch: { css: { files: '**/*.sass', tasks: ['sass'], options: { livereload: true, }, }, },
啟動之后,實際上在指定的端口上創建了一個服務器,如果訪問的話,可以看到返回的信息。
訪問:http://localhost:35729/
返回的內容
{"tinylr":"Welcome","version":"0.0.5"}
需要的話,還可以工作在 https 上,那就需要通過 key 和 cert 進行配置了。
watch: { css: { files: '**/*.sass', tasks: ['sass'], options: { livereload: { port: 9000, key: grunt.file.read('path/to/ssl.key'), cert: grunt.file.read('path/to/ssl.crt') // you can pass in any other options you'd like to the https server, as listed here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener } }, }, },
更多內容可以查看 enable livereload on your HTML.