我想通过 NPM 脚本传递一个对象,例如
"update-user-roles": "ts-node user-roles.ts {PAID_USER: true, VIP: true}"
我的函数拾取对象,但不断添加额外的逗号,因此它无法正确更新用户。我如何按原样收到对象?
async function updateUserRoles(roles: any) {
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: {
roles
},
}
})
console.log(`User roles successfully added: ${roles}`)
}
const rolesString = JSON.stringify(process.argv.slice(2))
updateUserRoles(JSON.parse(rolesString))
我收到以下消息:
User roles successfully added: {PAID_USER:,true,,VIP:,true}
之所以有逗号
,
是因为Nodejs会在空格处分割命令行参数。 process.argv
数组将如下所示:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{PAID_USER:',
'true,',
'VIP:',
'true}'
]
属性返回一个数组,其中包含启动 Node.js 进程时传递的命令行参数。process.argv
选项 1. 传递 JSON 字符串
$ npx ts-node ./index.ts '{"PAID_USER": true, "VIP": true}'
index.ts
console.log(process.argv);
console.log(JSON.parse(process.argv.slice(2)[0]));
输出:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{"PAID_USER": true, "VIP": true}'
]
{ PAID_USER: true, VIP: true }
选项2.传递一个字符串并将其解析为JSON字符串。
npx ts-node ./index.ts '{PAID_USER: true, VIP: true}'
index.ts
:
console.log(process.argv);
const arg = process.argv.slice(2)[0];
const obj = JSON.parse(JSON.stringify(eval('(' + arg + ')')));
console.log(obj, typeof obj, obj.PAID_USER, obj.VIP);
输出:
[
'/home/lindu/workspace/project/node_modules/.bin/ts-node',
'/home/lindu/workspace/project/index.ts',
'{PAID_USER: true, VIP: true}'
]
{ PAID_USER: true, VIP: true } object true true
选项 3.使用 minimistjs 包。
我们可以使用双引号来包裹对象。
"update-user-roles": "ts-node user-roles.ts \"{\\\"PAID_USER\\\": true, \\\"VIP\\\": true}\""
之后:
async function updateUserRoles(rolesString: string) {
const roles = JSON.parse(rolesString);
const userID = await getAuth().then((res) => res.uid);
updateUser({
userID: userID,
fields: {
roles: roles
}
});
console.log(`User roles successfully added: ${JSON.stringify(roles)}`);
}
应该可以。
您可能已经注意到,您传递的不是一个真实的对象作为参数,而是一个不是有效 json 的字符串。
首先,参数必须被换行并转义(\"{...}\"),这样它就不会被空格分开。
这里有两个辅助函数。一种是使用键 (myObject) 读出参数。第二个是用字符串创建一个对象(假 json)。
"update-user-roles": "ts-node user-roles.ts myObject=\"{PAID_USER: true, VIP: true}\""
这是最小的 JavaScript 功能。
const args = process.argv.slice(2).reduce((acc, arg) => {
let [k, v = true] = arg.split('=');
acc[k] = v;
return acc;
}, {});
console.log(args) // { myObject: '{PAID_USER: true, VIP: true}' }
const parseJSON = obj => Function('"use strict";return (' + obj + ')')();
const myObject = parseJSON(args.myObject); // { PAID_USER: true, VIP: true }
你的函数调用将是
updateUserRoles(myObject);
我无法得到任何这些答案,最终使用以下方法得到了解决方案:
剧本:
"ts-node user-roles.ts '{\"PAID_USER\": true, \"VIP\": true}'"
使用 JSON.parse 将对象字符串解析回对象并传递给函数:
const objArgStr = process.argv[2];
if (!objArgStr) {
console.error('No argument provided.');
process.exit(1);
}
const objArg = JSON.parse(objArgStr);
console.log('Object argument: ', objArg);
updateUserRoles(objArg)
问题是 Node.js 将参数视为字符串并用空格分隔它们,因此
roles
变量看起来像这样:
[
"{PAID_USER:",
"true,",
"VIP:",
"true}"
]
此外,它不是 JSON 字符串。您必须将其转换为 JSON 并用引号括起来,以便 Node.js 会将整个内容计为一个参数:
ts-node user-roles.ts "{\"PAID_USER\": true, \"VIP\": true}"
注意:不要忘记用反斜杠转义字符串中的引号
在
user-roles.ts
:
const rolesString = process.argv.slice(2)[0]
updateUserRoles(JSON.parse(rolesString))
因为
process.argv.slice(2)
返回 Array
,所以您需要获取第一个参数。您也不需要使用 JSON.stringify()
。
所有内容都在一行中(如果你愿意的话):
updateUserRoles(JSON.parse(process.argv.slice[2]))