0

在 Node.js Jake 构建中是否有办法等到某个文件被复制后,才能在找到目标文件后才进行一些操作?我认为这个问题几乎可以归结为“有没有办法在 Node.js/Jake 中同步复制文件?” (也许不是从头开始写东西,使用 和 的组合fs.readSyncfs.writeSync

背景:

我正在开发一个在开发期间在 Node.js(使用 Express)上运行的 Web 应用程序,但将在生产中部署在 Java 服务器上。(我们在客户端使用 Jade 和 Stylus,Express 使我们能够运行应用程序而无需生成所有 HTML 文件等,并在每次更改后部署它。)

我使用 Jake 进行构建,即从 Jade 文件生成 HTML 文件,从 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 文件、复制 Jade 文件、读取一个文件)放在它自己的函数中,但即使这样也给了我同样的错误。如果我多次运行脚本而不删除中间复制操作的目标目录,则可以找到该文件。因此,例如路径是正确的,问题似乎与时间有关。

4

1 回答 1

0

我并没有真正找到主要问题的答案,所以我不知道这是否有助于其他面临同样问题的人。但我确实找到了解决问题的方法。

我结束了对两个不同的转换使用相同的原始 Jade 文件,但在第二次转换中,我使用自定义js函数将script标记引用更改为指向缩小文件。

IE

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;
  }
});

这可能不是最漂亮的解决方法,但它确实有效。

于 2013-08-28T13:45:05.563 回答