diff --git a/README.md b/README.md index 0a22d289d..2614074d1 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,19 @@ Stack traces are preserved, by replacing removed types with white spaces. ```javascript const amaro = require('amaro'); -const { code } = amaro.transformSync("const foo: string = 'bar';"); +const { code } = amaro.transformSync("const foo: string = 'bar';", { mode: "strip-only" }); console.log(code); // "const foo = 'bar';" ``` +### Loader + +It is possible to user Amaro as a loader for TypeScript files. +This allows the local Amaro version to override the Amaro version used by Node.js. + +```bash +node --experimental-strip-types --import="amaro/register" script.ts +``` + ### How to update SWC To update the SWC version, run: diff --git a/esbuild.config.js b/esbuild.config.js new file mode 100644 index 000000000..72fe6f71a --- /dev/null +++ b/esbuild.config.js @@ -0,0 +1,18 @@ +const { copy } = require("esbuild-plugin-copy"); +const esbuild = require("esbuild"); + +esbuild.build({ + entryPoints: ["src/index.ts"], + bundle: true, + platform: "node", + target: "node20", + outdir: "dist", + plugins: [ + copy({ + assets: { + from: ["./src/register/register.mjs"], + to: ["."], + }, + }), + ], +}); diff --git a/package.json b/package.json index f0090da30..7c77a9ee4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "ci:fix": "biome check --write", "prepack": "npm run build", "postpack": "npm run clean", - "build": "esbuild --bundle --platform=node --target=node18 --outdir=dist src/index.ts", + "build": "node esbuild.config.js", "typecheck": "tsc --noEmit", "test": "node --test --experimental-test-snapshots \"**/*.test.js\"", "test:regenerate": "node --test --experimental-test-snapshots --test-update-snapshots \"**/*.test.js\"" @@ -30,11 +30,13 @@ "@biomejs/biome": "1.8.3", "@types/node": "^20.14.11", "esbuild": "^0.23.0", + "esbuild-plugin-copy": "^2.1.1", "rimraf": "^6.0.1", "typescript": "^5.5.3" }, - "files": [ - "dist", - "LICENSE.md" - ] + "exports": { + ".": "./dist/index.js", + "./register": "./dist/register.mjs" + }, + "files": ["dist", "LICENSE.md"] } diff --git a/src/loader.ts b/src/loader.ts index 78b07b981..d0ccdd918 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -1,14 +1,25 @@ -import swc from "../lib/wasm.js"; -import type { LoadHook } from "node:module"; -import { readFile } from "node:fs/promises"; +import type { LoadFnOutput, LoadHookContext } from "node:module"; +import { transformSync } from "./index.ts"; -export const load: LoadHook = async (source, context, nextLoad) => { - if (context.format?.includes("typescript")) { - const data = await readFile(source, "utf8"); +type NextLoad = ( + url: string, + context?: LoadHookContext, +) => LoadFnOutput | Promise; + +export async function load( + url: string, + context: LoadHookContext, + nextLoad: NextLoad, +) { + const { format } = context; + if (format.includes("typescript")) { + const { source = "" } = await nextLoad(url, context); + const { code } = transformSync(source.toString(), { mode: "strip-only" }); return { - source: swc.transformSync(data).code, - shortCircuit: true, // Skips bundled transpilation + format: format.replace("-typescript", ""), + source: code, + shortCircuit: true, }; } - return { source: await nextLoad(source, context) }; -}; + return { source: await nextLoad(url, context) }; +} diff --git a/src/register/register.mjs b/src/register/register.mjs new file mode 100644 index 000000000..39e7bce12 --- /dev/null +++ b/src/register/register.mjs @@ -0,0 +1,3 @@ +import { register } from "node:module"; + +register("./index.js", import.meta.url); diff --git a/test/fixtures/enum.ts b/test/fixtures/enum.ts index 0a5d0414c..c510a608e 100644 --- a/test/fixtures/enum.ts +++ b/test/fixtures/enum.ts @@ -1,4 +1,4 @@ enum Foo { - A = "Hello, TypeScript!" + A = "Hello, TypeScript!", } console.log(Foo.A); diff --git a/test/loader.test.js b/test/loader.test.js index f6d0e68c6..2ee276981 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -6,7 +6,7 @@ test("should work as a loader", async () => { const result = await spawnPromisified(process.execPath, [ "--experimental-strip-types", "--no-warnings", - "--import=./dist/index.js", + "--import=./dist/register.mjs", fixturesPath("hello.ts"), ]); @@ -19,11 +19,11 @@ test("should work with enums", async () => { const result = await spawnPromisified(process.execPath, [ "--experimental-strip-types", "--no-warnings", - "--import=./dist/index.js", + "--import=./dist/register.mjs", fixturesPath("enum.ts"), ]); - strictEqual(result.stderr, ""); - match(result.stdout, /Hello, TypeScript!/); - strictEqual(result.code, 0); + strictEqual(result.stdout, ""); + match(result.stderr, /TypeScript enum is not supported in strip-only mode/); + strictEqual(result.code, 1); });