如何使用Vim使JakeJS手表可靠地工作?

时间:2017-07-04 04:38:28

标签: javascript node.js vim jake

我正在使用Jakefile来帮助我从命令行更新Wordpress页面。我正在使用Jake的监视任务重新构建我编辑文件的时间。当我使用Vim编辑文件时,在第一次成功构建之后,Jake失败并出现以下错误:

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)

我尝试在规则中使用sleep函数来延迟重建。我试过这个,因为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');
}

1 个答案:

答案 0 :(得分: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);
    });
});

注意:我还在首次运行监视任务时调用了我想要调用的任务,以确保在监视启动之前所做的任何更改都已构建。