Skip to content

esm: Implement package.json "esm": true flag for ES modules in ".js" files

As previous proposed and discussed at https://github.com/nodejs/node-eps/pull/60, this implements a package.json lookup process for the module format so that adding "esm": true to the package.json enables ".js" files as ES modules.

There has been some discussion as well here as to whether this property should be a string to allow for extensibility in future, which is also still ongoing.

The ideal workflow imagined would be one where the package manager init process itself adds this into the package.json so that it becomes an invisible part of the authoring process, not completely dissimilar to the <!doctype> in html.

The cost of this approach is loading the base-level package.json for all module loads (instead of just for mains). The argument here is that there is already a lot of statting in the module lookup process, and since this shares the package.json cache with the mains, it adds around one extra stat on average for subfolder package lookups per package loaded. (Compare to adding ".mjs", which has added an extra stat per lookup path checked, an order of magnitude more in cost here).

The benefit of this approach is end-users never need to worry about the authoring format of a package they are importing, build tools and bundlers won't need to adapt to a separate linking mechanism for CommonJS, and that NodeJS ES modules wouldn't need to themselves be built for the browser.

The test cases here cover nesting, invalid values and subpaths. A package.json without an "esm": true property, or an invalid "esm" property is treated as if it contained "esm": false (ie ".js" files as CommonJS modules).

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

esmodules

Merge request reports

Loading