我正在开发无服务器NodeJS应用,需要在离线模式下对其进行测试。我在npm
文件中有一个package.json
脚本,如下所示:
"scripts": {
"serve": "cross-env AUTHORIZER='{\\\"claims\\\":{\\\"permissions\\\":\\\"[view:accounts manage:accounts]\\\",\\\"sub\\\":\\\"auth0|5cfe0adce3c4c50ea072ea9f\\\"}}' AWS_PROFILE=elit_nonprd serverless offline start -s dev --noAuth",
...
请注意,有两个权限需要用空格分隔。在Windows上运行npm run serve
会出现以下错误:
> @mypackage@1.0.0 serve C:\path
> cross-env AUTHORIZER='{\"claims\":{\"permissions\":\"[view:accounts manage:accounts]\",\"sub\":\"auth0|5cfe0adce3c4c50ea072ea9f\"}}' AWS_PROFILE=elit_nonprd serverless offline start -s dev --noAuth
The filename, directory name, or volume label syntax is incorrect.
events.js:288
throw er; // Unhandled 'error' event
^
Error: spawn manage:accounts]","sub":"auth0|5cfe0adce3c4c50ea072ea9f"}} ENOENT
at notFoundError (C:\path\node_modules\cross-spawn\lib\enoent.js:6:26)
at verifyENOENT (C:\path\node_modules\cross-spawn\lib\enoent.js:40:16)
at ChildProcess.cp.emit (C:\path\node_modules\cross-spawn\lib\enoent.js:27:25)
at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
Emitted 'error' event on ChildProcess instance at:
at ChildProcess.cp.emit (C:\path\node_modules\cross-spawn\lib\enoent.js:30:37)
at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12) {
code: 'ENOENT',
errno: 'ENOENT',
syscall: 'spawn manage:accounts]","sub":"auth0|5cfe0adce3c4c50ea072ea9f"}}',
path: 'manage:accounts]","sub":"auth0|5cfe0adce3c4c50ea072ea9f"}}',
spawnargs: [
'AWS_PROFILE=elit_nonprd',
'serverless',
'offline',
'start',
'-s',
'dev',
'--noAuth'
]
}
即使未显示堆栈跟踪,如果我将cross-env
替换为cross-env-shell
,也会发生这种情况。
当值包含空格时,是否存在一种通用的跨平台方法来设置环境变量?
更新:我希望得到的结果是将AUTHORIZER
设置为以下值(感谢@RobC要求澄清):
{
"claims":
{
"permissions": "[view:accounts manage:accounts]",
"sub": "auth0|5cfe0adce3c4c50ea072ea9f"
}
}
答案 0 :(得分:1)
实现跨平台兼容性是一个难题。在几次尝试失败之后,似乎无法在cross-env
中使用单一语法:
Windows(cmd
)在下面的worksOnWin
示例中成功运行,而* Nix(sh
)在下面的worksOnNix
示例中成功运行。
{
"scripts": {
"worksOnWin": "cross-env AUTHORIZER={\\\"claims\\\":{\\\"permissions\\\":\\\"\"[view:accounts manage:accounts]\"\\\",\\\"sub\\\":\\\"auth0|5cfe0adce3c4c50ea072ea9f\\\"}} AWS_PROFILE=elit_nonprd serverless offline start -s dev --noAuth",
"worksOnNix": "cross-env AUTHORIZER=\"{\\\"claims\\\":{\\\"permissions\\\":\\\"[view:accounts manage:accounts]\\\",\\\"sub\\\":\\\"auth0|5cfe0adce3c4c50ea072ea9f\\\"}}\" AWS_PROFILE=elit_nonprd serverless offline start -s dev --noAuth",
}
}
要满足您对单一语法跨平台的需求,我会考虑通过使用 node.js 脚本代替的方法。
将此serve.js
脚本(如下)保存在项目目录的根目录中,即,将其保存在 package.json 所在的同一级别。
serve.js
const spawn = require('child_process').spawn;
const processEnv = process.env;
processEnv.AUTHORIZER = '{"claims":{"permissions":"[view:accounts manage:accounts]","sub":"auth0|5cfe0adce3c4c50ea072ea9f"}}';
processEnv.AWS_PROFILE = 'elit_nonprd';
spawn('serverless', ['offline', 'start', '-s', 'dev', '--noAuth'], {
env: processEnv,
stdio: 'inherit',
shell: true
});
在您的 package.json 的scripts
部分中,重新定义serve
脚本,如下所示:
package.json
{
...
"scripts": {
"serve": "node serve"
}
...
}
运行以下命令:
npm run serve
以下内容说明 serve.js 中发生的事情:
首先,我们需要child_process
模块的spawn()
方法。
阅读部分;
const processEnv = process.env;
processEnv.AUTHORIZER = '{"claims":{"permissions":"[view:accounts manage:accounts]","sub":"auth0|5cfe0adce3c4c50ea072ea9f"}}';
processEnv.AWS_PROFILE = 'elit_nonprd';
使用process.env
获取现有的环境变量,并将其分配给processEnv
变量。
随后,我们使用processEnv
和AUTHORIZER
属性及其必要的值来扩充AWS_PROFILE
对象。这实际上定义了两个新的环境变量。
最后我们通过serverless offline start -s dev --noAuth
“掏空” child_process.spawn()
命令。
{ env: processEnv }
部分将child_process.spawn
的{{3}}选项设置为processEnv
对象,即,它设置子进程的环境变量。
env
选项在子进程中为stdin,stdout,stderr配置管道。这样可以确保您在控制台中获得任何日志记录。
shell
选项设置为true
。
注意:使用该解决方案,cross-env
程序包变得多余。