This repository has been archived by the owner on Apr 14, 2023. It is now read-only.
Support native ESM with .mjs
#537
Labels
feature
New addition or enhancement to existing solutions
has-reproduction
❤ Has a reproduction in a codesandbox or single minimal repository
This affects every Apollo package, not just Apollo links.
Node.js with
--experimental-modules
can run ESM in .mjs files. Soon ESM will work without a flag.At the moment, all Apollo packages can not be imported in a native ESM environment using named imports (e.g.
import { ApolloLink } from 'apollo-link'
). You have to use default imports, which is unintuitive and defeats tree shaking compilers.So that both CJS and ESM environments can consume a package properly, sibling
.js
(CJS) and.mjs
(ESM) files with the same names need to be published. Node.js will load the relevant file, looking up.mjs
before.js
formain
if--experimental-modules
is enabled. This is also how resolution works in Webpack v4 and other tools.package.json
entries need to look like this:Note that all imports within the
.mjs
files must be valid, i.e. there can be no named imports from CJS dependencies. A solution is to convert violating imports to use default instead. As this does not tree shake and degrades bundle size, the ultimate solution is to add propper native ESM support upstream.There are other benefits being realised over time to using the
.mjs
extension for ESM, even for source files. For example, Babel can now can set the mode automatically.My advice is to drop the TypeScript compiler, and use Babel v7 for everything as it now supports TS. It works better with
.mjs
, and will result in faster builds as you don't have to run TS and then Babel. This is an opportunity to ensure every package is setup with@babel/preset-env
to ensure only the required transpilation happens for a certain level of environment support. It should be configured to only include helpers and polyfills accordingly, and as imported dependencies so they are not duplicated in each package in a consumer's bundle. Some packages are using Rollup; this can be removed. For best results bundling and minification should happen exclusively in a consumer's project.A few related packages that provide
.mjs
for inspiration:graphql
.apollo-upload-server
apollo-upload-client
, although I'm about to fix an issue caused by a lack of support by Apollo dependencies.Related Slack discussion.
Expected Behavior
In
test.mjs
:Running
node --experimental-modules test.mjs
should log:Actual Behavior
A simple reproduction
See above.
Issue Labels
The text was updated successfully, but these errors were encountered: