Skip to content

[plugin-react] restoreJSX cannot handle typescript inputs outside of project root (usually from monorepo) #18

@hyrious

Description

@hyrious

Describe the bug

https://github.com/vitejs/vite/blob/dc323a0a230f57de0d102782dd4e673fb6b2d06c/packages/plugin-react/src/jsx-runtime/restore-jsx.ts#L68

The restoreJSX function makes a simple assumption that all its inputs are valid jsx file because usually it is going to transform code from thrid-party libraries which only includes js code. However, it is also possible to see user source code from monorepo, where using React.createElement() in .ts files will throw a parsing error because babel was not configured to parse typescript.

Reproduction

https://stackblitz.com/edit/vitejs-plugin-react-restorejsx-bug?file=lib/index.ts

System Info

System:
    OS: macOS 12.3.1
    CPU: (8) x64 Intel(R) Core(TM) i5-8257U CPU @ 1.40GHz
    Memory: 21.99 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.15.0 - /usr/local/bin/node
    Yarn: 1.22.18 - /usr/local/bin/yarn
    npm: 8.5.5 - /usr/local/bin/npm
    Watchman: 2022.03.21.00 - /usr/local/bin/watchman
  npmPackages:
    @vitejs/plugin-react: ^1.3.2 => 1.3.2
    vite: ^2.9.8 => 2.9.8

Used Package Manager

pnpm

Logs

2022-05-07T05:26:28.496Z vite:config bundled config file loaded in 281.58ms
2022-05-07T05:26:28.510Z vite:config using resolved config: {
  plugins: [
    'vite:build-metadata',
    'alias',
    'vite:react-babel',
    'vite:react-refresh',
    'vite:react-jsx',
    'vite:modulepreload-polyfill',
    'vite:resolve',
    'vite:html-inline-proxy',
    'vite:css',
    'vite:esbuild',
    'vite:json',
    'vite:wasm',
    'vite:worker',
    'vite:asset',
    'vite:define',
    'vite:css-post',
    'vite:build-html',
    'vite:worker-import-meta-url',
    'vite:watch-package-data',
    'commonjs',
    'vite:data-uri',
    'rollup-plugin-dynamic-import-variables',
    'vite:asset-import-meta-url',
    'vite:build-import-analysis',
    'vite:esbuild-transpile',
    'vite:terser',
    'vite:reporter',
    'vite:load-fallback'
  ],
  build: {
    target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
    polyfillModulePreload: true,
    outDir: 'dist',
    assetsDir: 'assets',
    assetsInlineLimit: 4096,
    cssCodeSplit: true,
    cssTarget: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
    sourcemap: false,
    rollupOptions: {},
    minify: 'esbuild',
    terserOptions: {},
    write: true,
    emptyOutDir: null,
    manifest: false,
    lib: false,
    ssr: false,
    ssrManifest: false,
    reportCompressedSize: true,
    chunkSizeWarningLimit: 500,
    watch: null,
    commonjsOptions: { include: [Array], extensions: [Array] },
    dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }
  },
  resolve: { dedupe: [ 'react', 'react-dom' ], alias: [ [Object], [Object] ] },
  optimizeDeps: {
    include: [ 'react/jsx-dev-runtime' ],
    esbuildOptions: { keepNames: undefined, preserveSymlinks: undefined }
  },
  configFile: '/Users/hyrious/pg/test-vite-react/main/vite.config.ts',
  configFileDependencies: [ '/Users/hyrious/pg/test-vite-react/main/vite.config.ts' ],
  inlineConfig: {
    root: undefined,
    base: undefined,
    mode: undefined,
    configFile: undefined,
    logLevel: undefined,
    clearScreen: undefined,
    build: {}
  },
  root: '/Users/hyrious/pg/test-vite-react/main',
  base: '/',
  publicDir: '/Users/hyrious/pg/test-vite-react/main/public',
  cacheDir: '/Users/hyrious/pg/test-vite-react/main/node_modules/.vite',
  command: 'build',
  mode: 'production',
  isWorker: false,
  isProduction: true,
  server: {
    preTransformRequests: true,
    fs: { strict: true, allow: [Array], deny: [Array] }
  },
  preview: {
    port: undefined,
    strictPort: undefined,
    host: undefined,
    https: undefined,
    open: undefined,
    proxy: undefined,
    cors: undefined,
    headers: undefined
  },
  env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
  assetsInclude: [Function: assetsInclude],
  logger: {
    hasWarned: false,
    info: [Function: info],
    warn: [Function: warn],
    warnOnce: [Function: warnOnce],
    error: [Function: error],
    clearScreen: [Function: clearScreen],
    hasErrorLogged: [Function: hasErrorLogged]
  },
  packageCache: Map(0) { set: [Function (anonymous)] },
  createResolver: [Function: createResolver],
  worker: {
    format: 'iife',
    plugins: [
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object], [Object], [Object],
      [Object]
    ],
    rollupOptions: {}
  }
}
vite v2.9.8 building for production...
transforming...
✓ 3 modules transformed.
[vite:react-babel] /Users/hyrious/pg/test-vite-react/lib/index.ts: Unexpected token (5:9)

  3 | export class b {
  4 |   // "public" is not a valid jsx code, it will break "restoreJSX()"
> 5 |   public f = () => React.createElement("span");
    |          ^
  6 | }
  7 |
file: /Users/hyrious/pg/test-vite-react/lib/index.ts:5:9
error during build:
SyntaxError: /Users/hyrious/pg/test-vite-react/lib/index.ts: Unexpected token (5:9)

  3 | export class b {
  4 |   // "public" is not a valid jsx code, it will break "restoreJSX()"
> 5 |   public f = () => React.createElement("span");
    |          ^
  6 | }
  7 |
    at instantiate (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:72:32)
    at constructor (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:358:12)
    at Object.raise (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:3335:19)
    at Object.unexpected (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:3373:16)
    at Object.parseClassMemberWithIsStatic (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:15606:12)
    at Object.parseClassMember (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:15473:10)
    at /Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:15413:14
    at Object.withSmartMixTopicForbiddingContext (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:14213:14)
    at Object.parseClassBody (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:15388:10)
    at Object.parseClass (/Users/hyrious/pg/test-vite-react/node_modules/.pnpm/@babel+parser@7.17.10/node_modules/@babel/parser/lib/index.js:15362:22)

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions