Monorepo
+ Nextjs
管理 .env
和 port
July 30, 2024 by
使用 @dotenvx/dotenvx
管理 .env
和 port
项目结构
- apps
- libs
- packages
- package.json
- .env
简单描述
通过根路径的 .env
文件控制全局的环境
通过各自目录下的 .env
文件控制局部的环境
在我的项目中, 所有项目的端口号都在根路径的 .env
中管理
在 apps
中有使用构建工具的项目, 比如 vite
, rsbuild
等, 可以在配置文件中通过自带的 loadEnv
或类似方法导入 (因为基本都内置了 dotenv
), 然后配置端口号
但在 next
里, next.config.js
里不支持 port
的配置, 只能通过命令行传参的方式, 比如 next dev -p 8200
所以, 只能在命令行中加载 .env
到环境变量中, 再启动 next
服务, 这里我选择了官方推荐的 dotenvx
作为工具
主要代码
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
vite.config.ts
// 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
是不正常的, 让我感到困惑的, 报错如下:
Terminal
[dotenvx@0.37.1] injecting env (4) from ../../.env
error: option '-p, --port <port>' argument missing
第一行是 dotenvx
的, 第二行是 next
的, 可能是安全防护, 不能加载父级目录吧, 还不清楚如何修改, 提了 issue