mirror of
https://github.com/oven-sh/bun
synced 2026-02-11 03:18:53 +00:00
## Summary Fixes #12548 - TypeScript syntax doesn't work in BunPlugin when using `loader: 'ts'` ## The Problem When creating a virtual module with `build.module()` and specifying `loader: 'ts'`, TypeScript syntax like `import { type TSchema }` would fail to parse with errors like: ``` error: Expected "}" but found "TSchema" error: Expected "from" but found "}" ``` The same code worked fine when using `loader: 'tsx'`, indicating the TypeScript parser wasn't being configured correctly for `.ts` files. ## Root Cause The bug was caused by an enum value mismatch between C++ and Zig: ### Before (Incorrect) - **C++ (`headers-handwritten.h`)**: `jsx=0, js=1, ts=2, tsx=3, ...` - **Zig API (`api/schema.zig`)**: `jsx=1, js=2, ts=3, tsx=4, ...` - **Zig Internal (`options.zig`)**: `jsx=0, js=1, ts=2, tsx=3, ...` When a plugin returned `loader: 'ts'`, the C++ code correctly parsed the string "ts" and set `BunLoaderTypeTS=2`. However, when this value was passed to Zig's `Bun__transpileVirtualModule` function (which expects `api.Loader`), the value `2` was interpreted as `api.Loader.js` instead of `api.Loader.ts`, causing the TypeScript parser to not be enabled. ### Design Context The codebase has two loader enum systems by design: - **`api.Loader`**: External API interface used for C++/Zig communication - **`options.Loader`**: Internal representation used within Zig The conversion between them happens via `options.Loader.fromAPI()` and `.toAPI()` functions. The C++ layer should use `api.Loader` values since that's what the interface functions expect. ## The Fix 1. **Aligned enum values**: Updated the `BunLoaderType` constants in `headers-handwritten.h` to match the values in `api/schema.zig`, ensuring C++ and Zig agree on the enum values 2. **Removed unnecessary assertion**: Removed the assertion that `plugin_runner` must be non-null for virtual modules, as it's not actually required for modules created via `build.module()` 3. **Added regression test**: Created comprehensive test in `test/regression/issue/12548.test.ts` that verifies TypeScript syntax works correctly with the `'ts'` loader ## Testing ### New Tests Pass - ✅ `test/regression/issue/12548.test.ts` - 2 tests verifying TypeScript type imports work with `'ts'` loader ### Existing Tests Still Pass - ✅ `test/js/bun/plugin/plugins.test.ts` - 28 pass - ✅ `test/bundler/bundler_plugin.test.ts` - 52 pass - ✅ `test/bundler/bundler_loader.test.ts` - 27 pass - ✅ `test/bundler/esbuild/loader.test.ts` - 10 pass - ✅ `test/bundler/bundler_plugin_chain.test.ts` - 13 pass ### Manual Verification ```javascript // This now works correctly with loader: 'ts' Bun.plugin({ setup(build) { build.module('hi', () => ({ contents: "import { type TSchema } from '@sinclair/typebox'", loader: 'ts', // ✅ Works now (previously failed) })) }, }) ``` 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>