Sorry, this isn't really an issue, but I do not see a questions section here in github.
Have you thought about making a project that is kind of the opposite of this project; importing commonJS modules where the entry script is mjs?
I'm in the process of converting a node project from commonJS to ESM, where node is run with the --experimental-modules flag.
So, you see, I'm not trying to import ESM modules into CommonJS; I'm trying to go the other way around (importing CommonJS modules into ESM).
hey @Lonniebiz
could you elaborate more on the specific problem you are facing?
So, you see, I'm not trying to import ESM modules into CommonJS; I'm trying to go the other way around (importing CommonJS modules into ESM).
esm can load commonjs modules into es6 modules (js + mjs).
Hi @Lonniebiz
I'll start with my usual Node core + Module WG spiel below:
:wave: Node core and Node Module WG member here. There is no set date for when
--experimental-moduleswill be unflagged. There's also no guarantee that what has shipped now is what will be in the future. For example, there are several discussions in the Node Module WG on how to approach implementation. One such discussion is to ship a maximally minimal implementation that would require package-name-maps for resolving bare specifiers _(no longer using the Node module resolution algorithm)_.Adopting
.mjswith the idea that its current support is solid _(for production use)_ at this stage is bit premature and may cause headaches for users. Folks have already seen.mjscause issues for real projects like react-apollo, graphql, and create-react-app due to complications with babel, webpack, testing/mocks, or dual packages. If/when changes do happen to Node's--experimental-modulesyour ESM story could be various shades of broken.The
--experimental-modulesflag really does mean experimental. It's something you should pause and consider at least before going all in as the route for your ESM support strategy today.
The esm loader locks down .mjs use so that no esm options extend to it because Node will ship some support for .mjs, but the details are not finalized. I want to avoid giving a false sense of ecosystem compatibility/interoperability with something experimental, because I saw that in earlier versions of the loader support for such things actually embolden folks to use --experimental-modules in production (not good).
By Node's experimental rules CJS modules are not able to load packages with an entry script that has a .mjs extension using require. However, Node's experimental ESM support does allow importing CJS modules:
import _ from "lodash"
or
import("lodash")
.then((_) => /*stuff*/)
@jdalton : When I was researching this last night, after coming across this project, I found this article by Axel Rauschmayer. From there I discovered the Plan for New Modules Implementation and it looks like module.createRequireFromPath landed in Node 11.8.
Still, like you warn, they could change anything before ESM support lands in a stable release. I'm so beyond eager for this to supported, and I'm just trying to figure out the best way to migrate to ESM now in a way that won't take too many modifications once things are finalized. Perhaps this project is the answer; I'm still studying it.
Yeah, after reading this article, I think this project is an excellent step in my migration strategy.
You should emphasize an example like this one on the main page:
const esmImport = require('esm')(module);
const { bar, baz } = esmImport('./my-foo');
console.log(bar, baz);
That's gold, right there.
The code above works fine when I run it on the source files live, but after bundling with webpack, I get a seemingly unrelated error when I try to run the bundle:
TypeError: Cannot destructure propertydirof 'undefined' or 'null'.
The instructions on bundling are not clear to me. They're not explicit enough for my comprehension; they seem to assume some type of familiarity that I do not have. Is there more documentation anywhere?
Hi @Lonniebiz!
I should add a doc note. For bundlers like webpack, parcel, pr browserify (with esmify) you should add a "module" field to your package.json that points to your ESM entry and not the CJS bridge. Using your example it would be:
"module": "my-foo"
Update:
Expanded bundler doc note https://github.com/standard-things/esm/commit/e4a4eb9f69f8134f4cf7b1e844652217fb00d787.
I figured that much out. Maybe the actual location of may es module is something that node understands but webpack doesn't:
"module": '../../client/src/folder5/abc.mjs',
You see, its actually in another project a couple of folders up (I'm struggling right now to figure out how to have all my code in one place and use it easily on all new projects). Like I say, if I run from source files it works. The bundle builds without error, but running node bundleName.js fails.
I only tell you this in case you might notice something obvious that could be causing my problem.
Packages should have an entry module. So for deploying packages with esm you'll need to have a CommonJS bridge file as an index.js and then the real ES module entry file as something like main.js. You should not be reaching across package boundaries.
"main": "index.js",
"module": "main.js"
For applications you can use esm like:
node -r esm ./start.js
This enables ESM support at a broader application range, compared to just a package range, and all files (even packages in node_modules) will be loaded with the esm loader.