Skip to content

Instantly share code, notes, and snippets.

@tobiashm
Last active November 17, 2023 13:39
Show Gist options
  • Save tobiashm/73bee40564c0baa7271378b691f2dd29 to your computer and use it in GitHub Desktop.
Save tobiashm/73bee40564c0baa7271378b691f2dd29 to your computer and use it in GitHub Desktop.
TypeScript transpiler for Node.js

Minimal TypeScript loader for Node.js

In newer versions of Node.js you can register your own loader and resolvers. This is an example of automatically transpiling .ts files.

Usage:

> node --import ./ts-loader.mjs ./my-app.ts
import { transform } from 'esbuild';
import { existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
const isRelativeJs = /^\.{1,2}\/.+\.js$/;
/**
* In TypeScript you can use .js extension in import statements, even though the actual file uses .ts
* @see https://nodejs.org/api/module.html#resolvespecifier-context-nextresolve
* @param {string} specifier
* @param {Object} context
* @param {Function} nextResolve
*/
export async function resolve(specifier, context, nextResolve) {
if (isRelativeJs.test(specifier) && !existsSync(fileURLToPath(new URL(specifier, context.parentURL)))) {
return nextResolve(specifier.replace(/\.js$/, '.ts'), context);
}
return nextResolve(specifier, context);
}
/**
* Transpile .ts files using esbuild.
* @see https://nodejs.org/api/module.html#loadurl-context-nextload
* @param {string} url
* @param {Object} context
* @param {Function} nextLoad
*/
export async function load(url, context, nextLoad) {
if (!url.endsWith('.ts')) return nextLoad(url, context);
const { source, format } = await nextLoad(url, { ...context, format: 'module' });
const { code } = await transform(source, { loader: 'ts' });
return { source: code, format };
}
import { register } from 'node:module';
register(new URL('ts-loader-hooks.mjs', import.meta.url));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment