【发布时间】:2020-08-08 13:46:27
【问题描述】:
我知道,这听起来很简单。但请继续阅读以了解我面临的挑战。
我正在尝试创建一个“init”命令,以帮助设置克隆存储库以进行开发。我们使用远程包管理器,要求开发人员在处理包时在存储库中有一个.npmrc 文件(我们不想通过使用全局.npmrc 文件来限制用户)。这个过程应该是这样的:
- 在终端提示用户输入用户名
- 将
.npmrc文件写入他们的系统 - 运行
npm i - 运行
npm run build
我在我的package.json 中创建了一个新的script:
"init": "node ./scripts/writeNpmRc.js && npm i && npm run build && node ./scripts/init.js"
我的writeNpmRc.js 文件使用readline 获取用户输入,然后写入文件(请记住,此时我们还没有运行npm i,所以我们正在处理节点安装的内容)。
const readline = require('readline');
const fs = require('fs');
const path = require('path');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const writeFile = function(dest, data) {
return new Promise((resolve, reject) => {
fs.writeFile(dest, data, 'utf-8', function(err) {
if (err) {
reject(err);
}
resolve();
});
});
};
const getUsername = () => {
const promise = new Promise((resolve, reject) => {
try {
rl.question(
'What is your username (typically firstname.lastname)? ',
result => {
if (!result) {
console.error('You must provide your username.');
return getUsername();
}
resolve(result);
}
);
} catch (err) {
reject(err);
}
});
return promise
.catch(err => {
console.error('[getUsername] ', err);
})
.finally(() => {
rl.close();
});
};
(async () => {
const userName = await getUsername();
const fileData = `registry=http://my.remote.repo/url/
email=${userName}@email.com`;
await writeFile(path.resolve(__dirname, '../.npmrc'), fileData).catch(err => {
console.err('[writeFile Error]', err);
});
console.log('[END writeNpmRcFile]');
process.exit(0);
})();
这部分似乎运行良好,除了后续命令 (npm i) 没有使用新的 .npmrc 文件和安装炸弹。我可以(失败后)运行npm i 就好了,所以文件内容本身似乎是正确的。事实上,如果我手动放置一个.npmrc 文件并运行所有内容,除了writeNpmRcFile.js,它运行得很好。只有当我链接此命令时它们才会失败。
我知道我错过了什么,我只是不知道是什么?我等待fs.writeFile 成功完成(可能只使用writeFileSync...)。这就像文件系统没有及时释放.npmrc 文件以执行下一个命令。我什至设置了一个自定义 async wait() 方法,在某个时刻,该方法在退出进程之前暂停了一秒钟,但它没有帮助。有什么想法吗?
【问题讨论】:
-
AFAIK,(在简要浏览了source code 之后)npm 已经确定了配置应该是什么,然后在你的 npm 脚本中定义的命令被评估和执行。本质上,就 npm 而言,通过 npm 脚本生成的
.npmrc文件根本不存在 - 它在运行脚本命令之前已经推断出配置设置。 -
现在说得通了。我想知道(而不是在脚本行中链接我的命令)我是否可以使用
child_process来运行每个附加命令?或者,至少是npm i,因为这是唯一依赖.npmrc的。作为一个子进程,它不会是一个单独的实例吗? (我想我只需要测试一下......)
标签: javascript node.js npm npm-scripts