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
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #23228
This commit is contained in:
Jack Hsu 2024-09-12 18:47:15 -04:00 committed by GitHub
parent 1924bc30b6
commit 7232b392ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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');