vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.77k stars 6.21k forks source link

Vite ignores `useDefineForClassFields` in nested tsconfigs when using ts project references #18297

Closed PredokMiF closed 1 month ago

PredokMiF commented 1 month ago

Describe the bug

When I use react-ts template and try to use mobx inside, then I get wrong behavior because mobx require ts compiler option "useDefineForClassFields": true, but vite loose this optin when it is defined in referenced tsconfig file.

It is vite bug, not tsc. To demonstrate this I remove options "noEmit": true and "allowImportingTsExtensions": true from tsconfig.app.json and tsconfig.node.json and run npm run build. For this setup I will see two result JS files (compiled by tsc and by vite). image

Similar errors:

  1. https://github.com/vitejs/vite/issues/3227 - it is closed
  2. https://github.com/vitejs/vite/issues/11722 - I think my issue is not about the order of field initialization

Reproduction

https://stackblitz.com/edit/vitejs-vite-va8v8j?file=src%2Fmain.tsx

Steps to reproduce

  1. npm create vite@latest vite-react-ts -- --template react-ts
  2. cd ./vite-react-ts
  3. npm i
  4. Remove the public folder and all files in src expect main.tsx
  5. Replace the contents of main.tsx with:

    
    class ContactInfoDto {
    firstName: string
    
    constructor(firstName: string) {
        if ('firstName' in this) {
            alert('"firstName" property is defined. Expected behavior')
        } else {
            alert('"firstName" property is not defined. Wrong behavior')
        }
    
        this.firstName = firstName
    }
    }

new ContactInfoDto('')

6. ```npm run dev```
7. Open browser http://localhost:5173/

### System Info

