如何让package.json脚本中dotenv-cli动态设置环境变量的命令生效?
问题:package.json脚本中无法运行带动态环境变量的dotenv命令
我有一条能在PowerShell 7.3.4正常运行的命令,用于执行Node.js程序并动态设置环境变量:
pnpm exec dotenv -v DATABASE_URL=$(pnpm exec ts-node ./getDatabaseUrl.ts) -- pnpm -C backend run migrate:dev:main
这条命令会先执行getDatabaseUrl.ts脚本,通过dotenv-cli将结果赋值给DATABASE_URL环境变量,再让后续的pnpm -C backend run migrate:dev:main脚本读取该变量。
但将其放入package.json的scripts中后却无法工作:
{ "scripts": { "migrate:dev:main": "pnpm exec dotenv -v DATABASE_URL=$(pnpm exec ts-node ./getDatabaseUrl.ts) -- pnpm -C backend run migrate:dev:main" } }
报错信息:Unexpected argument DATABASE_URL=$(pnpm. Expected variable in format variable=value
我尝试了几种修改写法均无效:
- 写法一(去掉开头的pnpm):
{ "scripts": { "migrate:dev:main": "dotenv -v DATABASE_URL=$(pnpm exec ts-node ./getDatabaseUrl.ts) -- pnpm -C backend run migrate:dev:main" } }
报错:-- was unexpected at this time.
- 写法二(去掉--):
{ "scripts": { "migrate:dev:main": "dotenv -v DATABASE_URL=$(pnpm exec ts-node ./getDatabaseUrl.ts) pnpm -C backend run migrate:dev:main" } }
报错:pnpm was unexpected at this time.
解决方案
方案1:指定用PowerShell执行脚本
pnpm/npm在Windows默认使用cmd执行脚本,而cmd不支持$()这种命令替换语法。可以在脚本中指定使用PowerShell运行:
{ "scripts": { "migrate:dev:main": "pnpm exec --shell=powershell dotenv -v DATABASE_URL=$(pnpm exec ts-node ./getDatabaseUrl.ts) -- pnpm -C backend run migrate:dev:main" } }
也可以在项目根目录的.pnpmrc(或.npmrc)文件中全局设置默认shell:
shell=powershell
方案2:改用cmd兼容的语法实现命令替换
如果需要兼容cmd环境,可以用for /f语法替代$():
{ "scripts": { "migrate:dev:main": "for /f \"delims=\" %%i in ('pnpm exec ts-node ./getDatabaseUrl.ts') do pnpm exec dotenv -v DATABASE_URL=%%i -- pnpm -C backend run migrate:dev:main" } }
注意:这种写法仅适用于cmd环境,在PowerShell中执行会出现问题。
方案3:将逻辑抽成单独的PowerShell脚本
创建一个单独的PowerShell脚本文件(比如migrate-dev-main.ps1):
$dbUrl = pnpm exec ts-node ./getDatabaseUrl.ts pnpm exec dotenv -v DATABASE_URL=$dbUrl -- pnpm -C backend run migrate:dev:main
然后在package.json中调用该脚本:
{ "scripts": { "migrate:dev:main": "powershell ./migrate-dev-main.ps1" } }
这种方式逻辑更清晰,也能避免不同shell的语法兼容问题。
内容的提问来源于stack exchange,提问作者valerii15298
相关产品推荐
相关产品推荐

