2017-07-04 98 views
0

我正在使用Jakefile來幫助我從命令行更新Wordpress頁面。我正在使用Jake的監視任務來重新構建我編輯文件的時間。當我編輯一個文件,Vim的,首次成功構建後,傑克失敗,以下錯誤:如何讓JakeJS手錶可靠地與Vim一起工作?

WatchTask started for: default 
cp home.html dist/home.html 
exec wp --path=../wordpress post list --post_type=page --format=json --fields=ID,post_name { silent: true } 
exec wp --path=../wordpress post update 2 dist/home.html --post_type=page 
Success: Updated post 2. 
jake aborted. 
Error: File-task home.html has no existing file, and no action to create one. 
    at FileBase.isNeeded (/usr/local/lib/node_modules/jake/lib/task/file_task.js:50:17) 
    at TaskBase.run (/usr/local/lib/node_modules/jake/lib/task/task.js:256:26) 
(See full trace by running task with --trace) 

我使用睡眠功能在規則拖延重建嘗試。我試過這個,因爲Vim在保存文件時,將內容寫入新的臨時文件,然後將新的臨時文件重命名爲原始文件名。我認爲構建失敗是因爲它在文件完全重命名之前嘗試構建。使用睡眠不能可靠地工作,它可能會工作一次或兩次,但然後失敗的方式與上面相同。

這裏是我的Jakefile:

var shell = require('shelljs'); 
var sleep = require('sleep'); 

shell.config.verbose = true; 

const destDir = 'dist'; 
const wpDir = '../wordpress'; 


var files = new jake.FileList(); 
files.include('*.html'); 
var outputFiles = files.toArray().map(function(fileName){ 
        return destDir + '/' + fileName; 
}); 

var sourceFile = function(name) { 
    return name.substr(name.lastIndexOf('/') + 1); 
} 
function objectToStr(object) { 
    var s = ''; 
    for(var property in object){ 
     s += property + ': ' + object[property] + '\n'; 
    } 
    return s; 
} 
function rmExt(name) { 
    return name.substr(0, name.lastIndexOf('.')); 
} 

directory(destDir); 
task('default', [destDir].concat(outputFiles)); 
task('clean', function() { 
    jake.rmRf(destDir); 
}); 
rule('dist/%.html', sourceFile, function() { 
    shell.cp(this.source, this.name); 
    var pages = JSON.parse(shell.exec('wp --path=' + wpDir 
        + ' post list --post_type=page --format=json --fields=ID,post_name', 
        { silent: true }).stdout); 
    var postId = null; 
    var l = pages.length; 
    for(var i = 0; i < l; i++){ 
     if(pages[i].post_name === rmExt(this.source)){ 
      postId = pages[i].ID; 
      break; 
     } 
    } 
    if(postId !== null){ 
     shell.exec('wp --path=' + wpDir + ' post update ' + postId 
        + ' ' + this.name + ' --post_type=page'); 
    }else{ 
     shell.echo('Unable to find matching post ID for file: ' + this.name); 
    } 
    shell.echo('1'); 
    sleep.sleep(2); 
    shell.echo('2'); 
}); 
watchTask('watch', ['default'], function() { 
    this.watchFiles.include('*.html'); 
} 
+0

大多數文件觀察者都能夠聚合事件,並且只在Vim實際寫入文件後觸發動作。 [傑克自己的觀察者](https://github.com/jakejs/jake/blob/master/lib/watch_task.js)似乎很天真,所以我建議你看看適當的選擇。 – romainl

+0

感謝您的評論@romainl。我研究了使用'inotifywait'和觀看單個文件時發生的相同問題。我在[與vim一起使用inotifywait](https://unix.stackexchange.com/questions/188873/using-inotifywait-along-with-vim)中找到了關於StackExchange的一些指導。它建議觀看目錄。這有助於解決方案。 –

+0

嘗試[modd](https://github.com/cortesi/modd)或[entr](http://entrproject.org/)。 – romainl

回答

0

我發現使用該庫node-watch一個可靠的解決方案。我用普通的Jake任務替換了watchTask,並使用node-watch調用我想要調用的任務來觀察當前工作目錄。庫node-watch能夠基於正則表達式過濾文件,因此手錶不會觸發Vim交換文件等。下面是我使用的代碼:

task('watch', function() { 
    var defaultTask = jake.Task['default']; 

    defaultTask.invoke(); 
    defaultTask.reenable(true); 

    watch('./', { filter: /.*.html$/ }, function(evt, name) { 
     defaultTask.invoke(); 
     defaultTask.reenable(true); 
    }); 
}); 

注:我也引用我要當手表的任務是第一次運行,以確保在開始之前,手錶所做的任何更改都建立呼叫的任務。