Skip to content

Commit 67d0dc2

Browse files
Add TypeScript loader (#7)
1 parent 835506a commit 67d0dc2

File tree

9 files changed

+669
-0
lines changed

9 files changed

+669
-0
lines changed

https-loader/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"version": "0.1.0",
44
"description": "",
55
"type": "module",
6+
"exports": {
7+
".": "./loader.js",
8+
"./package.json": "./package.json"
9+
},
610
"scripts": {
711
"start": "npm test",
812
"test": "node --experimental-loader ./loader.js test.js"

typescript-loader/fixtures/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { sum, VERSION } from './utils.ts';
2+
3+
console.log('sum:', sum(3,4));
4+
console.log('VERSION:', VERSION);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './app.ts';
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { VERSION } from './vendor.js';
2+
3+
export function sum(a: number, b: number) { return a + b }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const VERSION = 42;

typescript-loader/loader.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// 💡 It's probably a good idea to put this loader near the end of the chain.
2+
3+
import path from 'node:path';
4+
5+
import { transform } from 'esbuild';
6+
7+
8+
const tsExts = new Set([
9+
'.tsx',
10+
'.ts',
11+
'.mts',
12+
'.cts',
13+
]);
14+
15+
export async function resolve(specifier, context, nextResolve) {
16+
const ext = path.extname(specifier);
17+
18+
if (!tsExts.has(ext)) { return nextResolve(specifier); } // File is not ts, so step aside
19+
20+
const { url } = await nextResolve(specifier); // This can be deduplicated but isn't for simplicity
21+
22+
return {
23+
format: 'typescript', // Provide a signal to `load`
24+
shortCircuit: true,
25+
url,
26+
};
27+
}
28+
29+
export async function load(url, context, nextLoad) {
30+
if (context.format !== 'typescript') { return nextLoad(url); }
31+
32+
const rawSource = '' + (await nextLoad(url, { ...context, format: 'module' })).source;
33+
34+
const { code: transpiledSource } = await transform(rawSource, {
35+
format: 'esm',
36+
loader: 'ts',
37+
sourcemap: 'inline',
38+
target: 'esnext',
39+
});
40+
41+
return {
42+
format: 'module',
43+
shortCircuit: true,
44+
source: transpiledSource,
45+
};
46+
}

0 commit comments

Comments
 (0)