如何让npm config同时读取default.json与新增的editable.json配置文件?
Hey there! I get where you're coming from—npm's built-in config system doesn't natively support loading multiple custom JSON config files beyond its default setup, but there are a couple of practical workarounds depending on your use case. Let's break them down:
Scenario 1: Read and Merge Configs in Your Node.js Code
If you need to use the combined config values directly in your project's code, the simplest approach is to manually read both files using Node's built-in fs module and merge the objects (with the editable config taking priority over defaults).
Here's a quick example:
const fs = require('fs').promises; const path = require('path'); async function getCombinedConfig() { // Read both config files const defaultConfigRaw = await fs.readFile(path.join(__dirname, 'default.json'), 'utf8'); const editableConfigRaw = await fs.readFile(path.join(__dirname, 'editable.json'), 'utf8'); // Parse JSON into objects const defaultConfig = JSON.parse(defaultConfigRaw); const editableConfig = JSON.parse(editableConfigRaw); // Merge: editable config keys override default ones return { ...defaultConfig, ...editableConfig }; } // Use the combined config getCombinedConfig() .then(config => { console.log('Combined configuration:', config); // Your app logic using the config goes here }) .catch(err => console.error('Failed to load config:', err));
Scenario 2: Make npm Commands/Scripts Use the Combined Config
If you want npm itself (or your npm scripts) to recognize the combined config values, you can inject them into npm's config system via environment variables or temporary npm config settings.
Option A: Inject as Environment Variables
npm automatically picks up environment variables prefixed with npm_config_ as config values. You can write a script to merge your JSON files and set these variables before running your main command:
const fs = require('fs').promises; const path = require('path'); const { execSync } = require('child_process'); async function loadConfigAndRun() { // Same as before: read and merge configs const defaultConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'default.json'), 'utf8')); const editableConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'editable.json'), 'utf8')); const combinedConfig = { ...defaultConfig, ...editableConfig }; // Set environment variables for npm to detect Object.entries(combinedConfig).forEach(([key, value]) => { process.env[`npm_config_${key}`] = String(value); }); // Run your main command (replace with your actual command) execSync('node index.js', { stdio: 'inherit' }); } loadConfigAndRun().catch(err => console.error('Error:', err));
Then update your package.json scripts to use this:
"scripts": { "start": "node load-config-and-run.js" }
Option B: Temporary npm Config Settings
Alternatively, you can write a script that directly sets npm config values temporarily (valid for the current shell session):
const fs = require('fs').promises; const path = require('path'); const { execSync } = require('child_process'); async function mergeConfigsToNpm() { const defaultConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'default.json'), 'utf8')); const editableConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'editable.json'), 'utf8')); const combinedConfig = { ...defaultConfig, ...editableConfig }; // Set each key-value pair in npm config Object.entries(combinedConfig).forEach(([key, value]) => { execSync(`npm config set ${key} "${value}"`, { stdio: 'inherit' }); }); } mergeConfigsToNpm().catch(err => console.error('Failed to merge configs:', err));
Then chain this script in your npm commands:
"scripts": { "load-config": "node merge-configs.js", "start": "npm run load-config && node index.js" }
Bonus: For Build Tools (Webpack, Vue CLI, etc.)
If you're using a build tool that has its own config system, you can usually extend it to read your JSON files. For example:
- With Webpack: Use the
webpack-mergeplugin to merge config objects read from your JSON files. - With Vue CLI: Import and merge the JSON configs directly in your
vue.config.jsfile.
内容的提问来源于stack exchange,提问作者Hai Tien




