envcel
v2.0.0
Published
在 Vercel 与本地 .env* 文件之间双向同步环境变量的 CLI
Readme
envcel
在 Vercel 与本地 .env* 文件之间双向同步环境变量的 CLI,支持多环境、变更预览与类型声明生成。
快速开始
# 将 envcel 接入项目,生成配置模板
npx envcel setup编辑 envcel.config.ts,声明需要同步的变量,然后:
# 按配置初始化本地 .env* 文件
npx envcel init之后使用 pull / push 与 Vercel 保持同步。
用法
envcel setup
将 envcel 接入项目,生成配置模板。
--yes:跳过所有确认--framework <框架>:项目框架,跳过框架选择--types-file <路径>:类型声明文件路径,跳过路径输入
envcel init
按配置初始化本地 .env* 文件。
--yes:跳过所有确认--domain <域名>:生产环境域名,跳过域名选择
envcel gen
重新生成类型声明与本地 .env* 文件的注释。
--check:只校验类型声明是否最新,不写入
envcel pull
从 Vercel 拉取所选环境的变量,重建本地 .env* 文件。
--yes:跳过所有确认,环境视为全选--target <环境>:限定环境(可重复或逗号分隔),跳过环境选择
envcel push
将本地变量推送到 Vercel 的所选环境。
--yes:跳过所有确认,环境视为全选--target <环境>:限定环境(可重复或逗号分隔),跳过环境选择--redeploy [分支]:推送后重新部署的分支(可重复或逗号分隔,--no-redeploy则不部署),跳过部署询问
环境与文件
Vercel 的环境变量按环境(Development / Preview / Production)取值。envcel 将它们映射到四个本地文件:
| 本地文件 | 对应环境 |
|---|---|
| .env | 三个环境取值相同的变量 |
| .env.development | Development |
| .env.preview | Preview |
| .env.production | Production |
这些文件由 envcel 生成维护,不提交至 git。
配置
envcel.config.ts 声明所有需要同步的变量,未声明的变量不参与同步。
import { defineConfig } from 'envcel'
import { randomBytes } from 'node:crypto'
export default defineConfig({
// 框架标识,决定公开变量前缀与客户端读取方式(见下表)
framework: 'vite',
// 类型声明输出路径
// typesFile: 'src/types/env.d.ts',
// 非内置框架直接指定前缀与读取方式
// publicPrefix: 'MY_PUBLIC_',
// clientAccess: 'process-env' | 'import-meta'
vars: {
// comment 写入文件注释、Vercel 控制台与类型声明的 JSDoc;
// initial 为初始值,仅 init 时写入一次,此后值由 Vercel 接管
VITE_APP_NAME: { comment: '应用名称', initial: 'My App' },
// values 限定合法取值,生成字面量联合类型;initial 可按环境分别指定
VITE_ENV: {
comment: '环境标识',
values: ['development', 'preview', 'production'],
initial: { development: 'development', preview: 'preview', production: 'production' },
},
// 省略 initial 的变量,值完全由 Vercel 管理
DATABASE_URL: { comment: '数据库连接串' },
// initial 可传函数,init 时求值;只给部分环境时,其余环境留空,
// 配合 optional 表示允许为空(类型声明带 ?)
JWT_SECRET: {
comment: 'JWT 签名密钥',
initial: { production: () => randomBytes(32).toString('base64url') },
optional: true,
},
},
})初始值还可以取自部署地址(deployUrl)或团队的共享环境变量(shared),见下文。
framework
| 值 | 公开前缀 | 客户端读取 |
|---|---|---|
| vite | VITE_ | import.meta.env |
| nextjs | NEXT_PUBLIC_ | process.env |
| nuxtjs | NUXT_PUBLIC_ | process.env |
| astro | PUBLIC_ | import.meta.env |
| sveltekit | PUBLIC_ | import.meta.env |
| remix | 无 | process.env |
| vue | VUE_APP_ | process.env |
| create-react-app | REACT_APP_ | process.env |
| 未设置 | 无 | process.env |
公开前缀的变量以明文存储,其余加密存储。
deployUrl
生成部署地址,init 时按所在环境解析为真实值。
deployUrl.domain()
deployUrl.branch(branch: string)domain():从项目绑定的域名中选取,--domain直接指定branch(branch):按{项目}-git-{分支}-{团队}.vercel.app拼出地址
import { defineConfig, deployUrl } from 'envcel'
export default defineConfig({
vars: {
VITE_APP_URL: {
comment: '应用地址',
initial: {
development: 'http://localhost:5173',
preview: deployUrl.branch('dev'),
production: deployUrl.domain(),
},
},
},
})shared
init 时从团队的共享环境变量(Shared Environment Variables)取初始值,取不到值时留空。
shared(options?: { name?: string; target?: 'development' | 'preview' | 'production' })name:共享变量名,默认与变量同名target:只取该环境的值;省略时逐环境取值
import { defineConfig, shared } from 'envcel'
export default defineConfig({
vars: {
// 取团队里同名共享变量的值
WEBHOOK_SECRET: { comment: '回调签名密钥', initial: shared() },
// 按指定名字查找,取生产环境的值给三个环境共用
ACCESS_TOKEN: { comment: '访问令牌', initial: shared({ name: 'TEAM_ACCESS_TOKEN', target: 'production' }) },
// 按环境分别指定时,shared() 取所在环境的值
PAYMENT_SECRET: { comment: '支付签名密钥', initial: { production: shared() } },
},
})注意事项
- 避免使用 Vercel 的敏感(sensitive)变量。敏感变量的值写入后无法读回,双向同步无法工作。机密凭证应排除在配置之外,直接在 Vercel 控制台管理。
- 删除变量需在 Vercel 控制台操作。从配置中移除仅表示不再同步,不会删除线上记录。
- 类型声明文件不参与格式化。setup 检测到 prettier 时会将其加入
.prettierignore;之后才引入 prettier 的项目重跑envcel setup即可补上。
