當文件被添加尿招、更改或刪除時,運行預定義的任務
安裝插件
npm install grunt-contrib-watch --save-dev
安裝完插件后,可以在Gruntfile中用這行代碼啟用插件
grunt.loadNpmTasks('grunt-contrib-watch');
可以使用grunt watch
命令啟動這個任務
設置
files
類型: String|Array
定義了這個任務將要監(jiān)視的文件,可以為一個路徑字符串或者一個字符串的數(shù)組.
tasks
類型: `String|Array`
這定義了當監(jiān)視的文件事件發(fā)生時要運行的任務厢破。
options.spawn
類型:Boolean
默認值:true
默認會創(chuàng)建一個新的子進程來執(zhí)行觸發(fā)的任務。通過設置為 false
约急,可以使得觸發(fā)的任務可以共享進程上下文启昧,并且提高速度。但是疆柔,這會導致監(jiān)控任務容易崩潰咒精,所以,請盡量使用這個特性旷档,在新的子進程中執(zhí)行任務模叙。
watch: {
scripts: {
files: ['**/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
options.interrupt
類型:Boolean
默認值:false
在文件發(fā)生修改的時候,會生成子進程來執(zhí)行任務鞋屈,默認的行為是對于每個目標來說向楼,在上一個處理完成之后,僅僅生成一個新的子進程來執(zhí)行任務谐区。設置 interrupt
為 true
湖蜕,將會導致中止上一個進程,生成一個新進程來處理最后的變更宋列。
watch: {
scripts: {
files: '**/*.js',
tasks: ['jshint'],
options: {
interrupt: true,
},
},
},
options.debounceDelay
類型:Integer
默認值:500
如果同樣的文件或者路徑被修改昭抒,需要等待多長時間才觸發(fā)事件。默認 500 毫秒炼杖。
options.event
類型:String|Array
默認值:'all'
指定監(jiān)控目標的特定事件類型灭返,可以為 'all', 'changed', 'added' 和 'deleted'.
options.reload
類型:Boolean
默認值:false
默認情況下,如果 Gruntfile.js
文件被監(jiān)控坤邪,在這個文件被修改之后熙含,會導致監(jiān)控任務重新啟動。并且重新加載 Gruntfile.js
艇纺。
如果 reload
設置為 true
怎静,任何被監(jiān)控文件的修改都會導致監(jiān)控任務重新啟動。除非你的 Gruntfile.js
依賴于其它文件黔衡,否則不使用這個參數(shù)蚓聘。
options.forever
類型:Boolean
默認值:true
這是整個任務級別的參數(shù),不能在單個目標上配置盟劫。默認情況下夜牡,監(jiān)控任務會處理 grunt.fatal
和 grunt.warn
,防止導致的退出監(jiān)控問題侣签。如果你不希望監(jiān)控任務覆蓋 grunt.fatal
和 grunt.warn
塘装,可以將 forever 設置為 false
急迂。
options.dateFormat
類型: Function
這是一個任務級別的參數(shù),不能在單個目標上配置。默認情況下蹦肴,當watch完成任務時袋毙,它將顯示消息Completed in 1.301s at Thu Jul 18 2013 14:58:21 GMT-0700 (PDT) - Waiting...
您可以通過提供自己的函數(shù)來覆蓋此消息:
atch: {
options: {
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
grunt.log.writeln('Waiting for more changes...');
},
},
scripts: {
files: '**/*.js',
tasks: 'jshint',
},
},
options.atBegin
類型:Boolean
默認值:false
此選項將在監(jiān)視器啟動時觸發(fā)每個指定任務的運行。
options.livereload
類型:Boolean|Number|Object
默認值:false
設置為true
或設置為端口號以啟動實時加載,默認和推薦的端口號是35729
如果啟用了一個實時重新加載服務器冗尤,則將啟動每個目標的watch任務听盖。然后在指定的任務運行后,將通過修改的文件觸發(fā)實時重新加載服務器裂七。
另請參閱如何在HTML上啟用livereload皆看。
例:
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: true,
},
},
},
給livereload
傳遞一個對象允許偵聽特定端口和主機名/ IP或https連接(通過key
和cert
參數(shù) )
options.cwd
類型:String|Object
默認值:process.cwd()
能夠設置當前工作目錄。默認為process.cwd()
背零⊙鳎可以是一個字符串,以設置cwd來匹配文件和生成任務或一個對象來獨立設置
ptions: {
cwd: {
files: 'match/files/from/here',
spawn: 'but/spawn/files/from/here'
}
}
在發(fā)射事件之前剝離路徑:
options: {
cwd: {
files: 'a/path',
event: 'a/path'
}
}
a/path
在發(fā)射事件之前將被剝離徙瓶。此選項對于指定與livereload一起使用的基本目錄很有用毛雇。
options.livereloadOnError
類型:Boolean
默認值:true
如果執(zhí)行的任務遇到錯誤,則可以防止實時重新啟動侦镇。如果設置為false
灵疮,則只有當所有任務成功完成時,才會觸發(fā)活動載入壳繁。
示例
//簡單的配置,在任何添加文件震捣,更改或刪除的時候運行jshint
grunt.initConfig({
watch: {
files: ['**/*'],
tasks: ['jshint'],
},
});
//高級配置 在添加,更改或刪除特定文件時運行特定任務闹炉。
grunt.initConfig({
watch: {
gruntfile: {
files: 'Gruntfile.js',
tasks: ['jshint:gruntfile'],
},
src: {
files: ['lib/*.js', 'css/**/*.scss', '!lib/dontwatch.js'],
tasks: ['default'],
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit'],
},
},
});
使用watch
事件
watch
當觀察文件被修改時蒿赢,此任務將發(fā)出一個事件。如果您希望編輯文件時簡單通知渣触,或者如果您正在使用此任務與另一項任務相一致羡棵,這將非常有用。以下是使用watch事件的簡單示例:
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
},
},
});
grunt.event.on('watch', function(action, filepath, target) {
grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});
watch事件不是用來替換配置和運行標準的Grunt API的,如果嘗試從watch事件中執(zhí)行任務,可能會遇到錯誤
根據(jù)需要編譯文件
一個非常普遍的要求是只根據(jù)需要編譯文件.這里是一個例子嗅钻,只有改變內(nèi)容的文件才執(zhí)行jshint任務:
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
jshint: {
all: {
src: ['lib/*.js'],
},
},
});
// On watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
grunt.config('jshint.all.src', filepath);
});
如果您需要動態(tài)修改配置皂冰,則spawn設置為false
,以使watch在相同的上下文下運行啊犬。
如果您同時保存多個文件灼擂,您可以選擇更強大的方法:
var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
grunt.config('jshint.all.src', Object.keys(changedFiles));
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});
Live Reloading
Live Reloading已經(jīng)內(nèi)置在watch任務中.設置選項livereload
,true
使用默認端口35729
或設置為自定義端口:livereload: 1337
觉至。
grunt.initConfig({
watch: {
options: {
livereload: true,
},
css: {
files: ['public/scss/*.scss'],
tasks: ['compass'],
},
},
});
您還可以為單個監(jiān)視目標配置實時重新載入,或運行多個實時重新加載服務器睡腿。只要確定您是否啟動在不同端口上運行的多臺服務器:
grunt.initConfig({
watch: {
css: {
files: ['public/scss/*.scss'],
tasks: ['compass'],
options: {
// Start a live reload server on the default port 35729
livereload: true,
},
},
another: {
files: ['lib/*.js'],
tasks: ['anothertask'],
options: {
// Start another live reload server on port 1337
livereload: 1337,
},
},
dont: {
files: ['other/stuff/*'],
tasks: ['dostuff'],
},
},
});
在HTML中啟用實時重新加載
一旦啟動了live reload服務器语御,就可以訪問live reload腳本峻贮。在頁面上啟用實時重新加載,在閉合標簽</body>
前面田間一個script標簽指向livereload.js
<script src="http://localhost:35729/livereload.js"></script>
請隨意將此腳本添加到您的模板環(huán)境中,并以某種形式的dev
標志進行切換应闯。
使用實時重新加載瀏覽器擴展
您可以通過安裝瀏覽器擴展程序來重新加載頁面纤控,而不是在頁面中添加腳本標記。請訪問如何安裝和使用瀏覽器擴展來幫助安裝瀏覽器的擴展
碉纺。
一旦安裝船万,請使用默認的實時重新加載端口35729
,瀏覽器擴展將自動重新加載您的頁面骨田,而不需要<script>
標簽耿导。
使用連接中間件
由于在開發(fā)時使用了live reloading,所以您可能想要禁用生成的構(gòu)建(并且不使用瀏覽器擴展)态贤。一種方法是使用連接中間件將腳本標簽插入到頁面中舱呻。嘗試使用connect-livereload中間件將實時重新加載腳本注入到您的頁面中。
封裝自己的Live Reload
框架tiny-lr可以很輕松得實現(xiàn)Live reloading,鼓勵閱讀文檔tiny-lr
,如果想自己觸發(fā)live reload服務,只需將文件POST到URL:http://localhost:35729 /changed
,或者如果你想封裝自己的live reload 實現(xiàn)悠汽,請使用以下示例:
// Create a live reload server instance
var lrserver = require('tiny-lr')();
// Listen on port 35729
lrserver.listen(35729, function(err) { console.log('LR Server Started'); });
// Then later trigger files or POST to localhost:35729/changed
lrserver.changed({body:{files:['public/css/changed.css']}});