npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

plumjs-config

v1.0.54

Published

A powerful Node.js configuration management library with YAML support and dynamic configuration loading

Readme

plumjs-config

一个强大的 Node.js 配置管理库,支持 YAML、动态配置加载和 Nacos 集成,具有完整的 TypeScript 类型安全支持。

🚀 核心特性

  • 多源配置支持: YAML 文件、JSON 文件、环境变量、Nacos 远程配置
  • 🎯 类型安全: 自动从 YAML 配置生成 TypeScript 类型定义
  • CLI 工具: 一键生成外部项目的类型安全配置访问
  • 🔄 动态配置更新: 支持运行时配置热更新和事件通知
  • 🔗 变量插值: 配置值支持变量替换和表达式计算
  • 📁 灵活文件格式: 支持 YAML、JSON 配置文件
  • 🧪 测试友好: 易于在测试环境中模拟和替换配置
  • 📖 完整文档: 详细的 API 文档和使用示例

📦 安装

npm install plumjs-config
# 或者使用 pnpm
pnpm install plumjs-config

🎯 快速开始

基础用法

import { createConfig, getConfig } from 'plumjs-config';

// 初始化配置
await createConfig({
  configDir: './config',
  enableEnvironmentVariables: true
});

// 访问配置值
const appName = getConfig('app.name', 'default-app');
const dbHost = getConfig('database.host', 'localhost');
const dbPort = getConfig('database.port', 5432);

console.log(`启动应用 ${appName},数据库: ${dbHost}:${dbPort}`);

类型安全的配置访问

import { createConfig, getConfig, plumjsConfigTypes } from 'plumjs-config';

// 初始化配置(会自动生成类型)
await createConfig({
  configDir: './config'
});

// 使用生成的类型进行类型安全访问
const appConfig = getConfig(plumjsConfigTypes.app.name); // 自动类型推断
const dbConfig = getConfig(plumjsConfigTypes.database.host); // 完整的 IntelliSense 支持

🛠️ CLI 工具

plumjs-config 提供了强大的 CLI 工具来生成外部项目的类型定义。

生成类型定义

# 为指定配置目录生成类型定义
npx plumjs-config types --config ./config

# 或者在已安装的项目中
plumjs-config types -c ./my-config-directory

配置文件结构

创建配置文件夹,例如 ./config/

config/
├── app.yml          # 应用基本配置
├── database.yml     # 数据库配置
├── server.yml       # 服务器配置
└── cache.yml        # 缓存配置

app.yml 示例:

name: my-awesome-app
version: 1.0.0
environment: development
debug: true

database.yml 示例:

host: localhost
port: 5432
username: ${DB_USER:admin}
password: ${DB_PASSWORD:secret}
database: myapp
pool:
  min: 2
  max: 10

📚 API 参考

核心函数

createConfig(options)

初始化配置管理器。

interface ConfigOptions {
  configDir: string;              // 配置文件目录
  enableEnvironmentVariables?: boolean;  // 是否启用环境变量
  nacosConfig?: NacosConfig;      // Nacos 配置(可选)
}

await createConfig({
  configDir: './config',
  enableEnvironmentVariables: true
});

getConfig(path, defaultValue?)

获取配置值,支持点分隔路径。

// 基础用法
const value = getConfig('database.host');
const valueWithDefault = getConfig('database.port', 3306);

// 类型安全用法
const typedValue = getConfig(plumjsConfigTypes.app.name);

getAllConfig()

获取完整的配置对象。

const allConfig = getAllConfig();
console.log(allConfig);

reloadConfig()

重新加载配置。

await reloadConfig();

类型安全访问

使用 plumjsConfigTypes 对象进行类型安全的配置访问:

import { plumjsConfigTypes, getConfig } from 'plumjs-config';

// 自动补全和类型检查
const appName = getConfig(plumjsConfigTypes.app.name);
const dbHost = getConfig(plumjsConfigTypes.database.host);
const serverPort = getConfig(plumjsConfigTypes.server.port);

🔧 高级用法

环境变量插值

配置文件支持环境变量插值:

# database.yml
host: ${DB_HOST:localhost}
port: ${DB_PORT:5432}
username: ${DB_USER:admin}
password: ${DB_PASSWORD}

Nacos 集成

