如何从npm脚本(NodeJS + TypeScript)获取对象参数

问题描述 投票:0回答:5

我想通过 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}
node.js typescript npm command-line-interface
5个回答
1
投票

之所以有逗号

,
是因为Nodejs会在空格处分割命令行参数。
process.argv
数组将如下所示:

[
  '/home/lindu/workspace/project/node_modules/.bin/ts-node',
  '/home/lindu/workspace/project/index.ts',
  '{PAID_USER:',
  'true,',
  'VIP:',
  'true}'
]

process.argv
属性返回一个数组,其中包含启动 Node.js 进程时传递的命令行参数。

选项 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 包。


0
投票

我们可以使用双引号来包裹对象。

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

应该可以。


0
投票

您可能已经注意到,您传递的不是一个真实的对象作为参数,而是一个不是有效 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);

0
投票

我无法得到任何这些答案,最终使用以下方法得到了解决方案:

剧本:

"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)

0
投票

问题是 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]))
© www.soinside.com 2019 - 2024. All rights reserved.