I have browsed a lot of questions in this space, but I haven't found a clear answer.
I recently updated many of my project's npm dependencies to their latest. The project is entirely built around commonJS and most of the npm modules it includes use commonJS. However, a few (like chalk
) now use ES syntax. Surprisingly I haven't found a reasonable way of including those modules.
Since I can apparently use import
to load commonJS modules I guess I can change all the require
statements to import
, presumably having to use dynamic import for the few places where I'm using require
dynamically. Is this the only solution? Seems silly to have to change the entire structure to support a few npm modules.
CodePudding user response:
In the more recent versions of nodejs, the way to import an ESM module directly into a CommonJS module is with the dynamic version of import
as in:
// import ESM module from CommonJS module
import("chalk").then(m => {
// use m here
});
This is the one way that import
is allowed in a CommonJS module, though it may make coding and sticking with your CommonJS core a little more difficult.
This limitation is partially because ESM modules can use top-level await on asynchronous operations, but require()
which CommonJS modules are built around is a purely synchronous model. So, allowing top level await
in ESM modules is incompatible with a purely synchronous CommonJS loading architecture.
The dynamic import()
is an asynchronous loading model so it can be used to load ESM modules, even in a CommonJS module.
With more and more NPM modules moving to ESM interfaces only, it appears that the writing is on the wall to begin transitioning projects over to ESM. ESM is fairly full featured and implemented now in both nodejs and browsers.
You can load CommonJS modules from ESM modules with the regular import
so that makes it easier to move to ESM too.