Node.js配置管理:使用npm config和cross-env
概述
环境变量对于配置应用程序至关重要,可以避免硬编码敏感信息或环境特定的值。
在使用 Node.js 和 npm 脚本时,您有多种策略可以将环境变量传递给脚本。
在本文中,我们将探索三种关键方法:
使用 package.json 中的 config 键来存储和访问自定义设置
使用 cross-env 包以跨平台方式设置环境变量
通过 process.env 在 Node.js 应用程序内部访问这些设置
同时,我们还将了解像 Commitizen 这样的工具如何利用相同的 config 键来读取提交约定的 driver 等值。
使用 package.json 中的 npm config 存储自定义设置
npm 支持在 package.json 内部使用 config 部分,允许您声明自定义配置键和默认值。
脚本可以通过 npm_package_config_<key> 环境变量访问这些配置。
- // package.json
- {
- "name": "my-app",
- "version": "1.0.0",
- "config": {
- "apiHost": "https://api.example.com",
- "port": "3000"
- },
- "scripts": {
- "start": "node server.js",
- "report": "echo API is at $npm_package_config_apiHost on port $npm_package_config_port"
- }
- }
当您运行:
- npm run report
您将看到:
- API is at https://api.example.com on port 3000
在运行时覆盖配置
您可以在调用 npm 脚本时覆盖这些默认值:
- npm run report --apiHost=https://api.staging.local --port=4000
在底层,npm 将这些标志映射到相同的环境变量(npm_package_config_apiHost、npm_package_config_port)。
使用 cross-env 设置环境变量
Unix shell 允许您编写 NODE_ENV=production webpack,但 Windows CMD 和 PowerShell 使用不同的语法。为了统一跨平台,请使用 cross-env:
- npm install --save-dev cross-env
然后在您的脚本中:
- "scripts": {
- "build": "cross-env NODE_ENV=production webpack --config webpack.prod.js",
- "dev": "cross-env API_URL=$npm_package_config_apiHost PORT=$npm_package_config_port node server.js"
- }
现在 npm run build 和 npm run dev 在 Windows、macOS 和 Linux 上都能相同工作——无需更改语法。
示例:Commitizen 和 config 键
Commitizen 是一个用于标准化提交消息的工具。它从 package.json 中的 config.commitizen.path 值读取其适配器(driver):
- // package.json
- {
- "config": {
- "commitizen": {
- "path": "./node_modules/cz-conventional-changelog"
- }
- },
- "scripts": {
- "commit": "git-cz"
- }
- }
当您运行 npm run commit(git-cz 的别名)时,Commitizen 查找 config.commitizen.path 并使用该适配器来指导您的提交提示。
在 Node.js 应用程序内部访问 config 变量
一旦 npm 将您的 config 值作为环境变量暴露,您就可以使用 process.env 在任何 Node.js 文件中读取它们:
- // server.js
- const express = require('express');
- const app = express();
- // npm_package_config_port 来自 package.json 中的 config.port
- const PORT = process.env.npm_package_config_port || 3000;
- const API_URL = process.env.npm_package_config_apiHost || 'http://localhost:4000';
- app.get('/', (req, res) => {
- res.send(`API is at ${API_URL}`);
- });
- app.listen(PORT, () => {
- console.log(`Server listening on port ${PORT}`);
- });
如果您运行 npm run dev,npm 将为您注入 npm_package_config_port 和 npm_package_config_apiHost
如果有人直接运行 node server.js,回退值(|| 3000)确保您的应用程序仍然以合理的默认值启动
您仍然可以在运行时覆盖:npm run dev --npm_config_port=5000 将设置 process.env.npm_package_config_port === '5000'
最佳实践
集中默认值:在 package.json 的 config 下集中默认值,使脚本和代码共享相同的真实来源
使用 cross-env:对于设置真实操作系统环境变量的任何脚本,使用 cross-env 来保证跨平台兼容性
记录覆盖:向团队成员展示如何通过 --npm_config_<key> 进行调整
在工具中利用:Commitizen、linters、部署脚本等都遵循相同的 config 块
通过结合 npm 的 config 键、cross-env 和简单的 process.env 访问,您可以在 Node.js 项目中获得灵活、DRY(不重复)和跨平台的配置管理方法。
实际应用场景
1. 开发环境配置
- {
- "config": {
- "dev": {
- "port": "3000",
- "database": "mongodb://localhost:27017/dev",
- "logLevel": "debug"
- }
- },
- "scripts": {
- "dev": "cross-env NODE_ENV=development PORT=$npm_package_config_dev_port DB_URL=$npm_package_config_dev_database LOG_LEVEL=$npm_package_config_dev_logLevel nodemon server.js"
- }
- }
2. 生产环境配置
- {
- "config": {
- "prod": {
- "port": "8080",
- "database": "mongodb://prod-server:27017/prod",
- "logLevel": "error"
- }
- },
- "scripts": {
- "start": "cross-env NODE_ENV=production PORT=$npm_package_config_prod_port DB_URL=$npm_package_config_prod_database LOG_LEVEL=$npm_package_config_prod_logLevel node server.js"
- }
- }
3. 测试环境配置
- {
- "config": {
- "test": {
- "port": "3001",
- "database": "mongodb://localhost:27017/test",
- "logLevel": "warn"
- }
- },
- "scripts": {
- "test": "cross-env NODE_ENV=test PORT=$npm_package_config_test_port DB_URL=$npm_package_config_test_database LOG_LEVEL=$npm_package_config_test_logLevel jest"
- }
- }
总结
通过使用 npm 的 config 键和 cross-env,您可以:
集中管理配置:所有配置都在 package.json 中
跨平台兼容:脚本在所有操作系统上都能正常工作
灵活覆盖:可以在运行时轻松覆盖默认值
工具集成:与各种开发工具无缝集成
这种方法使配置管理变得更加简单、可靠和可维护。
