oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
72.07k stars 2.58k forks source link

Failing to use a ts loader plugin #4519

Open niklasgrewe opened 10 months ago

niklasgrewe commented 10 months ago

What version of Bun is running?

0.8.1+16b4bf341acc0f4804f0b6bdf5298c180cd00366

What platform is your computer?

Darwin 22.6.0 arm64 arm

What steps can reproduce the bug?

create a minimal loader that returns static typescript:

import { plugin } from "bun";

plugin({
  name: "Test Loader",
  setup(build) {
    build.onResolve({ filter: /.*/, namespace: "test" }, (args) => ({
      path: args.path,
      namespace: "test",
    }));

    build.onLoad({ filter: /.*/, namespace: "test" }, async (args) => ({
      contents:
        `export function assert(b: boolean): void { if (!b) throw new Error("Assertion failed"); }`,
      loader: "ts",
    }));
  },
});

using it with the following script

import { assert } from "test:test.ts";

assert(false);

What is the expected behavior?

expected output:

error: Assertion failed

What do you see instead?

get the following error:

error: Expected ")" but found ":"
export function assert(b: boolean): void { if (!b) throw new Error("Assertion failed"); }
                        ^
test:test.ts:1:25 24

error: Expected "{" but found "boolean"
export function assert(b: boolean): void { if (!b) throw new Error("Assertion failed"); }
                          ^
test:test.ts:1:27 26

error: Unexpected )
export function assert(b: boolean): void { if (!b) throw new Error("Assertion failed"); }
                                 ^
test:test.ts:1:34 33

Additional information

No response

lucas-jones commented 10 months ago

I'm no expert, just happen to be wanting to do the same thing.

https://bun.sh/docs/api/transpiler

This works for me

import { plugin, Transpiler } from "bun";

plugin({
    name: "Test",
    async setup(build) {
        const { readFileSync } = await import("fs");

        const transpiler = new Transpiler({ loader: "ts" });

        build.onLoad({ filter: /\.(ts)$/ }, (args) => {

            let typescript = readFileSync(args.path, "utf8");
            const javascript = transpiler.transformSync(typescript);

            return {
                contents: javascript
            };
        });
    },
});
vjpr commented 5 months ago

I noticed a temperamental regression here too. I was using loader: 'tsx' in a plugin. It used to work. But now it would like work once, and then stop working.

https://bun.sh/docs/runtime/plugins#loaders

Note that the returned object has a loader property. This tells Bun which of its internal loaders should be used to handle the result.

This seems to be broken.

edemaine commented 3 weeks ago

I see the same issue; our Civet plugin doesn't handle JSX with loader: 'tsx'. Running the Transpiler manually seems like a reasonable workaround, but I think you also need to give it the tsconfig manually, which is annoying (in a plugin context, where should we search for it?). I also can't seem to get it to emit the implicit import for JSX content; see https://github.com/oven-sh/bun/discussions/8335#discussioncomment-9839937

Update: loader: 'tsx' does seem to work for TypeScript code, whereas loader: 'js' errors. But loader: 'tsx' does not support JSX notation.