Skip to content

Commit d82d7f0

Browse files
refactor: esm directory (#8)
1 parent 4b1f03c commit d82d7f0

File tree

8 files changed

+114
-104
lines changed

8 files changed

+114
-104
lines changed

src/esm/api/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { register } from './register.js';

src/esm/register.ts renamed to src/esm/api/register.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import module from 'node:module';
2-
import { installSourceMapSupport } from '../source-map.js';
2+
import { installSourceMapSupport } from '../../source-map.js';
33

4-
export const registerLoader = () => {
4+
export const register = () => {
55
installSourceMapSupport();
66

77
module.register(

src/esm/hook/index.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { GlobalPreloadHook, InitializeHook } from 'module';
2+
3+
export const initialize: InitializeHook = async (data) => {
4+
if (!data) {
5+
throw new Error('tsx must be loaded with --import instead of --loader\nThe --loader flag was deprecated in Node v20.6.0 and v18.19.0');
6+
}
7+
};
8+
9+
/**
10+
* Technically globalPreload is deprecated so it should be in loaders-deprecated
11+
* but it shares a closure with the new load hook
12+
*/
13+
export const globalPreload: GlobalPreloadHook = () => `
14+
const require = getBuiltin('module').createRequire("${import.meta.url}");
15+
require('../source-map.cjs').installSourceMapSupport();
16+
`;
17+
18+
export { load } from './load.js';
19+
export { resolve } from './resolve.js';

src/esm/hook/load.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { fileURLToPath } from 'url';
2+
import type { LoadHook } from 'module';
3+
import type { TransformOptions } from 'esbuild';
4+
import { transform } from '../../utils/transform/index.js';
5+
import { transformDynamicImport } from '../../utils/transform/transform-dynamic-import.js';
6+
import { installSourceMapSupport } from '../../source-map.js';
7+
import { isFeatureSupported, importAttributes } from '../../utils/node-features.js';
8+
import { parent } from '../../utils/ipc/client.js';
9+
import {
10+
fileMatcher,
11+
tsExtensionsPattern,
12+
isJsonPattern,
13+
} from './utils.js';
14+
15+
const applySourceMap = installSourceMapSupport();
16+
17+
const contextAttributesProperty = (
18+
isFeatureSupported(importAttributes)
19+
? 'importAttributes'
20+
: 'importAssertions'
21+
);
22+
23+
export const load: LoadHook = async (
24+
url,
25+
context,
26+
defaultLoad,
27+
) => {
28+
/*
29+
Filter out node:*
30+
Maybe only handle files that start with file://
31+
*/
32+
if (parent.send) {
33+
parent.send({
34+
type: 'dependency',
35+
path: url,
36+
});
37+
}
38+
39+
if (isJsonPattern.test(url)) {
40+
if (!context[contextAttributesProperty]) {
41+
context[contextAttributesProperty] = {};
42+
}
43+
44+
context[contextAttributesProperty]!.type = 'json';
45+
}
46+
47+
const loaded = await defaultLoad(url, context);
48+
49+
// CommonJS and Internal modules (e.g. node:*)
50+
if (!loaded.source) {
51+
return loaded;
52+
}
53+
54+
const filePath = url.startsWith('file://') ? fileURLToPath(url) : url;
55+
const code = loaded.source.toString();
56+
57+
if (
58+
// Support named imports in JSON modules
59+
loaded.format === 'json'
60+
|| tsExtensionsPattern.test(url)
61+
) {
62+
const transformed = await transform(
63+
code,
64+
filePath,
65+
{
66+
tsconfigRaw: fileMatcher?.(filePath) as TransformOptions['tsconfigRaw'],
67+
},
68+
);
69+
70+
return {
71+
format: 'module',
72+
source: applySourceMap(transformed),
73+
};
74+
}
75+
76+
if (loaded.format === 'module') {
77+
const dynamicImportTransformed = transformDynamicImport(filePath, code);
78+
if (dynamicImportTransformed) {
79+
loaded.source = applySourceMap(dynamicImportTransformed);
80+
}
81+
}
82+
83+
return loaded;
84+
};
File renamed without changes.

src/esm/loaders.ts renamed to src/esm/hook/resolve.ts

+5-99
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,20 @@
11
import path from 'path';
2-
import { pathToFileURL, fileURLToPath } from 'url';
2+
import { pathToFileURL } from 'url';
33
import type {
4-
ResolveFnOutput, ResolveHookContext, LoadHook, GlobalPreloadHook, InitializeHook,
4+
ResolveFnOutput, ResolveHookContext,
55
} from 'module';
6-
import type { TransformOptions } from 'esbuild';
7-
import { transform } from '../utils/transform/index.js';
8-
import { transformDynamicImport } from '../utils/transform/transform-dynamic-import.js';
9-
import { resolveTsPath } from '../utils/resolve-ts-path.js';
10-
import { installSourceMapSupport } from '../source-map.js';
11-
import { isFeatureSupported, importAttributes } from '../utils/node-features.js';
12-
import { parent } from '../utils/ipc/client.js';
13-
import type { NodeError } from '../types.js';
14-
import { isRelativePathPattern } from '../utils/is-relative-path-pattern.js';
6+
import { resolveTsPath } from '../../utils/resolve-ts-path.js';
7+
import type { NodeError } from '../../types.js';
8+
import { isRelativePathPattern } from '../../utils/is-relative-path-pattern.js';
159
import {
1610
tsconfigPathsMatcher,
17-
fileMatcher,
1811
tsExtensionsPattern,
19-
isJsonPattern,
2012
getFormatFromFileUrl,
2113
fileProtocol,
2214
allowJs,
2315
type MaybePromise,
2416
} from './utils.js';
2517

26-
const applySourceMap = installSourceMapSupport();
27-
2818
const isDirectoryPattern = /\/(?:$|\?)/;
2919

3020
type NextResolve = (
@@ -39,21 +29,6 @@ type resolve = (
3929
recursiveCall?: boolean,
4030
) => MaybePromise<ResolveFnOutput>;
4131

42-
export const initialize: InitializeHook = async (data) => {
43-
if (!data) {
44-
throw new Error('tsx must be loaded with --import instead of --loader\nThe --loader flag was deprecated in Node v20.6.0 and v18.19.0');
45-
}
46-
};
47-
48-
/**
49-
* Technically globalPreload is deprecated so it should be in loaders-deprecated
50-
* but it shares a closure with the new load hook
51-
*/
52-
export const globalPreload: GlobalPreloadHook = () => `
53-
const require = getBuiltin('module').createRequire("${import.meta.url}");
54-
require('../source-map.cjs').installSourceMapSupport();
55-
`;
56-
5732
const resolveExplicitPath = async (
5833
defaultResolve: NextResolve,
5934
specifier: string,
@@ -218,72 +193,3 @@ export const resolve: resolve = async (
218193
throw error;
219194
}
220195
};
221-
222-
const contextAttributesProperty = (
223-
isFeatureSupported(importAttributes)
224-
? 'importAttributes'
225-
: 'importAssertions'
226-
);
227-
228-
export const load: LoadHook = async (
229-
url,
230-
context,
231-
defaultLoad,
232-
) => {
233-
/*
234-
Filter out node:*
235-
Maybe only handle files that start with file://
236-
*/
237-
if (parent.send) {
238-
parent.send({
239-
type: 'dependency',
240-
path: url,
241-
});
242-
}
243-
244-
if (isJsonPattern.test(url)) {
245-
if (!context[contextAttributesProperty]) {
246-
context[contextAttributesProperty] = {};
247-
}
248-
249-
context[contextAttributesProperty]!.type = 'json';
250-
}
251-
252-
const loaded = await defaultLoad(url, context);
253-
254-
// CommonJS and Internal modules (e.g. node:*)
255-
if (!loaded.source) {
256-
return loaded;
257-
}
258-
259-
const filePath = url.startsWith('file://') ? fileURLToPath(url) : url;
260-
const code = loaded.source.toString();
261-
262-
if (
263-
// Support named imports in JSON modules
264-
loaded.format === 'json'
265-
|| tsExtensionsPattern.test(url)
266-
) {
267-
const transformed = await transform(
268-
code,
269-
filePath,
270-
{
271-
tsconfigRaw: fileMatcher?.(filePath) as TransformOptions['tsconfigRaw'],
272-
},
273-
);
274-
275-
return {
276-
format: 'module',
277-
source: applySourceMap(transformed),
278-
};
279-
}
280-
281-
if (loaded.format === 'module') {
282-
const dynamicImportTransformed = transformDynamicImport(filePath, code);
283-
if (dynamicImportTransformed) {
284-
loaded.source = applySourceMap(dynamicImportTransformed);
285-
}
286-
}
287-
288-
return loaded;
289-
};
File renamed without changes.

src/esm/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { isMainThread } from 'node:worker_threads';
22
import { isFeatureSupported, moduleRegister } from '../utils/node-features.js';
3-
import { registerLoader } from './register.js';
3+
import { register } from './api/index.js';
44

55
// Loaded via --import flag
66
if (
77
isFeatureSupported(moduleRegister)
88
&& isMainThread
99
) {
10-
registerLoader();
10+
register();
1111
}
1212

13-
export * from './loaders.js';
13+
export * from './hook/index.js';

0 commit comments

Comments
 (0)