Skip to content

Commit 367fcc9

Browse files
committed
ESM conversion with test migration.
1 parent 4dc196c commit 367fcc9

30 files changed

Lines changed: 359 additions & 375 deletions

lib/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/** @typedef {import('./config.mjs').Config} Config */
2+
3+
/** @type {Config} */
4+
module.exports = require('./config.mjs').default;

lib/config.mjs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
// http://lorenwest.github.com/node-config
55

66
// Dependencies
7-
/** @typedef {import('./util').Util} Util */
8-
/** @typedef {import('./util').Load} Load */
9-
/** @typedef {import('./util').LoadOptions} LoadOptions */
10-
/** @typedef {typeof import('./../parser')} Parser */
11-
const { Util, Load, RawConfig } = require('./util.js');
12-
const Path = require('path');
7+
/** @typedef {import('./util.js').Util} Util */
8+
/** @typedef {import('./util.js').Load} Load */
9+
/** @typedef {import('./util.js').LoadOptions} LoadOptions */
10+
/** @typedef {typeof import('./../parser.js')} Parser */
11+
import { Util, Load, RawConfig } from './util.js';
12+
import Path from 'path';
1313

1414
const LOAD_SYMBOL = Symbol('load');
1515
const DEFAULT_CLONE_DEPTH = 20;
@@ -432,7 +432,7 @@ class ConfigUtils {
432432
* </p>
433433
*
434434
* @method getConfigSources
435-
* @return {import('./util').ConfigSource[]} configSources - An array of objects containing
435+
* @return {import('./util.js').ConfigSource[]} configSources - An array of objects containing
436436
* name, original, and parsed elements
437437
*/
438438
getConfigSources() {
@@ -699,7 +699,7 @@ function _init(load) {
699699
}
700700

701701
/** @type {Config} */
702-
module.exports = (() => {
702+
export default (() => {
703703
const load = Load.fromEnvironment();
704704

705705
_init(load);

lib/defer.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { isAsyncFunction } = require('node:util/types');
1+
import { isAsyncFunction } from 'node:util/types';
22

33
/** @typedef {import('./config').Config} Config */
44

@@ -66,5 +66,4 @@ function deferConfig(func) {
6666
return obj;
6767
}
6868

69-
module.exports.deferConfig = deferConfig;
70-
module.exports.DeferredConfig = DeferredConfig;
69+
export { deferConfig, DeferredConfig };

lib/util.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
// Dependencies
77
/** @typedef {typeof import('./../parser')} Parser */
8-
const { deferConfig, DeferredConfig } = require('./defer.js');
9-
const Path = require('path');
10-
const FileSystem = require('fs');
11-
const OS = require("os");
8+
import Path from 'node:path';
9+
import FileSystem from 'node:fs';
10+
import OS from 'node:os';
11+
import { createRequire } from 'node:module';
12+
13+
import defaultParser from '../parser.js';
14+
import { deferConfig, DeferredConfig } from './defer.js';
1215

1316
const DEFAULT_CONFIG_DIR = Path.join( process.cwd(), 'config');
1417
const SEEN_ERRORS = {};
@@ -60,7 +63,7 @@ const DEFAULT_OPTIONS = {
6063
nodeEnv: ['development'],
6164
hostName: OS.hostname(),
6265
gitCrypt: true,
63-
parser: require("../parser.js")
66+
parser: defaultParser
6467
};
6568

6669
/**
@@ -1392,7 +1395,6 @@ class Load {
13921395
// Remove any . appendages, and default to null if not set
13931396
try {
13941397
if (!hostName) {
1395-
const OS = require('os');
13961398
hostName = OS.hostname();
13971399
}
13981400
} catch (e) {
@@ -1450,20 +1452,22 @@ function _toAbsolutePath (configDir) {
14501452
return configDir;
14511453
}
14521454

1453-
function _loadParser(name, dir) {
1455+
function _loadParser(name, dir = process.cwd()) {
14541456
if (name === undefined) {
1455-
return require("../parser.js");
1457+
return defaultParser;
14561458
}
14571459

1460+
const require = createRequire(dir);
1461+
14581462
try {
1459-
const parserModule = Path.isAbsolute(name) ? name : Path.join(dir, name);
1463+
const required = require(Path.resolve(dir, name));
14601464

1461-
return require(parserModule);
1465+
return required.default ?? required;
14621466
}
14631467
catch (e) {
14641468
console.warn(`Failed to load config parser from ${name}`);
14651469
console.log(e);
14661470
}
14671471
}
14681472

1469-
module.exports = { Util, Load, RawConfig };
1473+
export { Util, Load, RawConfig };

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "config",
33
"version": "4.4.0",
44
"main": "./lib/config.js",
5+
"module": "./lib/config.mjs",
56
"types": "types/lib/config.d.ts",
67
"typesVersions": {
78
"*": {
@@ -69,7 +70,7 @@
6970
"url": "http://github.com/node-config/node-config.git"
7071
},
7172
"engines": {
72-
"node": ">= 20.0.0"
73+
"node": ">= 20.11.0"
7374
},
7475
"c8": {
7576
"include": [

parser.js

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
// External libraries are lazy-loaded only if these file types exist.
2+
import Path from 'path';
3+
import { createRequire } from 'node:module';
4+
import JSON5 from 'json5';
25

3-
// webpack can't solve dynamic module
4-
// @see https://github.com/node-config/node-config/issues/755
5-
// @see https://webpack.js.org/guides/dependency-management/#require-with-expression
6-
const JSON5Module = require('json5');
6+
const moduleRequire = createRequire(Path.join(process.cwd(), 'node_modules'));
7+
const require = createRequire(process.cwd());
78

8-
// webpack resolves json5 with module field out of the box which lead to this usage
9-
// @see https://github.com/node-config/node-config/issues/755
10-
// @see https://github.com/json5/json5/issues/240
11-
const JSON5 = JSON5Module.default || JSON5Module;
12-
13-
var Yaml = null,
9+
let Yaml = null,
1410
JSYaml = null,
1511
Coffee = null,
1612
Iced = null,
1713
CSON = null,
1814
PPARSER = null,
1915
TOML = null,
2016
HJSON = null,
21-
XML = null;
17+
XML = null,
18+
TS = null;
2219

2320
// Define soft dependencies so transpilers don't include everything
24-
var COFFEE_2_DEP = 'coffeescript',
21+
let COFFEE_2_DEP = 'coffeescript',
2522
COFFEE_DEP = 'coffee-script',
2623
ICED_DEP = 'iced-coffee-script',
2724
JS_YAML_DEP = 'js-yaml',
@@ -38,7 +35,7 @@ var COFFEE_2_DEP = 'coffeescript',
3835
* @template [T=any]
3936
* @typedef {(filename: string, content: string) => T | undefined} ParserFn<T>
4037
*/
41-
var Parser = module.exports;
38+
let Parser = {};
4239

4340
/**
4441
* @param {string} filename
@@ -60,7 +57,7 @@ Parser.parse = function(filename, content) {
6057
*/
6158
Parser.xmlParser = function(filename, content) {
6259
if (!XML) {
63-
XML = require(XML_DEP);
60+
XML = moduleRequire(XML_DEP);
6461
}
6562
var x2js = new XML();
6663
var configObject = x2js.xml2js(content);
@@ -91,15 +88,18 @@ Parser.jsParser = function(filename, content) {
9188
* @returns {object}
9289
*/
9390
Parser.tsParser = function(filename, content) {
94-
if (!require.extensions['.ts']) {
95-
require(TS_DEP).register({
96-
lazy: true,
97-
ignore: ['(?:^|/)node_modules/', '.*(?<!\.ts)$'],
98-
transpileOnly: true,
99-
compilerOptions: {
100-
allowJs: true,
101-
}
102-
});
91+
if (require?.extensions['.ts'] === undefined) {
92+
if (TS === null) {
93+
TS = moduleRequire(TS_DEP);
94+
TS.register({
95+
lazy: true,
96+
ignore: ['(?:^|/)node_modules/', '.*(?<!\.ts)$'],
97+
transpileOnly: true,
98+
compilerOptions: {
99+
allowJs: true,
100+
}
101+
});
102+
}
103103
}
104104

105105
// Imports config if it is exported via module.exports = ...
@@ -126,21 +126,13 @@ Parser.coffeeParser = function(filename, content) {
126126
if (!Coffee) {
127127
Coffee = {};
128128

129-
// The following enables iced-coffee-script on .coffee files, if iced-coffee-script is available.
130-
// This is commented as per a decision on a pull request.
131-
//try {
132-
// Coffee = require('iced-coffee-script');
133-
//}
134-
//catch (e) {
135-
// Coffee = require('coffee-script');
136-
//}
137129
try {
138130
// Try to load coffeescript
139-
Coffee = require(COFFEE_2_DEP);
131+
Coffee = moduleRequire(COFFEE_2_DEP);
140132
}
141133
catch (e) {
142134
// If it doesn't exist, try to load it using the deprecated module name
143-
Coffee = require(COFFEE_DEP);
135+
Coffee = moduleRequire(COFFEE_DEP);
144136
}
145137
// coffee-script >= 1.7.0 requires explicit registration for require() to work
146138
if (Coffee.register) {
@@ -157,7 +149,7 @@ Parser.coffeeParser = function(filename, content) {
157149
* @returns {object | undefined}
158150
*/
159151
Parser.icedParser = function(filename, content) {
160-
Iced = require(ICED_DEP);
152+
Iced = moduleRequire(ICED_DEP);
161153

162154
// coffee-script >= 1.7.0 requires explicit registration for require() to work
163155
if (Iced.register) {
@@ -174,10 +166,10 @@ Parser.yamlParser = function(filename, content) {
174166
if (!Yaml && !JSYaml) {
175167
// Lazy loading
176168
try {
177-
Yaml = require(YAML_DEP);
169+
Yaml = moduleRequire(YAML_DEP);
178170
} catch (e) {
179171
try {
180-
JSYaml = require(JS_YAML_DEP);
172+
JSYaml = moduleRequire(JS_YAML_DEP);
181173
} catch (e) {}
182174
}
183175
}
@@ -221,7 +213,7 @@ Parser.json5Parser = function(filename, content) {
221213
*/
222214
Parser.hjsonParser = function(filename, content) {
223215
if (!HJSON) {
224-
HJSON = require(HJSON_DEP);
216+
HJSON = moduleRequire(HJSON_DEP);
225217
}
226218
return HJSON.parse(content);
227219
};
@@ -233,7 +225,7 @@ Parser.hjsonParser = function(filename, content) {
233225
*/
234226
Parser.tomlParser = function(filename, content) {
235227
if(!TOML) {
236-
TOML = require(TOML_DEP);
228+
TOML = moduleRequire(TOML_DEP);
237229
}
238230
return TOML.parse(content);
239231
};
@@ -245,7 +237,7 @@ Parser.tomlParser = function(filename, content) {
245237
*/
246238
Parser.csonParser = function(filename, content) {
247239
if (!CSON) {
248-
CSON = require(CSON_DEP);
240+
CSON = moduleRequire(CSON_DEP);
249241
}
250242
// Allow comments in CSON files
251243
if (typeof CSON.parseSync === 'function') {
@@ -261,7 +253,7 @@ Parser.csonParser = function(filename, content) {
261253
*/
262254
Parser.propertiesParser = function(filename, content) {
263255
if (!PPARSER) {
264-
PPARSER = require(PPARSER_DEP);
256+
PPARSER = moduleRequire(PPARSER_DEP);
265257
}
266258
return PPARSER.parse(content, { namespaces: true, variables: true, sections: true });
267259
};
@@ -382,3 +374,5 @@ Parser.setFilesOrder = function(name, newIndex) {
382374
function isObject(arg) {
383375
return (arg !== null) && (typeof arg === 'object');
384376
}
377+
378+
export default Parser;

0 commit comments

Comments
 (0)