Как ждать, пока файл не будет доступен в сборке Jake (Node.js)?
Есть ли способ в сборке Node.js Jake, чтобы дождаться копирования определенного файла и выполнить какую-либо операцию только после того, как будет найден файл назначения? Я думаю, что этот вопрос в значительной степени сводится к "есть ли способ синхронного копирования файлов в Node.js/Jake?" (Возможно, что-то еще, чем писать что-то с нуля, используя комбинацию fs.readSync
а также fs.writeSync
.)
Фон:
Я разрабатываю веб-приложение, которое запускается на Node.js (с Express) во время разработки, но будет развернуто на сервере Java в производственном процессе. (Мы используем Jade и Stylus в клиенте, и Express позволяет нам запускать приложение, не генерируя все файлы HTML и т. Д. И не развертывая его после каждого изменения.)
Я использую Jake для создания сборки, то есть для генерации HTML-файлов из Jade-файлов и CSS из Stylus-файлов и т. Д. Теперь я также пытаюсь объединить все файлы JavaScript приложения в один свернутый файл и изменить все HTML-файлы, чтобы использовать их вместо этого. из всех отдельных файлов JS, которые используются в "сыром" виде во время разработки.
Тем не менее, у меня сейчас есть проблема с этим последним шагом. Моя идея состояла в том, чтобы скопировать все мои файлы Jade во временный каталог для сборки развертывания и заменить ссылку (в файле Jade, используемом в качестве заголовка на всех страницах HTML) на список всех отдельных файлов 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-файлов, чтение одного файла) в свою собственную функцию, но даже это дает мне ту же ошибку. Если я запускаю сценарий несколько раз, не удаляя целевой каталог операции копирования между ними, файл может быть найден. Так, например, путь правильный, и проблема действительно заключается во времени.
1 ответ
Я не нашел ответа на главный вопрос, поэтому не знаю, поможет ли это кому-нибудь еще, столкнувшемуся с той же проблемой. Но я нашел способ обойти эту проблему.
Я прекратил использовать одни и те же оригинальные файлы Jade для двух разных преобразований, но во втором преобразовании я использую пользовательские js
функция для изменения script
ссылка тега для указания на минимизированный файл.
Т.е.
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;
}
});
Это может быть не самый красивый обходной путь, но он работает.