Reputation: 657
I am using ESM in my node project. Added "type": "module"
in package.json
// index.js
import config from 'config'
// default.js
export default {
time: 123,
...
...
}
But getting error in node-config
Error: Cannot parse config file: '/home/Documents/.../config/default.js': Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/Documents/.../config/default.js
require() of ES modules is not supported.
require() of /home/Documents/.../config/default.js from /home/Documents/.../node_modules/config/parser.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename default.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/Documents/.../package.json.
I can fix this by adding default.cjs
instead of default.js
but as I am using ESM so I am expecting it to work with .js
extension also. am I missing something??. I can add .json
also but I have big config variables and dynamic values that is why using .js
.
Thank you in advance !!!
Upvotes: 2
Views: 4192
Reputation: 11281
According to https://github.com/node-config/node-config/wiki/Special-features-for-JavaScript-configuration-files you can not use ESM for configuration files but must use one of the other supported formats.
Loading files as ESM is not yet supported. So .mjs or .js when "type":"module" or --experimental-modules will not work.
But there is a work-around. For example you could have the following structure, where dynamic.js is where you have big config variables and dynamic values:
.
├── config
│ ├── dynamic.js
│ └── test.cjs
├── index.js
├── node_modules
│ ├── config
│ ├── json5
│ └── minimist
├── package-lock.json
└── package.json
You must tell nodejs that you use esm. So in your package.json you will want to have:
{
"scripts": {
"start": "NODE_ENV=test node index.js"
},
"type": "module"
}
In the beginning of your index.js file, you want to import node-config.
import config from 'config';
const {default:configVariable} = await config.get('variable');
console.debug(configVariable.foo);
In the above case you could write "Hello World!" to your terminal if config/test.cjs and config/dynamic.js has the following:
'use strict'
module.exports = {
variable: import('./dynamic.js')
}
test.cjs
export default {
v1: 'var1',
v2: 'var2',
foo: 'Hello World!'
}
dynamic.js
The result of the above should then be:
$ npm start
> start
> NODE_ENV=test node index.js
Hello World!
Obviously, you can rename variable
and configVariable
to what-ever you want.
In my test, I had no issue with the above way of exporting esm as a Promise. But if you do get any issue with with that, you might solve it by wrapping import()
in require('config/raw').raw
.
See: https://github.com/node-config/node-config/wiki/Special-features-for-JavaScript-configuration-files#using-promises-processstdout-and-other-objects-in-javascript-config-files.
Upvotes: 2