From 92c3ce36369e923f74ab3a2d801ae3c55b7c6a5a Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 5 May 2023 21:37:04 -0700 Subject: [PATCH] fix: Add globalPreload to ts-node/esm for node 20 As of node v20, loader hooks are executed in a separate isolated thread environment. As a result, they are unable to register the `require.extensions` hooks in a way that would (in other node versions) make both CJS and ESM work as expected. By adding a `globalPreload` method, which *does* execute in the main script environment (but with very limited capabilities), these hooks can be attached properly, and `--loader=ts-node/esm` will once again make both cjs and esm typescript programs work properly. --- esm.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/esm.mjs b/esm.mjs index 0843cf349..e6f205758 100644 --- a/esm.mjs +++ b/esm.mjs @@ -6,3 +6,13 @@ const require = createRequire(fileURLToPath(import.meta.url)); const esm = require('./dist/esm'); export const { resolve, load, getFormat, transformSource } = esm.registerAndCreateEsmHooks(); + +// Affordance for node 20, where load() happens in an isolated thread +export const globalPreload = () => { + const self = fileURLToPath(import.meta.url); + return ` +const { createRequire } = getBuiltin('module'); +const require = createRequire(${JSON.stringify(self)}); +require('./dist/esm').registerAndCreateEsmHooks(); +`; +};