如何在Turborepo Monorepo项目中实现.env环境变量的跨应用与包共享
Great question! When working with Turborepo, you don’t have to duplicate .env files across every app and package—centralizing your shared variables in a root .env is totally doable, and it’s the cleaner approach for most cases. Let’s break down how to set this up, plus when you might want to use per-app/package files instead.
.env (Recommended) This approach keeps all shared variables in one place, making it easy to update and maintain. Here’s how to implement it:
- Install required dependencies
Turborepo doesn’t automatically load root-level.envfiles out of the box, so you’ll needdotenv(to load env files) anddotenv-expand(to handle variable interpolation). Install them at the root of your Turborepo:
# npm npm install dotenv dotenv-expand --save-dev # pnpm pnpm add dotenv dotenv-expand -D # yarn yarn add dotenv dotenv-expand --dev
- Create your root
.envfile
Add your shared variables to a.envfile in the root of your Turborepo:
# Root .env API_BASE_URL=https://api.yourdomain.com NODE_ENV=development SHARED_AUTH_SECRET=your-secret-value
- Configure Turborepo to inject global variables
Update your rootturbo.jsonto define which variables should be available across all apps and packages using theglobalEnvfield. This tells Turborepo to pass these variables to every task (likedev,build, etc.) in your workspace:
{ "$schema": "https://turborepo.org/schema.json", "globalEnv": ["API_BASE_URL", "NODE_ENV", "SHARED_AUTH_SECRET"], "pipeline": { // Your existing pipeline configs } }
- Load variables in apps/packages (if needed)
For frontend apps (like Next.js, React), frameworks often auto-load env variables (especially if prefixed withNEXT_PUBLIC_orREACT_APP_). For Node.js packages or apps that don’t auto-load, add this code at the top of your entry file to pull in the root.env:
// CommonJS require('dotenv-expand')(require('dotenv').config({ path: '../../.env' })); // ES Modules import dotenv from 'dotenv'; import dotenvExpand from 'dotenv-expand'; const envConfig = dotenv.config({ path: '../../.env' }); dotenvExpand.expand(envConfig);
Adjust the path value based on the location of your app/package relative to the root (e.g., apps might use ../.env instead of ../../.env).
.env Files (For Isolated Variables) You only need separate .env files if you have variables that are specific to a single app/package, or if you need to override root variables for a particular workspace. Turborepo will automatically load .env files in individual app/package directories, and local variables will override root variables with the same name.
For example:
- A Next.js app in
apps/webcould have a.envfile withNEXT_PUBLIC_ANALYTICS_ID=abc123(a variable only used by that app) - A utility package in
packages/utilscould have a.envfile withUTIL_SPECIFIC_KEY=xyz789
- Prefix frontend-accessible variables: For React/Next.js apps, prefix shared variables that need to be available in the browser with
REACT_APP_orNEXT_PUBLIC_(frameworks automatically expose these to the client). - Use
.env.example: Create a.env.examplefile at the root to document all required shared variables (without sensitive values) so your team knows what to set up. - Never commit
.env: Add.envto your root.gitignoreto avoid pushing sensitive secrets to version control. - Environment-specific files: Use
.env.development,.env.production, etc., to handle environment-specific values. Turborepo will load these based on theNODE_ENVvalue, anddotenv-expandlets you reference other variables (e.g.,API_URL=${API_BASE_URL}/v1).
内容的提问来源于stack exchange,提问作者Adam

