You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running `ts-node --esm`, a child process is spawned with the
`child-loader.mjs` loader, `dist/child/child-entrypoint.js` main,
and `argv[2]` set to the base64 encoded compressed configuration
payload.
`child-loader.mjs` imports and re-exports the functions defined
in `src/child/child-loader.ts`. These are initially set to empty
loader hooks which call the next hook in line until they are
defined by calling `lateBindHooks()`.
`child-entrypoint.ts` reads the config payload from argv, and
bootstraps the registration process, which then calls
`lateBindHooks()`.
Presumably, the reason for this hand-off is because `--loader`
hooks do not have access to `process.argv`. Unfortunately, in
node 20, they don't have access to anything else, either, so
calling `lateBindHooks` is effectively a no-op; the
`child-loader.ts` where the hooks end up getting bound is not the
same one that is being used as the actual loader.
To solve this, the following changes are added:
1. An `isLoaderThread` flag is added to the BootstrapState. If
this flag is set, then no further processing is performed
beyond binding the loader hooks.
2. `callInChild` adds the config payload to _both_ the argv and
the loader URL as a query param.
3. In the `child-loader.mjs` loader, only on node v20 and higher,
the config payload is read from `import.meta.url`, and
`bootstrap` is called, setting the `isLoaderThread` flag.
I'm not super enthusiastic about this implementation. It
definitely feels like there's a refactoring opportunity to clean
it up, as it adds some copypasta between child-entrypoint.ts and
child-loader.mjs. A further improvement would be to remove the
late-binding handoff complexity entirely, and _always_ pass the
config payload on the loader URL rather than on process.argv.
0 commit comments