mcpField
A
arkenv

arkenv

github.com/yamcodes开发15163 次安装5 天前更新
代码仓库

关于 arkenv

ArkEnv 是面向 JavaScript 和 TypeScript 的环境变量验证库,适用于前后端框架。它整合多种模式引擎、框架专属隔离机制,以及用于初始化和检查项目的 CLI。

主要功能

  1. 01类型安全的环境变量模式
  2. 02支持 ArkType 与 Standard Schema
  3. 03自动转换与默认值
  4. 04支持 Vite、Bun、Next.js 和 Nuxt
  5. 05CLI 初始化与验证

适用场景

  1. 01在应用启动时验证变量
  2. 02防止客户端代码访问服务端密钥
  3. 03为框架生成环境配置
  4. 04按模式检查环境文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yamcodes/arkenv --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 为空则表示无法绕过。优先使用 nextActions,而不是任何旧版 retryWith 字段。

升级处理模式:始终先在不带 --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:将结构化 JSON 诊断信息输出到 stdout。

定义架构与导入 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 arkenv from "@arkenv/vite-plugin";

export default defineConfig({
  plugins: [arkenv()],
});

如果需要在 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 arkenv from "@arkenv/bun-plugin";

await Bun.build({
  entrypoints: ["./src/index.tsx"],
  outdir: "./dist",
  plugins: [arkenv()],
});

安全边界与布局

  • 扁平布局(默认):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