2013-08-23 144 views
0

有沒有在Node.js Jake構建中等待某個文件被複制,然後只有在找到目標文件之後才進行一些操作的方法?我認爲這個問題很大程度上歸結爲「是否有一種方法可以在Node.js/Jake中同步複製文件?」 (也許東西比從頭開始編寫一些東西,使用fs.readSyncfs.writeSync結合其他)。如何等待文件在Jake構建中可用(Node.js)?

背景:

我正在開發,它是在對Node.js的(含快遞)運行一個Web應用程序開發,但將部署在生產中的Java服務器上。 (我們在客戶端使用Jade和Stylus,Express使我們能夠運行應用程序,而不會生成所有HTML文件等,並在每次更改後部署它。)

我使用Jake進行構建,即生成HTML文件Jade文件和來自Stylus文件的CSS等。現在,我還試圖將所有應用程序的JavaScript文件連接成一個最小化文件,並更改所有HTML文件以使用該文件,而不是所有在「原始」文件中使用的單獨JS文件在開發期間形成。

但是,我現在有一個問題,最後一步。我的想法是將我所有的Jade文件複製到部署版本的臨時目錄中,並將引用(在所有HTML頁面中用作標題的Jade文件)替換爲所有單獨JS文件的列表通過連接並最小化整個羣體而生成。但是,當我首先將所有Jade文件複製到另一個位置(發生異步)並嘗試編輯其中一個文件時,由於複製操作尚未完成,因此打開該文件總是失敗。

這是我現在(的簡化形式)在我jakefile

var fs = require('fs'); 
var fse = require('fs-extra'); 
var path = require('path'); 
var glob = require('glob'); 
var Snockets = require('snockets'); 
var snockets = new Snockets(); 

// generating the minimized JS file 
snockets.getConcatenation(baseDir + '/scripts/all.js', { minify: true }, function(err, allJs) { 
    if (err) { 
    throw err; 
    } 

    fs.writeFileSync(generatedJsFileName, allJs); 
}); 

// copying all the Jade files to a temp dir 
glob.sync('**/*.*', { 
    cwd : srcDir 
}).forEach(function(file) { 
    var loadPath = srcDir + '/' + file; 
    var savePath = targetDir + '/' + file; 
    fse.mkdirsSync(path.dirname(savePath)); 
    fse.copy(loadPath, savePath); 
}); 

// trying to read one of the copied files (which fails, since the file cannot be found yet) 
fs.readFile(targetDir + '/views/includes/head.jade', 'utf8', function(err, data) { 
    ... 
}); 

這可能是一個愚蠢的問題,以及一個愚蠢的方式來嘗試解決擺在首位的問題。所以,對於更好的方法的建議也是非常受歡迎的。

更新:

我也嘗試過使用Parseq,將每個操作(創建JS文件,複製玉文件,讀取一個文件)在其自身的功能,但即使這給了我同樣的錯誤。如果我多次運行該腳本而不刪除其中的複製操作的目標目錄,則可以找到該文件。所以例如路徑是正確的,問題似乎是關於時間。

回答

0

我沒有真正找到主要問題的答案,所以我不知道這是否有助於其他人面臨同樣問題。但我確實找到了解決問題的方法。

我結束使用相同的原始Jade文件進行兩次不同的轉換,但在第二次轉換中,我使用自定義js函數將script標記引用更改爲指向縮小文件。

I.e.

var data = jade.compile(str, { filename: file, pretty: true })({ 
    css: function(path) { 
    return '<link rel="stylesheet" href="/styles/' + path + '.css" />'; 
    }, 
    js: function(path) { 
    var name = '<script src="/scripts/'; 

    if (path == 'all') { 
     name += generatedJsFileName; 
    } 
    else { 
     name += path + '.js'; 
    } 
    name += '"></script>'; 

    return name; 
    } 
}); 

它可能不是最漂亮的解決方法,但它的工作原理。