Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected early exit error after executing vite build in a multi-entry project with vite@^5.1.0 #16027

Closed
7 tasks done
Sec-ant opened this issue Feb 25, 2024 · 3 comments
Closed
7 tasks done
Labels
duplicate This issue or pull request already exists

Comments

@Sec-ant
Copy link

Sec-ant commented Feb 25, 2024

Describe the bug

When I update vite to ^5.1.0, executing vite build in my project produces an error: Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit: ....

My project is a multi-entry set up. I spent some time to locate the problem and managed to provide a minimal repro below.

Here is the folder structure of the repro project:

.
├── package-lock.json
├── package.json
├── src
│   ├── a.ts
│   ├── b.ts
│   └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

Here are the configs in the repro project:

vite.config.ts:

import { defineConfig } from "vite";

export default defineConfig({
  build: {
    lib: {
      entry: {
        a: "src/a.ts",
        b: "src/b.ts",
      },
      formats: ["es"],
    },
  },
});

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "types": [],
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"],
  "references": [
    {
      "path": "tsconfig.node.json"
    }
  ]
}

tsconfig.node.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "types": ["node"],
    "composite": true
  },
  "include": ["vite.config.ts"]
}

The error is:

vite v5.1.0 building for production...
error during build:
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite:esbuild) transform "/home/secant/vite-multi-entry-bug-repro/src/a.ts"
(vite:esbuild) transform "/home/secant/vite-multi-entry-bug-repro/src/b.ts"
    at process.handleBeforeExit (file:///home/secant/vite-multi-entry-bug-repro/node_modules/rollup/dist/es/shared/node-entry.js:19915:28)
    at Object.onceWrapper (node:events:634:26)
    at process.emit (node:events:519:28)

Some info I find may be helpful:

  1. v5.1.0-beta.7 or versions prior to that don't throw this error, and the project can be successfully built. So this bug is introduced somewhere in v5.1.0-beta.7...v5.1.0.
  2. If I keep only one entry in my vite.config.ts, it can be successfully built.
  3. If I remove the extends field in tsconfig.node.json, the project can be successfully built.

Thanks in advance!

Reproduction

https://github.com/Sec-ant/vite-multi-entry-bug-repro

Steps to reproduce

git clone https://github.com/Sec-ant/vite-multi-entry-bug-repro
cd vite-multi-entry-bug-repro
npm i
npm run build # or `npx vite build`

System Info

System:
  OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
  CPU: (16) x64 AMD Ryzen 7 4800U with Radeon Graphics
  Memory: 992.50 MB / 7.44 GB
  Container: Yes
  Shell: 5.1.16 - /bin/bash
Binaries:
  Node: 21.6.0 - ~/.nvm/versions/node/v21.6.0/bin/node
  Yarn: 1.22.19 - /usr/bin/yarn
  npm: 10.4.0 - ~/.nvm/versions/node/v21.6.0/bin/npm
  pnpm: 8.15.0 - ~/.local/share/pnpm/pnpm
  bun: 1.0.20 - ~/.bun/bin/bun
npmPackages:
  vite: 5.1.0 => 5.1.0

Used Package Manager

npm

Logs

Click to expand!
  vite:config bundled config file loaded in 25.83ms +0ms
  vite:config using resolved config: {
  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: false,
  vite:config     sourcemap: false,
  vite:config     rollupOptions: {},
  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: { entry: [Object], formats: [Array] },
  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   configFile: '/home/secant/vite-multi-entry-bug-repro/vite.config.ts',
  vite:config   configFileDependencies: [ '/home/secant/vite-multi-entry-bug-repro/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     build: {}
  vite:config   },
  vite:config   root: '/home/secant/vite-multi-entry-bug-repro',
  vite:config   base: '/',
  vite:config   rawBase: '/',
  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: [],
  vite:config     preserveSymlinks: false,
  vite:config     alias: [ [Object], [Object] ]
  vite:config   },
  vite:config   publicDir: '/home/secant/vite-multi-entry-bug-repro/public',
  vite:config   cacheDir: '/home/secant/vite-multi-entry-bug-repro/node_modules/.vite',
  vite:config   command: 'build',
  vite:config   mode: 'production',
  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   isProduction: true,
  vite:config   plugins: [
  vite:config     'vite:build-metadata',
  vite:config     'vite:watch-package-data',
  vite:config     'vite:pre-alias',
  vite:config     'alias',
  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:build-html',
  vite:config     'vite:worker-import-meta-url',
  vite:config     'vite:asset-import-meta-url',
  vite:config     'vite:force-systemjs-wrap-complete',
  vite:config     'commonjs',
  vite:config     'vite:data-uri',
  vite:config     'vite:dynamic-import-vars',
  vite:config     'vite:import-glob',
  vite:config     'vite:build-import-analysis',
  vite:config     'vite:esbuild-transpile',
  vite:config     'vite:terser',
  vite:config     'vite:reporter',
  vite:config     'vite:load-fallback'
  vite:config   ],
  vite:config   css: { lightningcss: undefined },
  vite:config   esbuild: { jsxDev: false },
  vite:config   server: {
  vite:config     preTransformRequests: true,
  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   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: '/home/secant/vite-multi-entry-bug-repro',
  vite:config   env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
  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_/home/secant/vite-multi-entry-bug-repro' => {
  vite:config       dir: '/home/secant/vite-multi-entry-bug-repro',
  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   optimizeDeps: {
  vite:config     holdUntilCrawlEnd: true,
  vite:config     esbuildOptions: { preserveSymlinks: false }
  vite:config   },
  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 } +23ms
vite v5.1.0 building for production...
error during build:
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite:esbuild) transform "/home/secant/vite-multi-entry-bug-repro/src/a.ts"
(vite:esbuild) transform "/home/secant/vite-multi-entry-bug-repro/src/b.ts"
    at process.handleBeforeExit (file:///home/secant/vite-multi-entry-bug-repro/node_modules/rollup/dist/es/shared/node-entry.js:19915:28)
    at Object.onceWrapper (node:events:634:26)
    at process.emit (node:events:519:28)

Validations

@Sec-ant Sec-ant changed the title Unexpected early exit. error after executing vite build in a multi-entry project in vite@^5.1.0 Unexpected early exit error after executing vite build in a multi-entry project with vite@^5.1.0 Feb 25, 2024
@Sec-ant
Copy link
Author

Sec-ant commented Feb 25, 2024

Ah, I believe this is a confirmed bug from tsconfck@3.0.2: dominikg/tsconfck#154. (Before releasing vite@5.1.0, the version of tsconfck is bumped to v3.0.2 in e0a6ef2)

Related issue in vite-tsconfig-paths: aleclarson/vite-tsconfig-paths#132.

A workaround mentioned in that issue from @dominikg, the author of tsconfck:

A workaround in get-tsconfig-paths could be to serialize the parse of found configs for the time being, affected users could try to not have references point at files that they also extend.

circle:

/src/tsconfig.json # extends ../tsconfig.json
tsconfig.json  # references src/tsconfig.json

no circle:

/src/tsconfig.json # extends ../tsconfig.base.json
tsconfig.json  # references src/tsconfig.json , nothing but references in it
tsconfig.base.json  # all the base config values

the latter seems to be the pattern used by typescript itself: https://github.com/microsoft/TypeScript/blob/main/src/tsconfig.json

And I can confirm the workaround also works in this case 🎉.

@Sec-ant
Copy link
Author

Sec-ant commented Feb 25, 2024

It turns out there're already related issues/PRs in vite regarding this problem: #15870, #15899, #15932

I didn't find them because the error message is not very clear for me to check where to look at. And searching the error message leads me to some old unrelated issues.

Feel free to close this issue if this is considered duplicated.

Sec-ant added a commit to Sec-ant/zxing-wasm that referenced this issue Feb 26, 2024
Sec-ant added a commit to Sec-ant/zxing-wasm that referenced this issue Feb 26, 2024
@sapphi-red
Copy link
Member

Duplicate of #15870

@sapphi-red sapphi-red marked this as a duplicate of #15870 Feb 27, 2024
@sapphi-red sapphi-red closed this as not planned Won't fix, can't repro, duplicate, stale Feb 27, 2024
@sapphi-red sapphi-red added duplicate This issue or pull request already exists and removed pending triage labels Feb 27, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants