Serverless is incompatible with server-side modules that use `esm`
See original GitHub issueBecause the esm pkg is not intended to be used with webpack, it doesn’t work quite right with target: 'serverless'.
More details can be found in the original issue filed with now-cli: https://github.com/zeit/now-cli/issues/2569.
Despite the advise esm gives to prefer the module key, this is not actually feasible or a proper solution.
This mainly boils down to two reasons, broadly speaking:
- The
modulefield is largely a browser field, not a Node.js field. - Many packages are published with a CJS (
main) variant that does not use thedefaultkey, meaning the non-standard switch to ESM breaks packages that work in Node.
The only viable options is to transform source code to remove esm.
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (6 by maintainers)
Top Results From Across the Web
Serverless is incompatible with server-side modules that use ...
The esm package is largely an attempt to solve this behavior by ensuring the main and module key are identical and isomorphic (until...
Read more >Imoprting ESM-only dependencies/Running as ESM Module
I solved this issue by making a separate handler module that imports the index. mjs file and calls the handler in it, like...
Read more >Setting up a Serverless Project with Webpack, Babel, and Knex
The solution I went for is to use a Babel plugin to transform ESM to CommonJS Modules which is the standard for Node...
Read more >State of the Web: Deno - ByteofDev
In contrast, Deno only works with entirely standards-compliant ESM. Using one module format makes using Deno a lot simpler for both users ...
Read more >Gotchas - Remix
To fix it, move the import into a different module named *.server.js or ... import some CommonJS modules that are incompatible with being...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

browsertypically indicates a UMD build or similar, not a bundler-friendly build. That’s why browser code is under themodulekey, because it spawned fromwebpack(first-and-foremost, a front-end bundler).Ultimately, we have too few field choices to work with here.
For maximum ecosystem compatibility, in my experience, you must:
esmpackage for things intended to be used in browser and Node. This package works great for Node-only packages.modulesfieldmainfield.typeof windowortypeof process, neverprocess.browser).However, more projects are moving towards compiling
./node_modules/which allow you to ship ES.Latest under themodulekey. Next.js will do this soon. Some other parts of the ecosystem still need to catch up, so this isn’t generally safe yet. Do note, compiling other users code is not a safe behavior, but works in most cases.The code shipped under the
mainkey still should be compiled down to the oldest-non-EOL Node version.TBH, for your specific case, I would:
modulekeyindex(note no extension), this allows users to resolve.mjsfirst if they desire in their bundler, otherwise gives.jsw/ CJSindex.mjsthat re-exports themodulekey’s entry point (or, preferably, skip this all together since ESM in Node.js isn’t a real thing)index.jsthat contains compiled commonjs code☝️ unfortunately there’s no
esmin this picture since your code is designed to be used in browser and server.Whilst this will actually be solved in Next.js soon (and you can use your current setup, with
esmas-is), you may find other users / tools having to customize their setup to accommodate it.Edit: Just want to add/reiterate:
The above suggestion is an opinion based on my experiencing maintaining two popular DX Toolboxes. There is no right or wrong answer because none of these fields are based on standards.
These practices also do not reflect the direction the ecosystem is potentially heading in the future, because they’re concerned with present-day maximum compatibility.
As an anecdote, you’ll see Node 12 uses a completely different behavior and that users are beginning to ask for ES.Latest to be published.
No @ericelliott, because they end up being bundled by webpack which converts them into commonjs.