-
Notifications
You must be signed in to change notification settings - Fork 12
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
feat: require TypeScript module resolution compatible exports map #55
Conversation
🦋 Changeset detectedLatest commit: c2c8cf1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest changes of this PR are not available as alpha, since there are no linked |
4c027a3
to
8cf63c9
Compare
…s to the package.json files
8cf63c9
to
eb984f2
Compare
2e18f50
to
cceffca
Compare
cceffca
to
11bc1d5
Compare
This is now tested in dotansimha/graphql-yoga#1307 with feedback being collected in dotansimha/graphql-yoga#1217 |
This comment was marked as resolved.
This comment was marked as resolved.
bdaa67c
to
c478235
Compare
8145794
to
6d0c3d3
Compare
6d0c3d3
to
18f8755
Compare
18f8755
to
47c190f
Compare
@n1ru4l I love it!! |
bc31a81
to
55ec258
Compare
43be269
to
34ee308
Compare
9da2e6f
to
b3c06ea
Compare
@dotansimha Right now the bootstrap command does not care, we can make it more flexible in a follow-up PR. I also think we should have some kind of command for easily adding a new package to a monorepo or converting a single package repo into a monorepo. |
@n1ru4l used it on https://github.com/charlypoly/graphql-yoga-nestjs, worked like a charm! |
To all reviewers: please give feedback and opinions - DO NOT YET MERGE ITHigh-level changes of this PR
prepack
command (which did not do anything important)bootstrap
commandbob build
command for single-package repo and mono repoDetails
1. Remove the
prepack
commandThis command is unnecessary and it's usage can safely be removed from all our packages that use bob.
2. Introduce the
bootstrap
commandThe bootstrap command looks for all
package.json
files within a repository and alters them by adding the opinionated fields (exports, main, module, type, and publishConfig). A full list of the opinionatedpackage.json
fields can be found within thesrc/commands/bootstrap.ts
file. In a future release we want to allow customizing theexports
map on a package basis.Furthermore, the bootstrap command looks for all
*.ts
files and transforms theimports
andexport
paths of RELATIVEpackages
(./
,../
) and adds the.js
extension at the end. This is necessary for pleasing the TypeScript compiler, but also ESM resolution to work properly.Before:
After:
NOTE:
We need an eslint rule in each package that every relative import ends withUPDATE: The script for checking CommonJS and ESM (7.) imports actually already covers this..js
. The problem is that we could enforce it via typescript compiler when using "moduleResolution": "Node16". However, it will break our build as w have a lot of dev-only dependencies that then would raise compiler errors in test cases. We can't really run jest in ESM just yet (as it is a nightmare).So for all the projects upgrading to the latest bob should be as simple as:
bob bootstrap
3. jest-resolver config
Unfortunately, adding
.js
to relative imports (as mentioned in#2
) breaks jest module resolution in commonjs mode. For now, we should not upgrade to running tests on ESM as it is a mess and requires using experimental node features.Fortunately, we can hook into the jest resolution algorithm. In order to tackle our ongoing DRY dev tooling effort the
jest-resolver.js
file lives within bob. That means any project using bob can easily reference it in thejest.config.js
:In the future, I wanna experiment with whether we can move more of the shared configuration into bob itself.
4. Unify
bob build
command for single-package repo and mono repoPreviously,
bob build
did completely different things for single-package repos and mono repo. I altered the implementation to share as much logic as possible, which will make future improvements/refinements easier. We now also have an integration test suite that we can improve over time. It is now no longer necessary to runtsc
separately before runningbob build
.bob build
now takes care of everything. You just have to runbob build
. That is it.5. Alter the output folder structure of the build packages
Old structure
New structure
We no longer bundle the code into a single flat file.
We use the
.js
extension everywhere (we don't need .mjs or .cjs)The
package.json
contains{"type":"module"}
for instructing the Node.js resolution algorithm to treat all files within this folder as esm.The
cjs/package.json
contains{type:"commonjs"}
for instructing the Node.js resolution algorithm to treat all files within this sub folder as commonjs.Fortunately, we can use the same typings for TypeScripts ESM and CommonJS support.
6. Generate a new exports map that pleases TypeScript module resolution
In order to pass the TypeScript compiler options for ECMA modules, the exports map must be altered to include a
"typings"
key.TypeScript compiler options:
More information about the TypeScript Exports Map: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#package-json-exports-imports-and-self-referencing
Legit exports map example:
7. Add a new command for checking whether commonjs and ESM exports can be used
We have a few
test-esm.js
script that runs on CI for checking whether the ESM files can be imported.bob check
replaces this script and furthermore also checks theexports
map including CJS and ESM, by spawningnode
processes for each file.Upgrading
The following PRs are example upgrades:
Envelop: n1ru4l/envelop#1426 (comment)
GraphQL Yoga: dotansimha/graphql-yoga#1307
graphql-tools: ardatan/graphql-tools#4539
The current upgrade path:
bob bootstrap
"prebuild": "bob prepack"
from allpackage.json
filestsconfig.build.json
tsc && bob build
withbob build
resolver: 'bob-the-bundler/jest-resolver.js',
tojest.config.js
test-esm.js
script withbob check
on CI tasksPending TODOS:
Apollo folks did something similar in Fix ESM/CJS and deep imports apollographql/apollo-server#6606, might use this as inspiration.
Closes #48
Closes #39
Closes #47
Closes #71