ConfigShip:零依赖的安全配置管理器(适用于 Node.js,支持 Raw Env!)

发布: (2025年12月26日 GMT+8 13:32)
4 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我将为您翻译成简体中文。

问题

我已经厌倦了配置管理的混乱。你会遇到:

  • 到处散落的硬编码默认值
  • 难以使用的 .env 文件
  • 开发 / 预发布 / 生产 环境的不同配置
  • 会导致问题的运行时覆盖
  • 原型污染漏洞(真的,确实存在)

我的解决方案:ConfigShip

零依赖。 真的——自己检查 package.json

有何不同?

分层解析(明确优先级)

runtime → env → file → defaults

原始环境变量名(v0.1.2 新增)

config.get("APP_NAME") // Works!
config.get("name")     // Also works! (transformed)

默认安全

  • 防止原型污染
  • TypeScript 严格模式
  • 缺少配置时不会崩溃

自动解析

APP_PORT=3000        # → number 3000
APP_ENABLED=true    # → boolean true
APP_DATA={"x":1}    # → object {x:1}

快速示例

import { createConfig } from "config-ship";

const config = createConfig({
  defaults: {
    db: { host: "localhost", port: 5432 }
  },
  envPrefix: "APP_",
  envFile: ".env"
});

// Access anywhere
config.get("db.host");
config.set("db.port", 5433);

实际案例:Express 应用

// config/index.js
import { createConfig } from "config-ship";

export const config = createConfig({
  defaults: {
    server: { port: 3000, host: "localhost" },
    db: {
      host: "localhost",
      port: 5432,
      pool: { min: 2, max: 10 }
    },
    redis: { url: "redis://localhost:6379" },
    features: {
      rateLimiting: true,
      analytics: false
    }
  },
  envPrefix: "MYAPP_",
  envFile: ".env",               // optional auto‑loading of process.env
  rootFile: `config/${process.env.NODE_ENV}.js`
});
// app.js
import express from "express";
import { config } from "./config/index.js";

const app = express();

app.listen(
  config.get("server.port"),
  () => console.log(`Running on port ${config.get("server.port")}`)
);

生产环境 .env

MYAPP_SERVER__PORT=8080
MYAPP_DB__HOST=prod-db.internal
MYAPP_DB__POOL__MAX=50
MYAPP_REDIS__URL=redis://prod:6379

注意 __ 用于嵌套键!

环境变量轻松管理

语法

  • 前缀:APP_(单个 _ 分隔前缀)
  • __ 创建嵌套路径
APP_DB__HOST=localhost          # → db.host
APP_DB__PORT=5432               # → db.port (parsed to number)
APP_FEATURE__BETA=true          # → feature.beta (parsed to boolean)

用例:功能标记

const config = createConfig({
  defaults: {
    features: {
      darkMode: false,
      newUI: false,
      betaAccess: false
    }
  },
  envPrefix: "FEATURES_"
});

function featureEnabled(name) {
  return config.get(`features.${name}`, false);
}

// Usage
if (featureEnabled("darkMode")) {
  applyDarkTheme();
}

// Enable for beta users
if (user.isBetaTester) {
  config.set("features.betaAccess", true);
}

用例:NPM 包配置

import { createConfig } from "config-ship";

export function createClient(userOptions = {}) {
  const config = createConfig({
    defaults: {
      timeout: 5000,
      retries: 3,
      baseURL: "https://api.example.com"
    },
    envPrefix: "MY_PKG_"
  });

  // User options override everything
  Object.keys(userOptions).forEach(key => {
    config.set(key, userOptions[key]);
  });

  return {
    config,
    // your API
  };
}

配置来源

  • 您的默认值
  • 环境变量:MY_PKG_TIMEOUT=10000
  • 运行时:createClient({ timeout: 3000 })

安全性:原型污染保护

关键修复在 v0.1.2:

// Malicious attempts are blocked ✅
config.set("__proto__.polluted", true);
config.set("constructor.prototype.polluted", true);

console.log({}.polluted); // undefined (safe!)

已通过全面的安全测试。

v0.1.2 版本更新内容?

  • Raw env namesconfig.get("APP_NAME") 现在可以使用
  • 🔒 Security – 修复了原型污染漏洞
  • 💪 TypeScript – 启用了严格模式
  • 📚 Docs – 提供了更好的示例和使用场景
  • Tests – 37 个测试全部通过

为什么不直接使用…?

LibraryDrawbacks
dotenv仅加载环境变量;没有分层,也没有运行时覆盖
config5 个以上依赖,设置复杂,缺少原始环境变量名称
convict功能强大但体积大;验证开销
ConfigShip零依赖,简单,安全,功能齐全

安装

npm install config-ship

链接

  • 📦 NPM:
  • 🐙 GitHub:
  • 📝 Changelog:

试一试

npm install config-ship

非常期待您的反馈!您遇到了哪些配置问题?

编辑:感谢大家的反馈!已添加关于 env‑var 命名和 raw‑name 支持的说明。

要发布的子版块

  • r/node
  • r/javascript
  • r/typescript
  • r/webdev
  • r/programming (如果它获得关注)
Back to Blog

相关文章

阅读更多 »