Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ESM/CJS and deep imports #6606

Merged
merged 1 commit into from Jun 23, 2022
Merged

Fix ESM/CJS and deep imports #6606

merged 1 commit into from Jun 23, 2022

Conversation

glasser
Copy link
Member

@glasser glasser commented Jun 23, 2022

There were a few problems with #6580, which added ESM builds and deep
imports to version-4.

The exports section of packages/server/package.json had two
mistakes: the types lines linked to files in the cjs directory but we
only placed them in the esm directory, and the types lines are
apparently supposed to appear first in each block.

However, it turned out that this didn't matter because tsc doesn't even
look in the exports section unless you set moduleResolution to
node16 or nodenext in your tsconfig compilerOptions, and we
weren't! And it turns out doing that setting is a bit of a pain because
many packages don't currently work with that flag. So if we published
our package with the deep imports only listed in exports in
package.json, we'd break any TypeScript user who's on the normal
moduleResolution: "node" and telling them to set nodenext would be
hard to obey.

So since we want to continue to support tsc with moduleResolution: "node", we have to teach tsc about our deep imports using the strategy
of "spew a bunch of package.jsons around the package", not even under
src/dist. Fortunately these package.json files can use paths
starting with ../ in order to find the actual generated files. So for
example, standalone/package.json tells tsc how to find
../dist/standalone/index.d.ts, via fields like types and main.

You might think that now that we have these little package.json files,
the exports block would be completely redundant. Not so! Node itself
does not support deep imports like @apollo/server/standalone by
looking for a main in standalone/package.json: when importing from a
published package name, it only looks for main at the top level of the
package. So to support deep imports in Node we need the exports block!

So this PR leaves both the exports block and the tree of
package.jsons in place, to be consumed by different software.

We add some tsc use cases to the new smoke test.

Our smoke tests verify that consumers with moduleResolution: "nodenext" work (or at least, that they will work once ardatan/graphql-tools#4532 is released). However, our own builds don't work that way next because some of our test-only dependencies don't work with that flag.

There were a few problems with #6580, which added ESM builds and deep
imports to version-4.

The `exports` section of `packages/server/package.json` had two
mistakes: the `types` lines linked to files in the cjs directory but we
only placed them in the esm directory, and the `types` lines are
apparently supposed to appear first in each block.

However, it turned out that this didn't matter because tsc doesn't even
look in the `exports` section unless you set `moduleResolution` to
`node16` or `nodenext` in your tsconfig `compilerOptions`, and we
weren't! And it turns out doing that setting is a bit of a pain because
many packages don't currently work with that flag. So if we published
our package with the deep imports only listed in `exports` in
package.json, we'd break any TypeScript user who's on the normal
`moduleResolution: "node"` and telling them to set `nodenext` would be
hard to obey.

So since we want to continue to support tsc with `moduleResolution:
"node"`, we have to teach tsc about our deep imports using the strategy
of "spew a bunch of package.jsons around the package", not even under
`src`/`dist`. Fortunately these package.json files can use paths
starting with `../` in order to find the actual generated files. So for
example, `standalone/package.json` tells tsc how to find
`../dist/standalone/index.d.ts`, via fields like `types` and `main`.

You might think that now that we have these little package.json files,
the `exports` block would be completely redundant. Not so! Node itself
does not support deep imports like `@apollo/server/standalone` by
looking for a `main` in `standalone/package.json`: when importing from a
published package name, it only looks for `main` at the top level of the
package. So to support deep imports in Node we need the `exports` block!

So this PR leaves both the `exports` block and the tree of
`package.json`s in place, to be consumed by different software.

We add some tsc use cases to the new smoke test.

Note that it is not a goal of this PR to ensure that `moduleResolution:
"nodenext"` works.
@netlify
Copy link

netlify bot commented Jun 23, 2022

Deploy Preview for apollo-server-docs ready!

Name Link
🔨 Latest commit d289cec
🔍 Latest deploy log https://app.netlify.com/sites/apollo-server-docs/deploys/62b41efeaf92e400086c0a82
😎 Deploy Preview https://deploy-preview-6606--apollo-server-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit d289cec:

Sandbox Source
Apollo Server Typescript Configuration
Apollo Server Configuration

Copy link
Member

@trevor-scheer trevor-scheer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on this, seems like a pretty good outcome!

},
"./plugin/disabled": {
"types": "./dist/esm/plugin/disabled.d.ts",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanna make the index change here for consistency?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh it looks like you did make that file move so I think this needs an update.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and maybe we need to smoke test these paths since presumably this is in a broken state without CI knowing.

@glasser glasser merged commit 47b798c into version-4 Jun 23, 2022
@glasser glasser deleted the glasser/new-esm-approach branch June 23, 2022 18:21
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants