mcpField
A
arkenv

arkenv

github.com/onmax开发723197 次安装今天更新
代码仓库

关于 arkenv

ArkEnv 是面向 JavaScript 和 TypeScript 项目的类型安全环境变量校验库,支持多种校验引擎及框架集成。配套 CLI 可初始化配置并检查环境变量。

主要功能

  1. 01ArkType 与 Standard Schema 校验
  2. 02自动类型转换与默认值
  3. 03集成 Vite、Bun、Next.js、Nuxt
  4. 04CLI 初始化与配置检测
  5. 05客户端与服务端密钥隔离

适用场景

  1. 01校验应用启动所需的环境变量
  2. 02在前端构建中内联公开变量
  3. 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/core ArkType 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 接口。

最佳实践与规则

  1. 始终使用 import { env } from "./env":在 v1 中,应用环境变量绝不要直接使用 import.meta.env 或 process.env。
  2. 绝不要创建全局 .d.ts 扩展:ImportMetaEnvAugmented 和 ProcessEnvAugmented 是已在 v1 中弃用的 v0 旧模式。
  3. 将机密保留在服务端:绝不要给服务端机密(DATABASE_URL、API_SECRET_KEY)添加客户端前缀(VITE_、NEXT_PUBLIC_、BUN_PUBLIC_、NUXT_PUBLIC_)。

评论

支持 Markdown