await createConfig({
  configDir: './config',
  nacosConfig: {
    serverAddr: 'localhost:8848',
    namespace: 'development',
    shareConfigs: [
      {
        dataId: 'app-config',
        group: 'DEFAULT_GROUP',
        refresh: true
      }
    ]
  }
});

配置变更监听

import { onConfigChange } from 'plumjs-config';

onConfigChange(() => {
  console.log('配置已更新!');
  // 重新获取配置或执行其他操作
});

📦 包发布与类型安全

🔄 自动类型重置

为了确保发布的包具有最大的兼容性,我们实现了自动类型重置机制:

⚡ 自动重置流程

  1. 发布前自动重置

    npm run prepublishOnly  # 自动执行 reset-types
    ./scripts/publish-package.sh config patch  # 发布脚本也会重置类型
  2. 手动重置

    npm run reset-types  # 重置为通用 any 类型

🎯 解决的问题

  • 问题:如果包含项目特定的生成类型,其他用户安装后会遇到类型错误
  • 解决:发布前自动重置为通用 any 类型,确保兼容性

📋 类型管理工作流

# 开发阶段 - 生成具体类型
npm run generate-types /path/to/your/config

# 发布阶段 - 自动重置为通用类型
npm run prepublishOnly  # 或者
./scripts/publish-package.sh config patch

# 发布后的包 - 包含通用 any 类型,用户可以:
# 1. 直接使用(any 类型)
# 2. 生成自己的具体类型

🔧 技术实现

  • 重置脚本scripts/reset-types.js
  • 构建集成prepublishOnly 钩子
  • 发布集成publish-package.sh 脚本
  • 默认类型:所有配置返回 any 类型

这确保了:

  • 📦 发布的包具有最大兼容性
  • 🔧 用户可以选择是否生成具体类型
  • 🚀 零配置即可使用

1. 配置文件组织

config/
├── app.yml          # 应用配置
├── database.yml     # 数据库配置
├── server.yml       # 服务器配置
├── cache.yml        # 缓存配置
├── logging.yml      # 日志配置
└── security.yml     # 安全配置

2. 环境特定配置

# app.yml
name: my-app
environment: ${NODE_ENV:development}
debug: ${DEBUG:false}

3. 类型安全的配置访问

// 推荐:使用生成的类型
const config = getConfig(plumjsConfigTypes.database.host);

// 避免:硬编码字符串
const config = getConfig('database.host');

🧪 测试

import { createConfig, getConfig } from 'plumjs-config';

describe('配置测试', () => {
  beforeEach(async () => {
    await createConfig({
      configDir: './test-config'
    });
  });

  it('应该加载配置', () => {
    const appName = getConfig('app.name');
    expect(appName).toBe('test-app');
  });
});

📋 配置选项

| 选项 | 类型 | 默认值 | 描述 | |------|------|--------|------| | configDir | string | - | 配置文件目录路径 | | enableEnvironmentVariables | boolean | false | 是否启用环境变量加载 | | nacosConfig | NacosConfig | - | Nacos 配置选项 |

🤝 贡献

欢迎贡献代码!请查看 贡献指南 了解更多信息。

开发设置

# 克隆仓库
git clone https://github.com/yourusername/plumjs.git
cd plumjs

# 安装依赖
pnpm install

# 构建项目
pnpm build --filter plumjs-config

# 运行测试
pnpm test --filter plumjs-config

发布流程

项目包含自动化发布脚本,详见 发布指南

# 1. 配置 NPM Token
echo "NPM_TOKEN=your_token_here" > .env

# 2. 发布新版本
npm run publish:patch  # 补丁版本
npm run publish:minor  # 次要版本  
npm run publish:major  # 主要版本

📄 许可证

MIT License - 查看 LICENSE 文件了解详情。

🔗 相关链接


PlumJS Config - 让配置管理变得简单而安全 🚀 pnpm install


For Nacos support, also install:

