关于 arkenv
ArkEnv 是面向 JavaScript 和 TypeScript 项目的类型安全环境变量校验库,支持多种校验引擎及框架集成。配套 CLI 可初始化配置并检查环境变量。
主要功能
- 01ArkType 与 Standard Schema 校验
- 02自动类型转换与默认值
- 03集成 Vite、Bun、Next.js、Nuxt
- 04CLI 初始化与配置检测
- 05客户端与服务端密钥隔离
适用场景
- 01校验应用启动所需的环境变量
- 02在前端构建中内联公开变量
- 03防止客户端访问服务端密钥
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ onmax/ nuxt-skills --skill arkenv安装后在 Claude Code 中输入/arkenv确认已加载。
详细介绍
ArkEnv
ArkEnv 是一款适用于现代 JavaScript 和 TypeScript 框架的类型安全环境变量验证库。它提供了跨所有框架统一的规范入口:import { env } from "./env"。
在 v1 中,ArkEnv 提供两种一等验证引擎:
@arkenv/core:内置 ArkType DSL 引擎,可高性能地定义架构并自动进行类型转换。@arkenv/standard:Standard Schema 引擎,支持任何兼容的验证器(Zod、Valibot 等)。
功能
核心用法
- 使用
@arkenv/coreArkType DSL 字符串或@arkenv/standard配合 Zod / Valibot 定义类型安全的架构。 - 自动类型转换(
string.numeric、number.port、布尔值、JSON 对象、数组)和默认值("boolean = true")。 - 统一一致的开发体验:在前端和后端代码中直接导入
env。
框架集成
- Vite(
@arkenv/vite-plugin):插件以转换模式运行,将客户端依赖图中来自env.ts的导入重写为内联的公开VITE_*字面量,并将私有服务端键替换为会抛出错误的运行时保护。 - Bun(
@arkenv/bun-plugin):插件会在Bun.build/Bun.serve中拦截对env.ts的导入,将公开的BUN_PUBLIC_*值内联,同时保护服务端机密信息。 - Next.js(
@arkenv/nextjs):提供构建时和运行时验证,并自动使用客户端 / 服务端隔离代理。 - Nuxt(
@arkenv/nuxt):Nuxt 模块,支持 Nitro 启动验证和运行时代理保护。 - Node.js:通过
@arkenv/core或@arkenv/standard直接进行启动时验证。
CLI(设置与 DevOps)
- 使用
pnpm dlx arkenv init(或npx arkenv init)在新项目或现有项目中初始化 ArkEnv。 - 自动检测框架(
Next.js、Nuxt、Vite、Bun等)并生成env.ts。 - 初始化期间选择托管服务提供商预设(
--preset, -P <provider>)。 - 必要时自动配置
tsconfig.json。CLI 命令通过--schema或扁平约定路径(env.ts、src/env.ts)发现架构,而不是使用package.json中的"arkenv"字段,也不会使用遗留的拆分布局文件名,例如env/server.ts。
托管预设
ArkEnv 以代码为先。你可以在项目初始设置期间选择托管服务提供商预设(--preset vercel、netlify、cloudflare、railway、render、fly),也可以直接从文档(/docs/core-concepts/hosting-presets)复制提供商字段并粘贴到 ./env.ts。这里没有由机器管理的注释块或 CLI 修改命令。
Agent 设置(机器可读)
AI Agent 应始终使用 CLI 初始化项目,以确保一致性和可靠性。使用 --agent 标志即可获得完全自动化、机器可读的体验。
- 命令:
pnpm dlx arkenv init --agent - 行为:
--agent标志会自动启用以下行为:--yes:跳过所有交互式提示并使用推荐默认值。--quiet:不显示加载动画和 ANSI 格式,使命令行日志更简洁。--json:完成后向stdout输出结构化 JSON 摘要(所有其他输出均发送到stderr)。
- 成功验证:解析
stdout上的 JSON 结算封装。成功时为ok: true且commandId: "init";详细信息(例如生成的路径)位于result下。
处理拒绝(ok: false)
--agent 绝不意味着 --force。安全检查未通过时,CLI 会拒绝操作,并向 stdout 输出一个错误结算信封:
{
"ok": false,
"commandId": "init",
"error": {
"code": "CLI.GIT_TREE_DIRTY",
"severity": "error",
"summary": "Git working tree is not clean.",
"why": "Commit or stash your changes before running arkenv init.",
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
},
"diagnostics": [],
"nextActions": [
{
"kind": "run-command",
"label": "Re-run with --force to bypass git working tree check",
"command": "arkenv init --force"
}
]
}
error.code:稳定的点分隔标识符,可用于分支判断(CLI.REQUIREMENTS_NOT_MET、CLI.GIT_TREE_DIRTY、CLI.NON_EMPTY_DIR,……)。CLI.INTERNAL_ERROR表示 CLI 出了_故障_,而不是_拒绝_操作——重试并添加标志不会有帮助。nextActions:补救步骤。包含--force的run-command操作表示可以绕过此次拒绝;nextActions为空则表示无法绕过。
升级处理模式:始终先运行不带 --force 的 init --agent。如果得到 ok: false,请检查 error.code 和 nextActions。只有在你审慎决定可以安全绕过此次拒绝后,才使用 --force(或执行 run-command 操作中的命令)重新运行——不要提前添加 --force。
CLI 命令
init
在项目中设置 ArkEnv。它会检测你的框架,并配置相应的插件和架构。
pnpm dlx arkenv init [options]
选项:
--preset, -P <preset>:指定托管服务提供商预设(none、vercel、netlify、cloudflare、railway、render、fly)。--no-codegen:禁用 Next.js 代码生成配置设置。--force, -f:绕过 Git 工作树必须干净的安全检查。
check
根据架构文件验证环境。
pnpm arkenv check [options]
选项:
--schema, -s <path>:显式指定架构模块的路径(覆盖按约定发现的路径)。--verify-example [file]:验证.env.example(或自定义示例文件路径)中是否包含所有已声明的架构键,不修改文件。--env-file <path>:指定要加载的一个或多个自定义环境文件。--json:向 stdout 输出结构化 JSON 诊断信息。
定义架构并导入 env
@arkenv/core(ArkType DSL)
import arkenv from "@arkenv/core";
export const env = arkenv({
PORT: "number.port = 3000",
DATABASE_URL: "string",
VITE_API_URL: "string",
NODE_ENV: "'development' | 'production' | 'test' = 'development'",
});
@arkenv/standard(Standard Schema:Zod、Valibot)
import arkenv from "@arkenv/standard";
import * as z from "zod";
export const env = arkenv({
PORT: z.number().default(3000),
DATABASE_URL: z.string(),
VITE_API_URL: z.url(),
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
});
Valibot 使用 /valibot 子路径(还需安装 @valibot/to-json-schema):
import { arkenv } from "@arkenv/standard/valibot";
import * as v from "valibot";
export const env = arkenv({
PORT: v.optional(v.number(), 3000),
DATABASE_URL: v.pipe(v.string(), v.url()),
});
在应用代码中使用 env
始终从规范的 env 对象直接导入并读取属性:
import { env } from "./env";
export default function App() {
const apiUrl = env.VITE_API_URL; // string
return <div>API URL: {apiUrl}</div>;
}
框架设置模式
1. Vite(@arkenv/vite-plugin)
在 vite.config.ts 中注册插件,不传入架构参数:
import { defineConfig } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
export default defineConfig({
plugins: [arkenvPlugin()],
});
如果需要在 vite.config.ts 本身中使用环境变量(例如 server.port),请使用 loadEnv 对其进行验证:
import { defineConfig, loadEnv } from "vite";
import arkenvPlugin from "@arkenv/vite-plugin";
import arkenv, { type } from "@arkenv/core";
export const Env = type({
PORT: "number.port = 5173",
VITE_API_URL: "string",
});
export default defineConfig(({ mode }) => {
const env = arkenv(Env, { env: loadEnv(mode, process.cwd(), "") });
return {
plugins: [arkenvPlugin()],
server: { port: env.PORT },
};
});
2. Bun(@arkenv/bun-plugin)
在 bunfig.toml 中:
[serve.static]
plugins = ["@arkenv/bun-plugin"]
在 Bun.build 中:
import arkenvPlugin from "@arkenv/bun-plugin";
await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
plugins: [arkenvPlugin],
});
安全边界与布局
- 扁平布局(默认):
src/env.ts包含所有键。服务端依赖图会在启动时执行完整验证;客户端依赖图会接收内联的公共字面值,而访问私有服务端键会触发运行时错误。 - 可选的双模块方案:如果必须确保机密名称/类型不会出现在客户端类型依赖图中,可使用两个模块(客户端 + 服务端),并分别导入;也可选择设置
extends: [clientEnv]。Next 可在服务端模块中使用import "server-only"+@arkenv/core。Nuxt:绝不要在客户端代码中导入服务端模块。这不是 CLI--strict标志,也不是包的/client/server接口。
最佳实践与规则
- 始终使用
import { env } from "./env":在 v1 中,应用环境变量绝不要直接使用import.meta.env或process.env。 - 绝不要创建全局
.d.ts扩展:ImportMetaEnvAugmented和ProcessEnvAugmented是已在 v1 中弃用的 v0 旧模式。 - 将机密保留在服务端:绝不要给服务端机密(
DATABASE_URL、API_SECRET_KEY)添加客户端前缀(VITE_、NEXT_PUBLIC_、BUN_PUBLIC_、NUXT_PUBLIC_)。