在构建脚本中使用 util.promisfy 无法按预期工作
Posted
技术标签:
【中文标题】在构建脚本中使用 util.promisfy 无法按预期工作【英文标题】:Using util.promisfy in build script not working as expected 【发布时间】:2019-03-07 20:45:24 【问题描述】:我在节点中有一个构建脚本,它在某一时刻重写了指向 ./dist 引用的链接中的所有 ./src 引用。我一直在阅读 util.promisfy 并尝试将 async/await 合并到我的脚本中,但它没有按计划工作。我可以将我的文件从 /src 移动到 /dist 目录并 uglify index.js 并压缩我的图像,但是使用节点 fs 函数来读取和写入我的 index.html 文件来更新链接是行不通的。下面是 build.js 的相关部分:
const fs = require("fs");
const fc = require("file-copy");
const promisify = require("util");
const copyFileAsync = promisify(fs.access); // convert fs.access to a promise
const readFileAsync = promisify(fs.readFile); // convert fs.readFile to a promise
const confirmWriteAsync = promisify(fs.stat); // convert fs.stat to a promise;
const writeFileAsync = promisify(fs.writeFile); // convert fs.writeFile to a promise
const mkdirp = require("mkdirp");
// Compressed and uglified files here ok //
// ============ Copy index.html to dist/index.html(copyIndexHtml) ============ //
/* jshint ignore:start */
const copyIndexFile = async function(result)
try
console.log(result);
await copyFileAsync(
"./index.html",
fs.constants.R_OK | fs.constants.W_OK
)
await fc("./index.html", "./dist/index.html");
catch (err)
console.log("ERROR:", err);
return "Copied Index.html to /dist!";
; // end copyIndexFile
/* jshint ignore:end */
// ================== End copyIndexFile ================ //
// ====== Read data from dist/index.html(getData) =============== //
/* jshint ignore:start */
const getData = async function(result)
console.log(result);
// Lets update dist/index.html file src and href links to reflect new location.
console.log(
"index.html: Redoing file links to reflect move to /dist folder."
);
try
const fileContents = await readFileAsync("./dist/index.html",
encoding: "utf8"
);
console.log("CONTENT:", fileContents);
// check and replace both src= and href= links to reflect chenge to dist/ folder
// Notice we chained .replace to do it
const regEx1 = /src\s*=\s*"\.\/src\//gi;
const regEx2 = /src\s*=\s*'\.\/src\//gi;
const regEx3 = /href\s*=\s*"\.\/src\//gi;
const regEx4 = /href\s*=\s*'\.\/src\//gi;
let distIndexHtml = fileContents
.replace(regEx1, 'src="./')
.replace(regEx2, "src='./")
.replace(regEx3, 'href="./')
.replace(regEx4, "href='./");
console.log(distIndexHtml);
// Confirm Write to index.html
await confirmWriteAsync("./dist/index.html", function(err, stats)
if (err)
console.log(`Error: $err`);
else if (stats.size === 0)
console.log(`Error copying index.html!!!!!!`);
else
console.log(
`Succesfully copied to dist\index.html. File size is $
stats.size
`
);
);
await writeFileAsync(
"dist/index.html",
distIndexHtml,
"utf8",
err =>
if (err)
reject(err);
else
resolve("Write to dist//index.html OK.");
);
catch (err)
console.log("ERROR:", err);
return "Read /dist/index.html file!!";
;
/* jshint ignore:end */
// ==================================================== //
// ========== Call promise chain ====================== //
// ==================================================== //
browserifyJS()
.then(
result =>
return compressImages(result);
,
err =>
console.log(err);
return compressImages(err);
)
.then(result =>
return copyIndexFile(result);
)
.then(result =>
return getData(result);
)
.then(result =>
console.log(result);
);
// mkdirp else end
); // mkdirp callback end
); // rimraf callback end
更正后更新控制台读数:控制台读数为:
npm run build
> sports-page-app@1.0.0 build C:\Users\akillian\Local Documents\GitHub\sports-page-app
> node ./scripts/build
main.css: build and uglify
Checking for index.js
Bundling Successful!
Images Compressed!!!
/dist/index.js: build and uglify
Copied Index.html to /dist!
index.html: Redoing file links to reflect move to /dist folder.
CONTENT:
Succesfully copied to distindex.html. File size is 3059
~\Local Documents\GitHub\sports-page-app [refactor-app ≡ +0 ~1 -0 !]
CONTENT 现在是空白的。
【问题讨论】:
【参考方案1】:你有这个:
await copyFileAsync(
"./index.html",
fs.constants.R_OK | fs.constants.W_OK,
err =>
if (err)
console.log("No index.html file present!");
else
// Note: fc() returns a promise and no .catch()
// This also means the code continues on without
// waiting for the file to copy.
fc("./index.html", "./dist/index.html");
);
但是如果你承诺它,就没有错误回调函数。 简单地说:
await copyFileAsync(
"./index.html",
fs.constants.R_OK | fs.constants.W_OK
)
await fc("./index.html", "./dist/index.html");
你的 try/catch 会得到错误。
此外,即使出现错误,也始终返回特定的 try/catch return "Copied Index.html to /dist!";
,因此我建议制作两个返回语句,一个在 try
内,一个在 catch
内,或者使用 finally
如果没关系。
【讨论】:
非常感谢!做到了。所以当你承诺你否定任何 fs 方法的回调时? 我问是因为控制台读数显示更新的链接,但当我查看 ./dist/index.html 时没有显示?? 是的,你应该,一般来说。一些 fs 方法是“事件发射器”,我相信你不能使用 promisify。 Promisify 应该只用于节点样式的回调函数,.e.g.someFunction(foo,bar,function(err,data))
以上是关于在构建脚本中使用 util.promisfy 无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
Jenkins作业无法在构建期间将整数参数传递给python脚本
为啥尽管在图像构建期间通过 `composer global install` 安装了“drush”,但我无法从正在运行的 PHP 脚本中找到该工具?