```bash
npm install nacos

Quick Start

Basic Usage

import { createConfig } from 'plumjs-config';

// Initialize configuration
const config = await createConfig({
  configDir: './config',
  enableEnvironmentVariables: true
});

// Access configuration values
const appName = config.getBootstrapConfig<string>('app.name', 'default-app');
const dbHost = config.getBootstrapConfig<string>('database.host', 'localhost');
const dbPort = config.getBootstrapConfig<number>('database.port', 5432);

console.log(`Starting ${appName} on ${dbHost}:${dbPort}`);

Type-Safe Configuration

The package automatically generates TypeScript types from your YAML configuration files:

import { createConfig, TypedConfigManager } from 'plumjs-config';

// Create configuration manager
const configManager = await createConfig({
  configDir: './config'
});

// Create type-safe wrapper
const typedConfig = new TypedConfigManager(configManager);

// Get strongly-typed configuration
const appConfig = typedConfig.getAppConfig(); // Full IntelliSense support
if (appConfig) {
  console.log(`App: ${appConfig.name} v${appConfig.version}`);
  console.log(`Environment: ${appConfig.environment}`); // 'development' | 'staging' | 'production' | 'test'
  console.log(`Debug mode: ${appConfig.debug}`);
}

// Get database configuration with full type safety
const dbConfig = typedConfig.getDatabaseConfig();
if (dbConfig) {
  console.log(`DB: ${dbConfig.host}:${dbConfig.port}/${dbConfig.database}`);
  console.log(`Pool: ${dbConfig.pool.min}-${dbConfig.pool.max} connections`);
}

// Generic type-safe access
const timeout = typedConfig.getBootstrapConfig<number>('server.timeout', 5000);
const features = typedConfig.getBootstrapConfig<{enableAuth: boolean}>('features');

Generating Types

Types are automatically generated when you build the package. You can also generate them manually:

npm run generate-types

This scans your YAML configuration files and creates TypeScript interfaces in src/generated-types.ts.

CLI Type Generation (External Projects)

For external projects using plumjs-config, you can generate type-safe configuration access:

# Install plumjs-config in your project
npm install plumjs-config

# Create your configuration files
mkdir config
echo "
app:
  name: 'my-app'
  version: '1.0.0'
  environment: 'production'
database:
  host: 'localhost'
  port: 5432
" > config/app.yml

# Generate types for your configuration
npx plumjs-config types

# Now use type-safe configuration in your code
import { initConfig, getConfig } from 'plumjs-config';

await initConfig('./config');

// Type-safe configuration access with full IntelliSense
const appConfig = getConfig('app');        // Type: AppConfig | undefined
const dbConfig = getConfig('database');    // Type: DatabaseConfig | undefined

if (appConfig) {
  console.log(`${appConfig.name} v${appConfig.version}`);
  console.log(`Environment: ${appConfig.environment}`); // 'development' | 'staging' | 'production'
}

The CLI tool automatically:

  • 📁 Scans your configuration directory
  • 🔍 Analyzes YAML structure and infers types
  • 📝 Generates TypeScript interfaces
  • 🔧 Updates the package's type definitions in node_modules
  • ⚡ Provides instant type safety and IntelliSense

See CLI Usage Guide for detailed instructions.

Configuration Files

Create YAML configuration files in your config directory:

config/app.yml

app:
  name: "my-application"
  version: "1.0.0"
  environment: "development"

database:
  host: "localhost"
  port: 5432
  database: "myapp"

server:
  host: "${database.host}"
  port: 3000
  url: "http://${server.host}:${server.port}"

Environment Variables

Environment variables are automatically loaded and converted from snake_case to dot notation:

export APP_NAME="production-app"
export DATABASE_HOST="prod-db.example.com"
export DATABASE_PORT="5432"

Access them using:

const appName = config.getDefaultConfig('app.name'); // "production-app"
const dbHost = config.getDefaultConfig('database.host'); // "prod-db.example.com"

API Reference

ConfigManager

The main class for configuration management.

Methods

createConfig(options?: ConfigLoaderOptions): Promise<ConfigManager>

Create and initialize a new configuration manager.

const config = await createConfig({
  configDir: './config',
  enableEnvironmentVariables: true,
  enableNacos: false,
  filePatterns: ['**/*.yml', '**/*.yaml']
});
getBootstrapConfig<T>(path: string, defaultValue?: T): T

Get configuration from the bootstrap namespace (loaded from files).

getDefaultConfig<T>(path: string, defaultValue?: T): T

Get configuration from the default namespace (environment variables).

getCommonConfig<T>(path: string, defaultValue?: T): T

Get configuration from the common namespace.

getDynamicConfig<T>(path: string, defaultValue?: T): T

Get configuration from the dynamic namespace (runtime updates).

setConfig(namespace: ConfigNamespace, data: ConfigData, source?: ConfigSource): void

Set configuration for a specific namespace.

onConfigChange(listener: ConfigChangeListener): void

Listen for configuration changes.

config.onConfigChange((event) => {
  console.log(`Configuration changed in ${event.namespace}`);
  console.log('New value:', event.newValue);
});

Configuration Namespaces

  • BOOTSTRAP: Configuration loaded from files at startup
  • DEFAULT: Configuration from environment variables
  • COMMON: Shared configuration (often from Nacos)
  • DYNAMIC: Runtime configuration updates

Variable Interpolation

Variables can be referenced using ${path.to.variable} syntax:

database:
  host: "localhost"
  port: 5432

server:
  host: "${database.host}"
  url: "http://${server.host}:3000"

Advanced Usage

Type-Safe Configuration

Define interfaces for your configuration:

interface AppConfig {
  name: string;
  version: string;
  environment: 'development' | 'staging' | 'production';
}

interface DatabaseConfig {
  host: string;
  port: number;
  database: string;
  ssl: boolean;
}

const appConfig = config.getBootstrapConfig<AppConfig>('app');
const dbConfig = config.getBootstrapConfig<DatabaseConfig>('database');

Nacos Integration

const config = new ConfigManager({
  enableNacos: true,
  nacosConfig: {
    serverAddr: 'localhost:8848',
    namespace: 'public',
    username: 'nacos',
    password: 'nacos',
    shareConfig: [
      {
        dataId: 'app-config.yaml',
        group: 'DEFAULT_GROUP',
        nameSpace: ConfigNamespace.COMMON,
        refresh: true // Enable automatic refresh
      }
    ]
  }
});

await config.initialize();

Configuration Validation

const requiredFields = [
  'app.name',
  'app.version',
  'database.host',
  'database.port'
];

const missingFields = requiredFields.filter(field => 
  config.getBootstrapConfig(field) === undefined
);

if (missingFields.length > 0) {
  throw new Error(`Missing required configuration: ${missingFields.join(', ')}`);
}

Configuration Precedence

Configuration values are resolved in the following order (highest to lowest priority):

  1. Dynamic Configuration (runtime updates)
  2. Bootstrap Configuration (files)
  3. Environment Variables (default namespace)
  4. Default Values (provided in code)

Examples

See the examples directory for complete usage examples:

Testing

Run the test suite:

npm test

Run tests with coverage:

npm run test:coverage

Configuration Options

ConfigLoaderOptions

interface ConfigLoaderOptions {
  configDir?: string;              // Directory containing config files
  enableNacos?: boolean;          // Enable Nacos integration
  nacosConfig?: NacosConfig;      // Nacos configuration
  enableEnvironmentVariables?: boolean; // Load environment variables
  filePatterns?: string[];        // File patterns to match
}

NacosConfig

interface NacosConfig {
  serverAddr: string;             // Nacos server address
  namespace?: string;             // Nacos namespace
  username?: string;              // Authentication username
  password?: string;              // Authentication password
  shareConfig?: Array<{
    dataId: string;               // Configuration data ID
    group: string;                // Configuration group
    nameSpace: ConfigNamespace;   // Target namespace
    refresh?: boolean;            // Enable auto-refresh
  }>;
}

Best Practices

  1. Use Type-Safe Configuration: Define interfaces for your configuration structures
  2. Validate Required Fields: Check for required configuration at startup
  3. Use Environment-Specific Files: Organize configuration by environment
  4. Monitor Configuration Changes: Use event listeners for configuration updates
  5. Secure Sensitive Data: Use environment variables for secrets and passwords
  6. Use Variable Interpolation: Reduce duplication with variable references
  7. Test Configuration Loading: Include configuration in your test suite

Error Handling

The library provides detailed error messages for common issues:

  • Missing configuration files
  • Invalid YAML syntax
  • Circular variable references
  • Nacos connection failures
try {
  const config = await createConfig({ configDir: './config' });
  await config.initialize();
} catch (error) {
  console.error('Configuration error:', error.message);
  process.exit(1);
}

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Support