项目结构
- apps
- next-web
- package.json
- .env
- react-a
- .package.json
- .env
- vite.config.ts
- react-b
- package.json
- .env
- rsbuild.config.ts
- next-web
- package.json
- .env
简单描述
通过根路径的 .env 文件控制全局的环境
通过各自目录下的 .env 文件控制局部的环境
在我的项目中, 所有项目的端口号都在根路径的 .env 中管理
在 apps 中有使用构建工具的项目, 比如 vite, rsbuild 等, 可以在配置文件中通过自带的 loadEnv 或类似方法导入 (因为基本都内置了 dotenv), 然后配置端口号
但在 next 里, next.config.js 里不支持 port 的配置, 只能通过命令行传参的方式, 比如 next dev -p 8200
所以, 只能在命令行中加载 .env 到环境变量中, 再启动 next 服务, 这里我选择了官方推荐的 dotenvx 作为工具, 参考 github.com/dotenvx/dot…
主要代码
// apps/next-web/package.json
{
"scripts": {
"dev": "next dev -p $BF_PORT_NEXT_DEV",
"dev:bad": "dotenvx run -f ../../.env -- next dev -p $BF_PORT_NEXT_DEV"
}
}
// package.json (root)
{
"scripts": {
"dev:next": "dotenvx run --quiet -- pnpm -F \"./apps/next-web\" dev",
"dev:next:bad": "pnpm -F \"./apps/next-web\" dev:bad",
"dev:a": "pnpm -F \"./apps/react-a\" dev",
"dev:b": "pnpm -F \"./apps/react-b\" dev"
}
}
# .env (root)
BF_PORT_NEXT_DEV=8200
// apps/react-a/vite.config.ts
export default defineConfig(({ mode }) => {
const env: Record<string, string> = {
...loadEnv(mode, '.'),
...loadEnv(mode, '../..', 'BF'),
}
// ...
}
// apps/react-b/rsbuild.config.ts
export default defineConfig(({ env, envMode, command }) => {
logger.info('env:', env)
logger.info('envMode:', envMode)
logger.info('command:', command)
logger.log()
const { parsed: innerAppEnvs } = loadEnv({ mode: envMode, prefixes: ['BF_'] })
const { parsed: rootEnvs } = loadEnv({
mode: envMode,
prefixes: ['BF_'],
cwd: path.resolve(process.cwd(), '../../'),
})
const envs = {
...rootEnvs,
...innerAppEnvs,
}
// ...
}
问题解释
里面 next 有两个开发命令 dev:next 和 dev:next:bad
dev:next 是正常的, 多次尝试后的结果
dev:next:bad 是不正常的, 让我感到困惑的, 报错如下:
[dotenvx@0.37.1] injecting env (4) from ../../.env
error: option '-p, --port <port>' argument missing
第一行是 dotenvx 的, 第二行是 next 的, 可能是安全防护, 不能加载父级目录吧, 还不清楚如何修改, 提了 issue
本期结束