Skip to content

Commit 1254a08

Browse files
Merge pull request #3208 from pierreb-devkit/docs/downstream-config-naming
docs(config): document downstream naming convention
2 parents 1e3ff86 + 03ac0f6 commit 1254a08

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

MIGRATIONS.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ The monolithic `config/defaults/development.js` has been split into per-module c
1515
- **Updated**: `config/index.js` now globs module configs and merges them in layers
1616
- **Standalone env files**: `config.production.js` and `config.test.js` no longer import `development.js` — they export only their overrides
1717
- **Assets glob**: `config/assets.js` changed from `modules/*/config/*.js` to `modules/*/config/*.config.js` (excludes data config files, still matches init modules like `users.config.js`)
18+
- **Template**: `config/defaults/config.myproject.js` added as a starting point for downstream projects
19+
- **Startup warning**: the loader now warns when `NODE_ENV` is non-standard and no matching config files are found
1820

1921
### New file layout
2022

@@ -51,6 +53,10 @@ Create `NODE_ENV=staging` by adding any of:
5153

5254
No file is required — only modules that define a `config.<env>.js` will be overridden.
5355

56+
### Downstream project config files
57+
58+
Files must be named `config.{projectname}.js` — files without the `config.` prefix are silently ignored. A template is provided at `config/defaults/config.myproject.js`.
59+
5460
### Steps for downstream projects
5561

5662
1. If you have **customized** `config/defaults/development.js`:
@@ -64,8 +70,9 @@ No file is required — only modules that define a `config.<env>.js` will be ove
6470
- Remove the `import ... from './development.js'` and `merge()` wrapper — just export the override object directly
6571
- If your test overrides contain module-specific keys (e.g. `uploads`), move them to `modules/<name>/config/config.test.js`
6672
3. If you have **custom init modules** matching `modules/*/config/*.js` that are NOT named `*.config.js`, rename them to follow the `*.config.js` convention (the assets glob has changed).
67-
4. If you have **not customized** any config files, the merge will apply cleanly.
68-
5. Run `npm run lint && npm test` to confirm everything works.
73+
4. Rename any `{projectname}.js` config files to `config.{projectname}.js` (both in `config/defaults/` and `modules/*/config/`)
74+
5. If you have **not customized** any config files, the merge will apply cleanly.
75+
6. Run `npm run lint && npm test` to confirm everything works.
6976

7077
---
7178

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@ DEVKIT_NODE_app_title='my app' # sets config.app.title
156156
DEVKIT_NODE_db_uri='mongodb://...' # sets config.db.uri
157157
```
158158

159+
### Downstream projects
160+
161+
When running a downstream project that clones this stack, set `NODE_ENV` to the project name and create matching config files:
162+
163+
```text
164+
config/defaults/
165+
config.myproject.js ← global project overrides (optional)
166+
167+
modules/<name>/config/
168+
config.myproject.js ← module project overrides (optional)
169+
```
170+
171+
The loader discovers files named `config.${NODE_ENV}.js` — files without the `config.` prefix are ignored.
172+
159173
## :whale: Docker
160174

161175
```bash
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Downstream project config template.
3+
*
4+
* 1. Copy this file and rename it to config.{yourproject}.js
5+
* 2. Set NODE_ENV={yourproject} when running the app
6+
* 3. Override only the keys you need — development defaults are used for everything else
7+
*
8+
* @example NODE_ENV=myproject npm start
9+
*/
10+
export default {
11+
// app: {
12+
// title: 'My Project',
13+
// },
14+
// db: {
15+
// uri: 'mongodb://localhost/MyProjectDev',
16+
// },
17+
};

config/index.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { pathToFileURL } from 'url';
1010
import assets from './assets.js';
1111
import configHelper from '../lib/helpers/config.js';
1212

13+
const STANDARD_ENVS = new Set(['development', 'production', 'test']);
14+
1315
/**
1416
* Deep merge two objects, replacing arrays instead of merging by index.
1517
* @param {Object} target - Base object
@@ -91,15 +93,25 @@ const initGlobalConfig = async () => {
9193
// Layer 3 & 4: environment overrides (only if not development)
9294
if (env !== 'development') {
9395
// Layer 3: module env overrides
94-
const moduleEnvConfigs = await loadModuleConfigs(`modules/*/config/config.${env}.js`);
96+
const moduleEnvPattern = `modules/*/config/config.${env}.js`;
97+
const moduleEnvConfigs = await loadModuleConfigs(moduleEnvPattern);
98+
const hasModuleEnvConfigs = (await configHelper.getGlobbedPaths(moduleEnvPattern)).length > 0;
9599
config = deepMerge(config, moduleEnvConfigs);
96100

97101
// Layer 4: global env override
98102
const globalEnvPath = path.join(process.cwd(), 'config', 'defaults', `config.${env}.js`);
99-
if (fs.existsSync(globalEnvPath)) {
103+
const hasGlobalEnvConfig = fs.existsSync(globalEnvPath);
104+
if (hasGlobalEnvConfig) {
100105
const globalEnv = await loadConfigFile(globalEnvPath);
101106
config = deepMerge(config, globalEnv);
102107
}
108+
109+
// Warn when a non-standard NODE_ENV has no matching config files
110+
if (!STANDARD_ENVS.has(env) && !hasModuleEnvConfigs && !hasGlobalEnvConfig) {
111+
console.warn(
112+
chalk.yellow(`+ Warning: NODE_ENV="${env}" but no config.${env}.js files found — using development defaults. Downstream projects should create config.${env}.js files (see README).`),
113+
);
114+
}
103115
}
104116

105117
// Layer 5: DEVKIT_NODE_* env vars (final override)

0 commit comments

Comments
 (0)