In my package.json file I've specified that my nodejs
app is of type module
, because if I do not do that, it seems that I can not use import
statements. This is how it looks like now:
{
"name": "...",
"version": "1.0.0",
"description": "....",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "...."
},
"author": "",
"license": "ISC",
"devDependencies": {
"lodash": "^4.17.15"
},
"type": "module"
}
But if I add the "type": "module"
to my package.json file, I can't use require
statements anymore, because I get a ReferenceError: require is not defined
error.
If I remove the "type": "module"
line from package.json, and rewrite all of my imports to requires, everything works without an error.
I can't seem to find any indication, that import
and require
can not be mixed or used together in the same script, am I missing something here, or I am having some other bug? How could I resolve to use these two kind of statements in the same script?
Why I would need this, is because I want to require
some config files based on dynamic paths, and only if the files exists, which I think I can not do with import
.
DISCLAIMER: I am rather new to nodejs server side programming, so it is possible that I am approaching this situation very wrongly, if that's the case, please advice me something, based on the Why I've mentioned above.
NOTE: I am running this node script from the server terminal, and not from the browser.
But if I add the
"type": "module"
to mypackage.json
file, I can't userequire
statements anymore, because I get aReferenceError: require is not defined error
.
Right. It's either/or. Either you use ESM (JavaScript modules, type = "module") or you use CJS (CommonJS-like Node.js native modules, require
).
But there is some interoperability between them. For instance, in an ESM module you can import
CJS modules, and you can use createRequire
to create a require
function to use to load CJS modules.
Why I would need this, is because I want to
require
some config files based on dynamic paths, and only if the files exists, which I think I can not do withimport
.
You can still do that while using type="module"
. You have a few options:
If these "config" files are JavaScript, you can use createRequire
:
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const yourData = require("./config.js");
If these config files are JSON, you can use the currently-experimental support for importing JSON modules. Since you said you want to allow for files not existing, you'd want to use dynamic import()
rather than static import
declarations:
let config = /*...defaults...*/;
try {
config = await import("./config.json", { assert: { type: "json" } });
} catch (error) {
// ...the file didn't exist or wasn't valid JSON...
}
Or if (again) they're JSON, you can go old school: use readFile
and JSON.parse
. :-)