From 7232b392ba26ff74130170a5bec229d9ccef7005 Mon Sep 17 00:00:00 2001 From: Jack Hsu Date: Thu, 12 Sep 2024 18:47:15 -0400 Subject: [PATCH] fix(js): set compilerOptions correctly when loading .ts that targets ESM (#27862) When we load `.ts` files and the closest `package.json` specifies `"type": "module"`, then the file may error upon loading. This happens because we're not setting `compilerOptions` correctly when registering `ts-node/esm`-- in fact there is no way to pass options through this hook. This PR sets defaults on `TS_NODE_COMPILER_OPTIONS` such that the `module` and `moduleResolution` are correct values for ESM. It also works for CJS since both `module` and `moduleResolution` check the closest `package.json` to determine the format. ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes #23228 --- packages/nx/src/plugins/js/utils/register.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/nx/src/plugins/js/utils/register.ts b/packages/nx/src/plugins/js/utils/register.ts index 747b8b90341b5..ce4836d0d23ba 100644 --- a/packages/nx/src/plugins/js/utils/register.ts +++ b/packages/nx/src/plugins/js/utils/register.ts @@ -91,6 +91,13 @@ export function registerTsProject( // Based on limited testing, it doesn't seem to matter if we register it multiple times, but just in // case let's keep a flag to prevent it. if (!isTsEsmLoaderRegistered) { + // We need a way to ensure that `.ts` files are treated as ESM not CJS. + // Since there is no way to pass compilerOptions like we do with the programmatic API, we should default + // the environment variable that ts-node checks. + process.env.TS_NODE_COMPILER_OPTIONS ??= JSON.stringify({ + moduleResolution: 'nodenext', + module: 'nodenext', + }); const module = require('node:module'); if (module.register && packageIsInstalled('ts-node/esm')) { const url = require('node:url');