Skip to content

Commit

Permalink
Build dual ESM/CJS packages; move some exports to deep imports (#6580)
Browse files Browse the repository at this point in the history
* Revert "Inline usage reporting protobuf into main package (#6515)"

This reverts commit 0b58585.

This leaves the fix of adding cors and body-parser to server's deps and
leaves the removal of a TODO(AS4) about this.

The build process for this package is completely different from a normal
TS package, so keeping it together seems best. This seems like it'll
make setting up ESM builds easier.

* plugins: Use dynamic import instead of manual intermediate functions

We want to avoid loading usage reporting protobuf until as late as
possible. Previously we had a specific file src/plugins/index.ts full of
little wrapper functions that call `require`. Now we use dynamic
`import` (which is compiled to CJS as `require` by tsc) instead.

We use "exports" in package.json to let you do deep imports from
particular files (only). Note that this still only supports CJS!

* Generate ESM and CJS files; change to deep-import API

The overall approach is to ask tsc to build two different projects for
package/server, one with CJS output and one with ESM, outputting into
two subdirectories of packages/server/dist. package.json teaches Node
how to find various entry points with both ESM and CJS.

To make the ESM version work, this equires making all "file imports"
(not `import type` or imports of packages) end with `.js`. Instead of
using `__dirname` we now update the version number in a normal TS file
before building.

We have to do some weird stuff with how we import the proto package
since it is not ESM-y enough due to the weird index.js in it. (Maybe we
should just fix our protobuf port to drop long support directly so we
can have a nicer index.js which is analyzed properly?)

We update the actual API so that `startStandaloneServer` must be
imported from `@apollo/server/standalone` (and thus express can be
tree-shaken if you don't use the standalone server) and so that the
various plugins are imported from `@apollo/server/plugin/usageReporting`
etc (and so you don't have to load protobuf stuff if you don't use it).

* scripts to subdir

* Make @apollo/usage-reporting-protobuf dual CJS/ESM too

This mostly involved running pbjs a second time to generate ESM. A few
tweaks were made to our fork `@apollo/protobufjs`:
- Long support is just turned off by default, so we don't need the
  wrapper index.* files that just turn it off
- The import line in generated code no longer includes `* as` since that
  didn't quite work in practice (it imported an object with a 'default'
  key on it)
- The `@apollo/protobufjs` package.json uses `exports` to show where
  `/minimal` is
  • Loading branch information
glasser committed Jun 16, 2022
1 parent dae6dda commit 3d4cdd9
Show file tree
Hide file tree
Showing 74 changed files with 11,253 additions and 1,541 deletions.
8 changes: 8 additions & 0 deletions .circleci/config.yml
Expand Up @@ -44,6 +44,13 @@ jobs:
- store_test_results:
path: junit.xml

Smoke test built package:
docker:
- image: cimg/base:stable
steps:
- setup-node
- run: npm run test:smoke

Prettier:
docker:
- image: cimg/base:stable
Expand Down Expand Up @@ -90,3 +97,4 @@ workflows:
- "Check for FIXM\x45"
- Prettier
- Spell check
- Smoke test built package
1 change: 1 addition & 0 deletions .codesandbox/ci.json
Expand Up @@ -2,6 +2,7 @@
"buildCommand": "compile",
"installCommand": "install-with-npm-8.5",
"packages": [
"packages/usage-reporting-protobuf",
"packages/server"
],
"sandboxes": ["apollo-server-typescript-3opde","apollo-server"],
Expand Down
4 changes: 4 additions & 0 deletions cspell-dict.txt
Expand Up @@ -102,6 +102,7 @@ microrouter
middlewares
Middlewares
millis
mktemp
monodocs
mygraph
myvariant
Expand All @@ -119,6 +120,8 @@ pbts
pook
Pook
pooks
postcompile
precompile
preflighted
preflighting
prepended
Expand All @@ -135,6 +138,7 @@ retryable
revalidates
roadmap
ROADMAP
rollup
runtimes
safelist
safelisted
Expand Down
10 changes: 8 additions & 2 deletions jest.config.base.js
@@ -1,6 +1,6 @@
const { defaults } = require('jest-config');
import { defaults } from 'jest-config';

module.exports = {
export default {
testEnvironment: 'node',
setupFilesAfterEnv: ['<rootDir>/../../jest.setup.js'],
preset: 'ts-jest',
Expand All @@ -9,10 +9,16 @@ module.exports = {
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'],
clearMocks: true,
extensionsToTreatAsEsm: ['.ts'],
globals: {
'ts-jest': {
useESM: true,
tsconfig: '<rootDir>/src/__tests__/tsconfig.json',
diagnostics: false,
},
},
moduleNameMapper: {
// Ignore '.js' at the end of imports; part of ESM support.
'^(\\.{1,2}/.*)\\.js$': '$1',
},
};

0 comments on commit 3d4cdd9

Please sign in to comment.