Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 12, 2025

Description

Fixes #17878

es-module-lexer expects valid JavaScript but was receiving raw TypeScript. When parsing TypeScript enums, it succeeds without throwing but returns hasModuleSyntax: false, causing Vite to incorrectly apply CommonJS interop to ESM code.

Before:

// dep/index.ts
export enum Status { GREEN = 'GREEN' }

// main.ts
import { Status } from 'dep'  // Runtime error: no export named 'default'

After:
TypeScript files are transformed to JavaScript before parsing, correctly identifying ESM syntax.

Changes

  • Check file extension in extractExportsData() before calling es-module-lexer
  • Transform TypeScript files (.ts, .tsx, .mts, .cts) with transformWithOxc before parsing
  • Non-TypeScript files maintain existing try-catch fallback behavior
  • Added test case with TypeScript enum dependency to prevent regression
  • Disabled erasableSyntaxOnly in playground/tsconfig.json to allow TypeScript enum usage in tests
Original prompt

This section details on the original issue you should resolve

<issue_title>"vite" rewrites "named import" of typescript enums as "default import" and breaks app</issue_title>
<issue_description>### Describe the bug

I try to use a named import (import { Status } from 'ts-enum/status.ts'), I expect the import to work (it works with yarn build), but vite rewrites it as a "default import" (cf below) which is wrong (cf error).

vite import rewrite:

import __vite__cjsImport0_tsEnum_status from "https://github.com/node_modules/.vite/deps/ts-enum_status.js?v=af7bba1f"; const Status = __vite__cjsImport0_tsEnum_status["Status"];

browser error (from dev console, both Firefox and Chrome):

main.ts:1 Uncaught SyntaxError: The requested module 'https://github.com/node_modules/.vite/deps/ts-enum_status.js?v=d7be5188' does not provide an export named 'default' (at main.ts:1:1)

Issues that might be related: #17727 ; #11231 ; #14018 ; #11783 ; #15434 ; #17619 ; #16742 ; #16293 ; #15620

Reproduction

https://gist.github.com/superboum/1d59a67290a3224d83fbc5cb7f97fb03

Steps to reproduce

Create a simple typescript module:

mkdir ts-enum
cd ts-enum
yarn init --yes
echo "export enum Status { GREEN = 'GREEN' }" > status.ts
# :warning: The issue seems directly related to enums. If we replace the enum by a struct, the error does not occur:
# echo 'export let Status = { "GREEN": "GREEN" }' > status.ts
cd ..

Create a vite project with the typescript template:

yarn create vite vite-bug --template vanilla-ts
cd vite-bug

Replace yarn PnP module resolution with the traditional node-modules

yarn config set nodeLinker node-modules

Now add our dependency (problem also exists if the dependency is pulled from git or a npm registry):

yarn add ts-enum@file:./../ts-enum
yarn install

Write the most straightforward javascript that will trigger the bug:

echo "import { Status } from 'ts-enum/status'" > src/main.ts
echo 'console.log(Status.GREEN)' >> src/main.ts

Building works perfectly, you can try with:

yarn build
cd dist ; python -m http.server
# go to http://localhost:8000 ; open the dev console ; see no error, only a `GREEN` console log. It works!

But vite breaks our app:

yarn dev
# go to http://localhost:5173 ; open the dev console ; see an import error

System Info

  System:
    OS: Linux 6.6 NixOS 24.05 (Uakari) 24.05 (Uakari)
    CPU: (4) x64 Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
    Memory: 9.71 GB / 15.53 GB
    Container: Yes
    Shell: 5.2.26 - /nix/store/pg0zqlym7y3cd8631b3x6cghxcmjl8xa-bash-interactive-5.2p26/bin/bash
  Binaries:
    Node: 18.20.4 - /run/current-system/sw/bin/node
    Yarn: 4.2.2 - /nix/store/wvalqmxg0275mf7alwyl0x0fvjbgcb8j-yarn-berry-4.2.2/bin/yarn
    npm: 10.7.0 - /run/current-system/sw/bin/npm
  Browsers:
    Chromium: 127.0.6533.88
    Firefox: 129.0
  npmPackages:
    vite: ^5.4.0 => 5.4.0

Used Package Manager

yarn

Logs

vite and vite build do not produce any error.
But loading the website in a browser with vite will produce this error:

main.ts:1 Uncaught SyntaxError: The requested module 'https://github.com/node_modules/.vite/deps/ts-enum_status.js?v=d7be5188' does not provide an export named 'default' (at main.ts:1:1)

Still, the output of vite --debug:

Reveal output
[nix-shell:/tmp/vite-bug]$ yarn run vite --debug
  vite:config no config file found. +0ms
  vite:config using resolved config: {
  vite:config   root: 'https://github.com/tmp/vite-bug',
  vite:config   base: 'https://github.com/',
  vite:config   mode: 'development',
  vite:config   configFile: undefined,
  vite:config   logLevel: undefined,
  vite:config   clearScreen: undefined,
  vite:config   optimizeDeps: {
  vite:config     holdUntilCrawlEnd: true,
  vite:config     force: undefined,
  vite:config     esbuildOptions: { preserveSymlinks: false }
  vite:config   },
  vite:config   server: {
  vite:config     preTransformRequests: true,
  vite:config     host: undefined,
  vite:config     sourcemapIgnoreList: [Function: isInNodeModules$1],
  vite:config     middlewareMode: false,
  vite:config     fs: {
  vite:config       strict: true,
  vite:config       allow: [Array],
  vite:config       deny: [Array],
  vite:config       cachedChecks: undefined
  vite:config     }
  vite:config   },
  vite:config   configFileDependencies: [],
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     optimizeDeps: { force: undefined },
  vi...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes vitejs/vite#17878

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for you](https://github.com/vitejs/vite/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

…fore parsing

Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix Vite rewriting named imports of TypeScript enums fix(optimizer): transform TypeScript files before parsing with es-module-lexer Dec 12, 2025
Copilot AI requested a review from sapphi-red December 12, 2025 06:32
@sapphi-red
Copy link
Member

@copilot disable erasableSyntaxOnly in playground

Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 12, 2025

@copilot disable erasableSyntaxOnly in playground

Done in 5e89c00. Changed erasableSyntaxOnly from true to false in playground/tsconfig.json to allow TypeScript enum usage in the test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"vite" rewrites "named import" of typescript enums as "default import" and breaks app

2 participants