```shell
System:
    OS: Windows 10 10.0.19045
    CPU: (16) x64 Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
    Memory: 22.24 GB / 47.79 GB
Binaries:
    Node: 18.19.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.5.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.19041.4355
npmPackages:
    @vitejs/plugin-react: ^4.3.2 => 4.3.2
    vite: ^5.4.8 => 5.4.8

Used Package Manager

npm

Logs

Click to expand vite debug log ```shell vite:config bundled config file loaded in 98.53ms +0ms vite:config using resolved config: { vite:config plugins: [ vite:config 'vite:optimized-deps', vite:config 'vite:watch-package-data', vite:config 'vite:pre-alias', vite:config 'alias', vite:config 'vite:react-babel', vite:config 'vite:react-refresh', vite:config 'vite:modulepreload-polyfill', vite:config 'vite:resolve', vite:config 'vite:html-inline-proxy', vite:config 'vite:css', vite:config 'vite:esbuild', vite:config 'vite:json', vite:config 'vite:wasm-helper', vite:config 'vite:worker', vite:config 'vite:asset', vite:config 'vite:wasm-fallback', vite:config 'vite:define', vite:config 'vite:css-post', vite:config 'vite:worker-import-meta-url', vite:config 'vite:asset-import-meta-url', vite:config 'vite:dynamic-import-vars', vite:config 'vite:import-glob', vite:config 'vite:client-inject', vite:config 'vite:css-analysis', vite:config 'vite:import-analysis' vite:config ], vite:config optimizeDeps: { vite:config holdUntilCrawlEnd: true, vite:config force: undefined, vite:config esbuildOptions: { preserveSymlinks: false, jsx: 'automatic' }, vite:config include: [ 'react', 'react/jsx-dev-runtime', 'react/jsx-runtime' ] 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 esbuild: { jsxDev: true, jsx: 'automatic', jsxImportSource: undefined }, vite:config build: { vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ], vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ], vite:config outDir: 'dist', vite:config assetsDir: 'assets', vite:config assetsInlineLimit: 4096, vite:config cssCodeSplit: true, vite:config sourcemap: false, vite:config rollupOptions: { onwarn: [Function: onwarn] }, vite:config minify: 'esbuild', vite:config terserOptions: {}, vite:config write: true, vite:config emptyOutDir: null, vite:config copyPublicDir: true, vite:config manifest: false, vite:config lib: false, vite:config ssr: false, vite:config ssrManifest: false, vite:config ssrEmitAssets: false, vite:config reportCompressedSize: true, vite:config chunkSizeWarningLimit: 500, vite:config watch: null, vite:config commonjsOptions: { include: [Array], extensions: [Array] }, vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] }, vite:config modulePreload: { polyfill: true }, vite:config cssMinify: true vite:config }, vite:config resolve: { vite:config mainFields: [ 'browser', 'module', 'jsnext:main', 'jsnext' ], vite:config conditions: [], vite:config extensions: [ vite:config '.mjs', '.js', vite:config '.mts', '.ts', vite:config '.jsx', '.tsx', vite:config '.json' vite:config ], vite:config dedupe: [ 'react', 'react-dom' ], vite:config preserveSymlinks: false, vite:config alias: [ [Object], [Object] ] vite:config }, vite:config configFile: 'C:/src/t/vite-react-ts/vite.config.ts', vite:config configFileDependencies: [ 'C:/src/t/vite-react-ts/vite.config.ts' ], 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 }, vite:config server: { host: undefined } vite:config }, vite:config root: 'C:/src/t/vite-react-ts', vite:config base: '/', vite:config decodedBase: '/', vite:config rawBase: '/', vite:config publicDir: 'C:/src/t/vite-react-ts/public', vite:config cacheDir: 'C:/src/t/vite-react-ts/node_modules/.vite', vite:config command: 'serve', vite:config mode: 'development', vite:config ssr: { vite:config target: 'node', vite:config optimizeDeps: { noDiscovery: true, esbuildOptions: [Object] } vite:config }, vite:config isWorker: false, vite:config mainConfig: null, vite:config bundleChain: [], vite:config isProduction: false, vite:config css: { lightningcss: undefined }, vite:config preview: { vite:config port: undefined, vite:config strictPort: undefined, vite:config host: undefined, vite:config https: undefined, vite:config open: undefined, vite:config proxy: undefined, vite:config cors: undefined, vite:config headers: undefined vite:config }, vite:config envDir: 'C:/src/t/vite-react-ts', vite:config env: { BASE_URL: '/', MODE: 'development', DEV: true, PROD: false }, vite:config assetsInclude: [Function: assetsInclude], vite:config logger: { vite:config hasWarned: false, vite:config info: [Function: info], vite:config warn: [Function: warn], vite:config warnOnce: [Function: warnOnce], vite:config error: [Function: error], vite:config clearScreen: [Function: clearScreen], vite:config hasErrorLogged: [Function: hasErrorLogged] vite:config }, vite:config packageCache: Map(1) { vite:config 'fnpd_C:/src/t/vite-react-ts' => { vite:config dir: 'C:/src/t/vite-react-ts', vite:config data: [Object], vite:config hasSideEffects: [Function: hasSideEffects], vite:config webResolvedImports: {}, vite:config nodeResolvedImports: {}, vite:config setResolvedCache: [Function: setResolvedCache], vite:config getResolvedCache: [Function: getResolvedCache] vite:config }, vite:config set: [Function (anonymous)] vite:config }, vite:config createResolver: [Function: createResolver], vite:config worker: { format: 'iife', plugins: '() => plugins', rollupOptions: {} }, vite:config appType: 'spa', vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false }, vite:config getSortedPlugins: [Function: getSortedPlugins], vite:config getSortedPluginHooks: [Function: getSortedPluginHooks] vite:config } +13ms vite:deps removing old cache dir C:/src/t/vite-react-ts/node_modules/.vite/deps +0ms vite:resolve 4.30ms react -> C:/src/t/vite-react-ts/node_modules/react/index.js +0ms vite:resolve 1.28ms react/jsx-dev-runtime -> C:/src/t/vite-react-ts/node_modules/react/jsx-dev-runtime.js +2ms vite:resolve 0.68ms react/jsx-runtime -> C:/src/t/vite-react-ts/node_modules/react/jsx-runtime.js +1ms vite:deps scanning for dependencies... +0ms VITE v5.4.8 ready in 442 ms ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose ➜ press h + enter to show help vite:deps Crawling dependencies using entries: vite:deps C:/src/t/vite-react-ts/index.html +0ms vite:resolve 0.60ms /src/main.tsx -> C:/src/t/vite-react-ts/src/main.tsx +62ms vite:deps Scan completed in 64.09ms: no dependencies found +34ms vite:deps creating package.json in C:/src/t/vite-react-ts/node_modules/.vite/deps_temp_76891b01 +84ms vite:resolve 2.29ms react -> C:/src/t/vite-react-ts/node_modules/react/index.js +27ms vite:deps Dependencies bundled in 34.24ms +37ms ```

Validations

stackblitz[bot] commented 1 month ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

PredokMiF commented 1 month ago

I got around this problem by specifying “useDefineForClassFields”: true in the root tsconfig.json:

{
  "compilerOptions": {
    "useDefineForClassFields": true
  },
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

It worked for me, but I think this misbehavior needs to be fixed. mobx works with this as expected

sapphi-red commented 1 month ago

This is caused by an upstream issue: https://github.com/dominikg/tsconfck/issues/199

The workaround is to set src/**/* instead of src in tsconfig.app.json.

PredokMiF commented 1 month ago

Yes, this method workes too

PredokMiF commented 1 month ago

Maybe put src/**/* in the react-ts template until the issue is fixed?