diff --git a/package.json b/package.json index 44e5d00..79f8019 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "prepack": "pnpm build && clean-pkg-json" }, "dependencies": { - "@esbuild-kit/core-utils": "^3.2.3", + "@esbuild-kit/core-utils": "^3.3.0", "get-tsconfig": "^4.7.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9417b5..000fdd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@esbuild-kit/core-utils': - specifier: ^3.2.3 - version: 3.2.3 + specifier: ^3.3.0 + version: 3.3.0 get-tsconfig: specifier: ^4.7.0 version: 4.7.0 @@ -91,8 +91,8 @@ packages: js-tokens: 4.0.0 dev: true - /@esbuild-kit/core-utils@3.2.3: - resolution: {integrity: sha512-daTXIDXv6lTpADQYTfY9BgHfL3HjVfY7xD8aOuPWtD1bJdqk9hAtHK5cErBcxcBtjFcfB0B2tftFtW01jTveKw==} + /@esbuild-kit/core-utils@3.3.0: + resolution: {integrity: sha512-jTtSvVpr5ygNXyPXf9IBbCrKQ0uckq6vWkcGfy1fEr9KjkKdnFn4kFAGjpqZDZim1wsTwh/Be+lhAUemEmxEYA==} dependencies: esbuild: 0.18.20 source-map-support: 0.5.21 diff --git a/src/loaders.ts b/src/loaders.ts index b9bff7e..64a2fed 100644 --- a/src/loaders.ts +++ b/src/loaders.ts @@ -1,6 +1,9 @@ +import type { MessagePort } from 'node:worker_threads'; import path from 'path'; import { pathToFileURL, fileURLToPath } from 'url'; -import type { ResolveFnOutput, ResolveHookContext, LoadHook } from 'module'; +import type { + ResolveFnOutput, ResolveHookContext, LoadHook, GlobalPreloadHook, +} from 'module'; import { transform, transformDynamicImport, @@ -31,6 +34,20 @@ type resolve = ( recursiveCall?: boolean, ) => MaybePromise; +/** + * Technically globalPreload is deprecated so it should be in loaders-deprecated + * but it shares a closure with the new load hook + */ +let mainThreadPort: MessagePort | undefined; +export const globalPreload: GlobalPreloadHook = ({ port }) => { + mainThreadPort = port; + return ` + const require = getBuiltin('module').createRequire(getBuiltin('process').cwd() + '/'); + require('@esbuild-kit/core-utils').installSourceMapSupport(port); + port.unref(); // Allows process to exit without waiting for port to close + `; +}; + const extensions = ['.js', '.json', '.ts', '.tsx', '.jsx'] as const; async function tryExtensions( @@ -223,6 +240,7 @@ export const load: LoadHook = async function ( const code = loaded.source.toString(); if ( + // Support named imports in JSON modules loaded.format === 'json' || tsExtensionsPattern.test(url) ) { @@ -236,7 +254,7 @@ export const load: LoadHook = async function ( return { format: 'module', - source: applySourceMap(transformed, url), + source: applySourceMap(transformed, url, mainThreadPort), }; } @@ -246,6 +264,7 @@ export const load: LoadHook = async function ( loaded.source = applySourceMap( dynamicImportTransformed, url, + mainThreadPort, ); } } diff --git a/tests/index.ts b/tests/index.ts index 7ae03c6..0aa06e9 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -11,6 +11,7 @@ const nodeVersions = [ '16', '17', '18', + '20', ] : [] ), diff --git a/tests/specs/typescript/tsconfig.ts b/tests/specs/typescript/tsconfig.ts index 2ae6e9c..eb5eeb9 100644 --- a/tests/specs/typescript/tsconfig.ts +++ b/tests/specs/typescript/tsconfig.ts @@ -1,3 +1,5 @@ +import path from 'path'; +import fs from 'fs/promises'; import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; import type { NodeApis } from '../../utils/node-with-loader.js'; @@ -37,6 +39,12 @@ export default testSuite(async ({ describe }, node: NodeApis) => { }, }); + await fs.symlink( + path.resolve('node_modules'), + path.join(fixture.path, 'node_modules'), + 'dir', + ); + onTestFinish(async () => await fixture.rm()); // Strict mode is not tested because ESM is strict by default @@ -71,6 +79,12 @@ export default testSuite(async ({ describe }, node: NodeApis) => { 'src/jsx.jsx': checkJsx, }); + await fs.symlink( + path.resolve('node_modules'), + path.join(fixture.path, 'node_modules'), + 'dir', + ); + onTestFinish(async () => await fixture.rm()); const jsxJs = await node.load('./src/jsx.jsx', {