diff --git a/docs/config/worker-options.md b/docs/config/worker-options.md index 840caa60915ba2..99500ae259ccfe 100644 --- a/docs/config/worker-options.md +++ b/docs/config/worker-options.md @@ -5,7 +5,7 @@ Options related to Web Workers. ## worker.format - **Type:** `'es' | 'iife'` -- **Default:** `iife` +- **Default:** `'iife'` Output format for worker bundle. diff --git a/docs/guide/features.md b/docs/guide/features.md index 787a3c0d58b620..b13049029d6724 100644 --- a/docs/guide/features.md +++ b/docs/guide/features.md @@ -248,10 +248,14 @@ You can also use CSS modules combined with pre-processors by prepending `.module The automatic injection of CSS contents can be turned off via the `?inline` query parameter. In this case, the processed CSS string is returned as the module's default export as usual, but the styles aren't injected to the page. ```js -import styles from './foo.css' // will be injected into the page +import './foo.css' // will be injected into the page import otherStyles from './bar.css?inline' // will not be injected ``` +::: tip NOTE +Default and named imports from CSS files (e.g `import style from './foo.css'`) are deprecated since Vite 4. Use the `?inline` query instead. +::: + ## Static Assets Importing a static asset will return the resolved public URL when it is served: diff --git a/package.json b/package.json index 7cdd7149ec2c01..c8d3545fe57519 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "prompts": "^2.4.2", "resolve": "^1.22.1", "rimraf": "^4.1.2", - "rollup": "^3.18.0", + "rollup": "^3.20.0", "semver": "^7.3.8", "simple-git-hooks": "^2.8.1", "tslib": "^2.5.0", diff --git a/packages/create-vite/template-lit-ts/package.json b/packages/create-vite/template-lit-ts/package.json index 4848ae80082102..90472689e40891 100644 --- a/packages/create-vite/template-lit-ts/package.json +++ b/packages/create-vite/template-lit-ts/package.json @@ -21,6 +21,6 @@ }, "devDependencies": { "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-lit/package.json b/packages/create-vite/template-lit/package.json index 59779467f32e38..d6dbd42d941a89 100644 --- a/packages/create-vite/template-lit/package.json +++ b/packages/create-vite/template-lit/package.json @@ -18,6 +18,6 @@ "lit": "^2.6.1" }, "devDependencies": { - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-preact-ts/package.json b/packages/create-vite/template-preact-ts/package.json index d74ff00adb7766..c077e8826aa894 100644 --- a/packages/create-vite/template-preact-ts/package.json +++ b/packages/create-vite/template-preact-ts/package.json @@ -14,6 +14,6 @@ "devDependencies": { "@preact/preset-vite": "^2.5.0", "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-preact/package.json b/packages/create-vite/template-preact/package.json index e9924eb4e8e61a..f723768617a466 100644 --- a/packages/create-vite/template-preact/package.json +++ b/packages/create-vite/template-preact/package.json @@ -13,6 +13,6 @@ }, "devDependencies": { "@preact/preset-vite": "^2.5.0", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-react-ts/package.json b/packages/create-vite/template-react-ts/package.json index 6d6ad2b6823548..046d3a2cba8c69 100644 --- a/packages/create-vite/template-react-ts/package.json +++ b/packages/create-vite/template-react-ts/package.json @@ -17,6 +17,6 @@ "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-react-ts/src/App.tsx b/packages/create-vite/template-react-ts/src/App.tsx index 776eaa027ab01e..08d57ca4dd50ba 100644 --- a/packages/create-vite/template-react-ts/src/App.tsx +++ b/packages/create-vite/template-react-ts/src/App.tsx @@ -12,7 +12,7 @@ function App() { Vite logo - + React logo diff --git a/packages/create-vite/template-react/package.json b/packages/create-vite/template-react/package.json index 8c8bf0326a7fb9..19640fbd37aad6 100644 --- a/packages/create-vite/template-react/package.json +++ b/packages/create-vite/template-react/package.json @@ -16,6 +16,6 @@ "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-react/src/App.jsx b/packages/create-vite/template-react/src/App.jsx index 2ba469dc82918f..4c471316eb2c04 100644 --- a/packages/create-vite/template-react/src/App.jsx +++ b/packages/create-vite/template-react/src/App.jsx @@ -12,7 +12,7 @@ function App() { Vite logo - + React logo diff --git a/packages/create-vite/template-svelte-ts/package.json b/packages/create-vite/template-svelte-ts/package.json index 14da1ab85d432b..70070a703a3266 100644 --- a/packages/create-vite/template-svelte-ts/package.json +++ b/packages/create-vite/template-svelte-ts/package.json @@ -16,6 +16,6 @@ "svelte-check": "^2.10.3", "tslib": "^2.5.0", "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-svelte/package.json b/packages/create-vite/template-svelte/package.json index 19b01199aef10a..b33e29c76a5375 100644 --- a/packages/create-vite/template-svelte/package.json +++ b/packages/create-vite/template-svelte/package.json @@ -11,6 +11,6 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.3", "svelte": "^3.55.1", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-vanilla-ts/package.json b/packages/create-vite/template-vanilla-ts/package.json index 10c7996322a22d..c23eef8e5a9902 100644 --- a/packages/create-vite/template-vanilla-ts/package.json +++ b/packages/create-vite/template-vanilla-ts/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-vanilla/package.json b/packages/create-vite/template-vanilla/package.json index cc773a72a806be..9de9447933d69f 100644 --- a/packages/create-vite/template-vanilla/package.json +++ b/packages/create-vite/template-vanilla/package.json @@ -9,6 +9,6 @@ "preview": "vite preview" }, "devDependencies": { - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/create-vite/template-vue-ts/package.json b/packages/create-vite/template-vue-ts/package.json index 6e13b1c0f13f00..b3adc619dd6632 100644 --- a/packages/create-vite/template-vue-ts/package.json +++ b/packages/create-vite/template-vue-ts/package.json @@ -12,9 +12,9 @@ "vue": "^3.2.47" }, "devDependencies": { - "@vitejs/plugin-vue": "^4.0.0", + "@vitejs/plugin-vue": "^4.1.0", "typescript": "^4.9.3", - "vite": "^4.1.0", + "vite": "^4.2.0", "vue-tsc": "^1.2.0" } } diff --git a/packages/create-vite/template-vue/package.json b/packages/create-vite/template-vue/package.json index 7a0c5bff4da4ec..754830b42723d5 100644 --- a/packages/create-vite/template-vue/package.json +++ b/packages/create-vite/template-vue/package.json @@ -13,6 +13,6 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", - "vite": "^4.1.0" + "vite": "^4.2.0" } } diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index 4d74fd1a4eb094..a970611530a54b 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,25 +1,88 @@ +## 4.2.1 (2023-03-20) + +* fix: add `virtual:` to virtual module source map ignore (#12444) ([c4aa28f](https://github.com/vitejs/vite/commit/c4aa28f)), closes [#12444](https://github.com/vitejs/vite/issues/12444) +* fix(css): inject source content conditionally (#12449) ([3e665f6](https://github.com/vitejs/vite/commit/3e665f6)), closes [#12449](https://github.com/vitejs/vite/issues/12449) +* fix(worker): using data URLs for inline shared worker (#12014) ([79a5007](https://github.com/vitejs/vite/commit/79a5007)), closes [#12014](https://github.com/vitejs/vite/issues/12014) +* chore: changelog edits for 4.2 (#12438) ([ce047e3](https://github.com/vitejs/vite/commit/ce047e3)), closes [#12438](https://github.com/vitejs/vite/issues/12438) + + + ## 4.2.0 (2023-03-16) -* feat: add status message for 504 caused by optimizer (#12435) ([5cdd3fa](https://github.com/vitejs/vite/commit/5cdd3fa)), closes [#12435](https://github.com/vitejs/vite/issues/12435) -* fix: html env replacement plugin position (#12404) ([96f36a9](https://github.com/vitejs/vite/commit/96f36a9)), closes [#12404](https://github.com/vitejs/vite/issues/12404) -* fix(optimizer): # symbol in deps id stripped by browser (#12415) ([e23f690](https://github.com/vitejs/vite/commit/e23f690)), closes [#12415](https://github.com/vitejs/vite/issues/12415) -* fix(resolve): rebase sub imports relative path (#12373) ([fe1d61a](https://github.com/vitejs/vite/commit/fe1d61a)), closes [#12373](https://github.com/vitejs/vite/issues/12373) -* fix(server): should close server after create new server (#12379) ([d23605d](https://github.com/vitejs/vite/commit/d23605d)), closes [#12379](https://github.com/vitejs/vite/issues/12379) -* docs: correct description for UserConfig.envDir when used with relative path (#12429) ([2b37cde](https://github.com/vitejs/vite/commit/2b37cde)), closes [#12429](https://github.com/vitejs/vite/issues/12429) -* refactor(resolve): remove deep import syntax handling (#12381) ([42e0d6a](https://github.com/vitejs/vite/commit/42e0d6a)), closes [#12381](https://github.com/vitejs/vite/issues/12381) +Vite 4.2 is out! + +### Support env variables replacement in HTML files + +Vite now supports [replacing env variables in HTML files](https://vitejs.dev/guide/env-and-mode.html#html-env-replacement). Any properties in `import.meta.env` can be used in HTML files with a special `%ENV_NAME%` syntax: + +```html +

Vite is running in %MODE%

+

Using data from %VITE_API_URL%

+``` + +### Sourcemaps improvements + +The Chrome Dev Tools team has been working to improve the DX of Vite and Vite-powered frameworks in the dev tools. Vite 4.2 brings an [improved experience](https://twitter.com/bmeurer/status/1631286267823439881) and tools for framework authors to [hide 3rd party code and build artifacts from the user](https://twitter.com/bmeurer/status/1631531492462526467) from console log traces using [`server.sourcemapIgnoreList`](https://vitejs.dev/config/server-options.html#server-sourcemapignorelist) and [`build.rollupOptions.output.sourcemapIgnoreList`](https://rollupjs.org/configuration-options/#output-sourcemapignorelist). + +### ESM subpath imports + +Vite 4.2 now supports [subpath imports](https://nodejs.org/api/packages.html#subpath-imports), thanks to [@lukeed05](https://twitter.com/lukeed05)'s [resolve.exports](https://github.com/lukeed/resolve.exports) library. + +### TypeScript 5 support + +Vite 4.2 also supports TypeScript 5's `tsconfig` `extends` [array format](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#supporting-multiple-configuration-files-in-extends), thanks to [tsconfck](https://github.com/dominikg/tsconfck). + + +### esbuild 0.17 + +esbuild [v0.17.0](https://github.com/evanw/esbuild/releases/tag/v0.17.0) improved the design of its incremental, watch, and serve APIs. Check out [#11908](https://github.com/vitejs/vite/pull/11908) for the rationale of why we didn't consider the backward-incompatible changes breaking for our use cases. The updated esbuild design now allows Vite to properly cancel in-fly builds and improve server restarts. +### Use Rollup types from the vite package -## 4.2.0-beta.2 (2023-03-13) +Expose Rollup types as a namespace. This is helpful to avoid type conflicts because of different versions of Rollup types in environments like [vite-ecosystem-ci](https://github.com/vitejs/vite-ecosystem-ci) ([#12316](https://github.com/vitejs/vite/issues/12316)). -* chore: fix test misc (#12392) ([a595b11](https://github.com/vitejs/vite/commit/a595b11)), closes [#12392](https://github.com/vitejs/vite/issues/12392) -* chore: remove build warn filter (#12391) ([0755cf2](https://github.com/vitejs/vite/commit/0755cf2)), closes [#12391](https://github.com/vitejs/vite/issues/12391) -* chore: update tsconfck to 2.1.0 to add support for typescript 5 config syntax (#12401) ([3f1c379](https://github.com/vitejs/vite/commit/3f1c379)), closes [#12401](https://github.com/vitejs/vite/issues/12401) -* chore(deps): update all non-major dependencies (#12299) ([b41336e](https://github.com/vitejs/vite/commit/b41336e)), closes [#12299](https://github.com/vitejs/vite/issues/12299) -* chore(utils): remove redundant type judgment (#12345) ([01a0056](https://github.com/vitejs/vite/commit/01a0056)), closes [#12345](https://github.com/vitejs/vite/issues/12345) +```ts +import type { Rollup } from 'vite' +``` + + +### Português Docs Translation + +The Vite documentation is now translated to Português at [pt.vitejs.dev](https://pt.vitejs.dev) thanks to [Nazaré Da Piedade](https://twitter.com/nazarepiedady) . + + +### Features + +* feat: add status message for 504 caused by optimizer (#12435) ([5cdd3fa](https://github.com/vitejs/vite/commit/5cdd3fa)), closes [#12435](https://github.com/vitejs/vite/issues/12435) +* feat: update tsconfck to 2.1.0 to add support for typescript 5 config syntax (#12401) ([3f1c379](https://github.com/vitejs/vite/commit/3f1c379)), closes [#12401](https://github.com/vitejs/vite/issues/12401) * feat: default esbuild jsxDev based on config.isProduction (#12386) ([f24c2b0](https://github.com/vitejs/vite/commit/f24c2b0)), closes [#12386](https://github.com/vitejs/vite/issues/12386) -* feat(css): add build.cssMinify (#12207) ([90431f2](https://github.com/vitejs/vite/commit/90431f2)), closes [#12207](https://github.com/vitejs/vite/issues/12207) +* feat(css): add `build.cssMinify` (#12207) ([90431f2](https://github.com/vitejs/vite/commit/90431f2)), closes [#12207](https://github.com/vitejs/vite/issues/12207) * feat(types): export Rollup namespace (#12316) ([6e49e52](https://github.com/vitejs/vite/commit/6e49e52)), closes [#12316](https://github.com/vitejs/vite/issues/12316) +* feat: add `sourcemapIgnoreList` configuration option (#12174) ([f875580](https://github.com/vitejs/vite/commit/f875580)), closes [#12174](https://github.com/vitejs/vite/issues/12174) +* feat: cancellable scan during optimization (#12225) ([1e1cd3b](https://github.com/vitejs/vite/commit/1e1cd3b)), closes [#12225](https://github.com/vitejs/vite/issues/12225) +* feat: don't override `build.target` if terser is 5.16.0+ (#12197) ([9885f6f](https://github.com/vitejs/vite/commit/9885f6f)), closes [#12197](https://github.com/vitejs/vite/issues/12197) +* feat: support ESM subpath imports (#7770) ([cc92da9](https://github.com/vitejs/vite/commit/cc92da9)), closes [#7770](https://github.com/vitejs/vite/issues/7770) +* feat(css): add preprocessor option to define stylus vars & funcs (#7227) ([5968bec](https://github.com/vitejs/vite/commit/5968bec)), closes [#7227](https://github.com/vitejs/vite/issues/7227) +* feat(css): support resolving stylesheets from exports map (#7817) ([108aadf](https://github.com/vitejs/vite/commit/108aadf)), closes [#7817](https://github.com/vitejs/vite/issues/7817) +* feat(html): support env replacement (#12202) ([4f2c49f](https://github.com/vitejs/vite/commit/4f2c49f)), closes [#12202](https://github.com/vitejs/vite/issues/12202) +* refactor: customize ErrorOverlay (part 2) (#11830) ([4159e6f](https://github.com/vitejs/vite/commit/4159e6f)), closes [#11830](https://github.com/vitejs/vite/issues/11830) +* refactor: remove constructed sheet type style injection (#11818) ([1a6a0c2](https://github.com/vitejs/vite/commit/1a6a0c2)), closes [#11818](https://github.com/vitejs/vite/issues/11818) +* refactor(importAnalysis): cache injected env string (#12154) ([2aad552](https://github.com/vitejs/vite/commit/2aad552)), closes [#12154](https://github.com/vitejs/vite/issues/12154) +* feat: esbuild 0.17 (#11908) ([9d42f06](https://github.com/vitejs/vite/commit/9d42f06)), closes [#11908](https://github.com/vitejs/vite/issues/11908) +* feat: ignore list client injected sources (#12170) ([8a98aef](https://github.com/vitejs/vite/commit/8a98aef)), closes [#12170](https://github.com/vitejs/vite/issues/12170) +* feat: support rollup plugin `this.load` in plugin container context (#11469) ([abfa804](https://github.com/vitejs/vite/commit/abfa804)), closes [#11469](https://github.com/vitejs/vite/issues/11469) +* feat(cli): allow to specify sourcemap mode via --sourcemap build's option (#11505) ([ee3b90a](https://github.com/vitejs/vite/commit/ee3b90a)), closes [#11505](https://github.com/vitejs/vite/issues/11505) +* feat(reporter): report built time (#12100) ([f2ad222](https://github.com/vitejs/vite/commit/f2ad222)), closes [#12100](https://github.com/vitejs/vite/issues/12100) + + +### Bug Fixes + +* fix: html env replacement plugin position (#12404) ([96f36a9](https://github.com/vitejs/vite/commit/96f36a9)), closes [#12404](https://github.com/vitejs/vite/issues/12404) +* fix(optimizer): # symbol in deps id stripped by browser (#12415) ([e23f690](https://github.com/vitejs/vite/commit/e23f690)), closes [#12415](https://github.com/vitejs/vite/issues/12415) +* fix(resolve): rebase sub imports relative path (#12373) ([fe1d61a](https://github.com/vitejs/vite/commit/fe1d61a)), closes [#12373](https://github.com/vitejs/vite/issues/12373) +* fix(server): should close server after create new server (#12379) ([d23605d](https://github.com/vitejs/vite/commit/d23605d)), closes [#12379](https://github.com/vitejs/vite/issues/12379) +* fix(resolve): remove deep import syntax handling (#12381) ([42e0d6a](https://github.com/vitejs/vite/commit/42e0d6a)), closes [#12381](https://github.com/vitejs/vite/issues/12381) * fix: print urls when dns order change (#12261) ([e57cacf](https://github.com/vitejs/vite/commit/e57cacf)), closes [#12261](https://github.com/vitejs/vite/issues/12261) * fix: throw ssr import error directly (fix #12322) (#12324) ([21ffc6a](https://github.com/vitejs/vite/commit/21ffc6a)), closes [#12322](https://github.com/vitejs/vite/issues/12322) [#12324](https://github.com/vitejs/vite/issues/12324) * fix(config): watch config even outside of root (#12321) ([7e2fff7](https://github.com/vitejs/vite/commit/7e2fff7)), closes [#12321](https://github.com/vitejs/vite/issues/12321) @@ -30,19 +93,6 @@ * fix(reporter): build.assetsDir should not impact output when in lib mode (#12108) ([b12f457](https://github.com/vitejs/vite/commit/b12f457)), closes [#12108](https://github.com/vitejs/vite/issues/12108) * fix(types): avoid resolve.exports types for bundling (#12346) ([6b40f03](https://github.com/vitejs/vite/commit/6b40f03)), closes [#12346](https://github.com/vitejs/vite/issues/12346) * fix(worker): force rollup to build worker module under watch mode (#11919) ([d464679](https://github.com/vitejs/vite/commit/d464679)), closes [#11919](https://github.com/vitejs/vite/issues/11919) -* ci: should exit when build-types-check failed (#12378) ([821d6b8](https://github.com/vitejs/vite/commit/821d6b8)), closes [#12378](https://github.com/vitejs/vite/issues/12378) - - - -## 4.2.0-beta.1 (2023-03-07) - -* feat: add `sourcemapIgnoreList` configuration option (#12174) ([f875580](https://github.com/vitejs/vite/commit/f875580)), closes [#12174](https://github.com/vitejs/vite/issues/12174) -* feat: cancellable scan during optimization (#12225) ([1e1cd3b](https://github.com/vitejs/vite/commit/1e1cd3b)), closes [#12225](https://github.com/vitejs/vite/issues/12225) -* feat: don't override `build.target` if terser is 5.16.0+ (#12197) ([9885f6f](https://github.com/vitejs/vite/commit/9885f6f)), closes [#12197](https://github.com/vitejs/vite/issues/12197) -* feat: support ESM subpath imports (#7770) ([cc92da9](https://github.com/vitejs/vite/commit/cc92da9)), closes [#7770](https://github.com/vitejs/vite/issues/7770) -* feat(css): add preprocessor option to define stylus vars & funcs (#7227) ([5968bec](https://github.com/vitejs/vite/commit/5968bec)), closes [#7227](https://github.com/vitejs/vite/issues/7227) -* feat(css): support resolving stylesheets from exports map (#7817) ([108aadf](https://github.com/vitejs/vite/commit/108aadf)), closes [#7817](https://github.com/vitejs/vite/issues/7817) -* feat(html): support env replacement (#12202) ([4f2c49f](https://github.com/vitejs/vite/commit/4f2c49f)), closes [#12202](https://github.com/vitejs/vite/issues/12202) * fix: resolve browser mapping using bare imports (fix #11208) (#11219) ([22de84f](https://github.com/vitejs/vite/commit/22de84f)), closes [#11208](https://github.com/vitejs/vite/issues/11208) [#11219](https://github.com/vitejs/vite/issues/11219) * fix: avoid null sourcePath in `server.sourcemapIgnoreList` (#12251) ([209c3bd](https://github.com/vitejs/vite/commit/209c3bd)), closes [#12251](https://github.com/vitejs/vite/issues/12251) * fix: configure proxy before subscribing to error events (#12263) ([c35e100](https://github.com/vitejs/vite/commit/c35e100)), closes [#12263](https://github.com/vitejs/vite/issues/12263) @@ -53,13 +103,6 @@ * fix(build-import-analysis): should not append ?used when css request has ?url or ?raw (#11910) ([e3f725f](https://github.com/vitejs/vite/commit/e3f725f)), closes [#11910](https://github.com/vitejs/vite/issues/11910) * fix(optimizer): don not call context.rebuild after cancel (#12264) ([520d84e](https://github.com/vitejs/vite/commit/520d84e)), closes [#12264](https://github.com/vitejs/vite/issues/12264) * fix(resolve): update `resolve.exports` to `2.0.1` to fix `*` resolution issue (#12314) ([523d6f7](https://github.com/vitejs/vite/commit/523d6f7)), closes [#12314](https://github.com/vitejs/vite/issues/12314) -* chore: upgrade to Rollup 3.18 (#12283) ([cde9191](https://github.com/vitejs/vite/commit/cde9191)), closes [#12283](https://github.com/vitejs/vite/issues/12283) -* chore(deps): update es-module-lexer (#12230) ([d617093](https://github.com/vitejs/vite/commit/d617093)), closes [#12230](https://github.com/vitejs/vite/issues/12230) - - - -## 4.2.0-beta.0 (2023-02-27) - * fix: use relative paths in `sources` for transformed source maps (#12079) ([bcbc582](https://github.com/vitejs/vite/commit/bcbc582)), closes [#12079](https://github.com/vitejs/vite/issues/12079) * fix(cli): after setting server.open, the default open is inconsistent… (#11974) ([33a38db](https://github.com/vitejs/vite/commit/33a38db)), closes [#11974](https://github.com/vitejs/vite/issues/11974) * fix(client-inject): replace globalThis.process.env.NODE_ENV (fix #12185) (#12194) ([2063648](https://github.com/vitejs/vite/commit/2063648)), closes [#12185](https://github.com/vitejs/vite/issues/12185) [#12194](https://github.com/vitejs/vite/issues/12194) @@ -70,16 +113,24 @@ * fix(optimizer): log unoptimizable entries (#12138) ([2c93e0b](https://github.com/vitejs/vite/commit/2c93e0b)), closes [#12138](https://github.com/vitejs/vite/issues/12138) * fix(server): watch env files creating and deleting (fix #12127) (#12129) ([cc3724f](https://github.com/vitejs/vite/commit/cc3724f)), closes [#12127](https://github.com/vitejs/vite/issues/12127) [#12129](https://github.com/vitejs/vite/issues/12129) * build: correct d.ts output dir in development (#12212) ([b90bc1f](https://github.com/vitejs/vite/commit/b90bc1f)), closes [#12212](https://github.com/vitejs/vite/issues/12212) -* refactor: customize ErrorOverlay (part 2) (#11830) ([4159e6f](https://github.com/vitejs/vite/commit/4159e6f)), closes [#11830](https://github.com/vitejs/vite/issues/11830) -* refactor: remove constructed sheet type style injection (#11818) ([1a6a0c2](https://github.com/vitejs/vite/commit/1a6a0c2)), closes [#11818](https://github.com/vitejs/vite/issues/11818) -* refactor(importAnalysis): cache injected env string (#12154) ([2aad552](https://github.com/vitejs/vite/commit/2aad552)), closes [#12154](https://github.com/vitejs/vite/issues/12154) -* feat: esbuild 0.17 (#11908) ([9d42f06](https://github.com/vitejs/vite/commit/9d42f06)), closes [#11908](https://github.com/vitejs/vite/issues/11908) -* feat: ignore list client injected sources (#12170) ([8a98aef](https://github.com/vitejs/vite/commit/8a98aef)), closes [#12170](https://github.com/vitejs/vite/issues/12170) -* feat: support rollup plugin this.load in plugin container context (#11469) ([abfa804](https://github.com/vitejs/vite/commit/abfa804)), closes [#11469](https://github.com/vitejs/vite/issues/11469) -* feat(cli): allow to specify sourcemap mode via --sourcemap build's option (#11505) ([ee3b90a](https://github.com/vitejs/vite/commit/ee3b90a)), closes [#11505](https://github.com/vitejs/vite/issues/11505) -* feat(reporter): report built time (#12100) ([f2ad222](https://github.com/vitejs/vite/commit/f2ad222)), closes [#12100](https://github.com/vitejs/vite/issues/12100) -* chore(define): remove inconsistent comment with import.meta.env replacement in lib mode (#12152) ([2556f88](https://github.com/vitejs/vite/commit/2556f88)), closes [#12152](https://github.com/vitejs/vite/issues/12152) -* chore(deps): update rollup to 3.17.2 (#12110) ([e54ffbd](https://github.com/vitejs/vite/commit/e54ffbd)), closes [#12110](https://github.com/vitejs/vite/issues/12110) + + +### Previous Changelogs + + +#### [4.2.0-beta.2](https://github.com/vitejs/vite/compare/v4.2.0-beta.1....v4.2.0-beta.2) (2023-03-13) + +See [4.2.0-beta.2 changelog](https://github.com/vitejs/vite/blob/v4.2.0-beta.2/packages/vite/CHANGELOG.md) + + +#### [4.2.0-beta.1](https://github.com/vitejs/vite/compare/v4.2.0-beta.0....v4.2.0-beta.1) (2023-03-07) + +See [4.2.0-beta.1 changelog](https://github.com/vitejs/vite/blob/v4.2.0-beta.1/packages/vite/CHANGELOG.md) + + +#### [4.2.0-beta.0](https://github.com/vitejs/vite/compare/v4.1.4....v4.2.0-beta.0) (2023-02-27) + +See [4.2.0-beta.0 changelog](https://github.com/vitejs/vite/blob/v4.2.0-beta.0/packages/vite/CHANGELOG.md) diff --git a/packages/vite/package.json b/packages/vite/package.json index 3d438cddc27929..1f837b12a3017b 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "4.2.0", + "version": "4.2.1", "type": "module", "license": "MIT", "author": "Evan You", @@ -69,7 +69,7 @@ "esbuild": "^0.17.5", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.18.0" + "rollup": "^3.20.0" }, "optionalDependencies": { "fsevents": "~2.3.2" diff --git a/packages/vite/rollup.config.ts b/packages/vite/rollup.config.ts index 51f40a09b72995..e241a77182c4c7 100644 --- a/packages/vite/rollup.config.ts +++ b/packages/vite/rollup.config.ts @@ -300,7 +300,7 @@ const __require = require; return { code: s.toString(), - map: s.generateMap(), + map: s.generateMap({ hires: true }), } }, } diff --git a/packages/vite/src/node/plugins/clientInjections.ts b/packages/vite/src/node/plugins/clientInjections.ts index bf46c0e42ce597..dfd3b878b6f459 100644 --- a/packages/vite/src/node/plugins/clientInjections.ts +++ b/packages/vite/src/node/plugins/clientInjections.ts @@ -13,54 +13,74 @@ const normalizedEnvEntry = normalizePath(ENV_ENTRY) * @server-only */ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { + let injectConfigValues: (code: string) => string + return { name: 'vite:client-inject', - async transform(code, id, options) { - if (id === normalizedClientEntry || id === normalizedEnvEntry) { - const resolvedServerHostname = ( - await resolveHostname(config.server.host) - ).name - const resolvedServerPort = config.server.port! - const devBase = config.base + async buildStart() { + const resolvedServerHostname = (await resolveHostname(config.server.host)) + .name + const resolvedServerPort = config.server.port! + const devBase = config.base + + const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` - const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` + let hmrConfig = config.server.hmr + hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined + const host = hmrConfig?.host || null + const protocol = hmrConfig?.protocol || null + const timeout = hmrConfig?.timeout || 30000 + const overlay = hmrConfig?.overlay !== false + const isHmrServerSpecified = !!hmrConfig?.server - let hmrConfig = config.server.hmr - hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined - const host = hmrConfig?.host || null - const protocol = hmrConfig?.protocol || null - const timeout = hmrConfig?.timeout || 30000 - const overlay = hmrConfig?.overlay !== false - const isHmrServerSpecified = !!hmrConfig?.server + // hmr.clientPort -> hmr.port + // -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port + let port = hmrConfig?.clientPort || hmrConfig?.port || null + if (config.server.middlewareMode && !isHmrServerSpecified) { + port ||= 24678 + } + + let directTarget = hmrConfig?.host || resolvedServerHostname + directTarget += `:${hmrConfig?.port || resolvedServerPort}` + directTarget += devBase - // hmr.clientPort -> hmr.port - // -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port - let port = hmrConfig?.clientPort || hmrConfig?.port || null - if (config.server.middlewareMode && !isHmrServerSpecified) { - port ||= 24678 - } + let hmrBase = devBase + if (hmrConfig?.path) { + hmrBase = path.posix.join(hmrBase, hmrConfig.path) + } - let directTarget = hmrConfig?.host || resolvedServerHostname - directTarget += `:${hmrConfig?.port || resolvedServerPort}` - directTarget += devBase + const serializedDefines = serializeDefine(config.define || {}) - let hmrBase = devBase - if (hmrConfig?.path) { - hmrBase = path.posix.join(hmrBase, hmrConfig.path) - } + const modeReplacement = escapeReplacement(config.mode) + const baseReplacement = escapeReplacement(devBase) + const definesReplacement = () => serializedDefines + const serverHostReplacement = escapeReplacement(serverHost) + const hmrProtocolReplacement = escapeReplacement(protocol) + const hmrHostnameReplacement = escapeReplacement(host) + const hmrPortReplacement = escapeReplacement(port) + const hmrDirectTargetReplacement = escapeReplacement(directTarget) + const hmrBaseReplacement = escapeReplacement(hmrBase) + const hmrTimeoutReplacement = escapeReplacement(timeout) + const hmrEnableOverlayReplacement = escapeReplacement(overlay) + injectConfigValues = (code: string) => { return code - .replace(`__MODE__`, JSON.stringify(config.mode)) - .replace(/__BASE__/g, JSON.stringify(devBase)) - .replace(`__DEFINES__`, serializeDefine(config.define || {})) - .replace(`__SERVER_HOST__`, JSON.stringify(serverHost)) - .replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol)) - .replace(`__HMR_HOSTNAME__`, JSON.stringify(host)) - .replace(`__HMR_PORT__`, JSON.stringify(port)) - .replace(`__HMR_DIRECT_TARGET__`, JSON.stringify(directTarget)) - .replace(`__HMR_BASE__`, JSON.stringify(hmrBase)) - .replace(`__HMR_TIMEOUT__`, JSON.stringify(timeout)) - .replace(`__HMR_ENABLE_OVERLAY__`, JSON.stringify(overlay)) + .replace(`__MODE__`, modeReplacement) + .replace(/__BASE__/g, baseReplacement) + .replace(`__DEFINES__`, definesReplacement) + .replace(`__SERVER_HOST__`, serverHostReplacement) + .replace(`__HMR_PROTOCOL__`, hmrProtocolReplacement) + .replace(`__HMR_HOSTNAME__`, hmrHostnameReplacement) + .replace(`__HMR_PORT__`, hmrPortReplacement) + .replace(`__HMR_DIRECT_TARGET__`, hmrDirectTargetReplacement) + .replace(`__HMR_BASE__`, hmrBaseReplacement) + .replace(`__HMR_TIMEOUT__`, hmrTimeoutReplacement) + .replace(`__HMR_ENABLE_OVERLAY__`, hmrEnableOverlayReplacement) + } + }, + transform(code, id, options) { + if (id === normalizedClientEntry || id === normalizedEnvEntry) { + return injectConfigValues(code) } else if (!options?.ssr && code.includes('process.env.NODE_ENV')) { // replace process.env.NODE_ENV instead of defining a global // for it to avoid shimming a `process` object during dev, @@ -75,6 +95,11 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin { } } +function escapeReplacement(value: string | number | boolean | null) { + const jsonValue = JSON.stringify(value) + return () => jsonValue +} + function serializeDefine(define: Record): string { let res = `{` for (const key in define) { diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index a2dd0738add156..e5e0e96bd50134 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -166,10 +166,10 @@ export const removedPureCssFilesCache = new WeakMap< Map >() -const postcssConfigCache: Record< - string, - WeakMap -> = {} +const postcssConfigCache = new WeakMap< + ResolvedConfig, + PostCSSConfigResult | null | Promise +>() function encodePublicUrlsInCSS(config: ResolvedConfig) { return config.command === 'build' @@ -188,6 +188,9 @@ export function cssPlugin(config: ResolvedConfig): Plugin { extensions: [], }) + // warm up cache for resolved postcss config + resolvePostcssConfig(config) + return { name: 'vite:css', @@ -377,7 +380,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { const getContentWithSourcemap = async (content: string) => { if (config.css?.devSourcemap) { const sourcemap = this.getCombinedSourcemap() - await injectSourcesContent(sourcemap, cleanUrl(id), config.logger) + if (sourcemap.mappings && !sourcemap.sourcesContent) { + await injectSourcesContent(sourcemap, cleanUrl(id), config.logger) + } return getCodeWithSourcemap('css', content, sourcemap) } return content @@ -801,7 +806,7 @@ async function compileCSS( const needInlineImport = code.includes('@import') const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code) const lang = id.match(CSS_LANGS_RE)?.[1] as CssLang | undefined - const postcssConfig = await resolvePostcssConfig(config, getCssDialect(lang)) + const postcssConfig = await resolvePostcssConfig(config) // 1. plain css that needs no processing if ( @@ -882,14 +887,6 @@ async function compileCSS( // 3. postcss const postcssOptions = (postcssConfig && postcssConfig.options) || {} - // for sugarss change parser - if (lang === 'sss') { - postcssOptions.parser = loadPreprocessor( - PostCssDialectLang.sss, - config.root, - ) - } - const postcssPlugins = postcssConfig && postcssConfig.plugins ? postcssConfig.plugins.slice() : [] @@ -972,6 +969,10 @@ async function compileCSS( .default(postcssPlugins) .process(code, { ...postcssOptions, + parser: + lang === 'sss' + ? loadPreprocessor(PostCssDialectLang.sss, config.root) + : postcssOptions.parser, to: source, from: source, ...(devSourcemap @@ -1137,16 +1138,10 @@ interface PostCSSConfigResult { async function resolvePostcssConfig( config: ResolvedConfig, - dialect = 'css', ): Promise { - postcssConfigCache[dialect] ??= new WeakMap< - ResolvedConfig, - PostCSSConfigResult | null - >() - - let result = postcssConfigCache[dialect].get(config) + let result = postcssConfigCache.get(config) if (result !== undefined) { - return result + return await result } // inline postcss config via vite config @@ -1162,9 +1157,7 @@ async function resolvePostcssConfig( } else { const searchPath = typeof inlineOptions === 'string' ? inlineOptions : config.root - try { - result = await postcssrc({}, searchPath) - } catch (e) { + result = postcssrc({}, searchPath).catch((e) => { if (!/No PostCSS Config found/.test(e.message)) { if (e instanceof Error) { const { name, message, stack } = e @@ -1176,11 +1169,15 @@ async function resolvePostcssConfig( throw new Error(`Failed to load PostCSS config: ${e}`) } } - result = null - } + return null + }) + // replace cached promise to result object when finished + result.then((resolved) => { + postcssConfigCache.set(config, resolved) + }) } - postcssConfigCache[dialect].set(config, result) + postcssConfigCache.set(config, result) return result } @@ -1975,7 +1972,3 @@ const preProcessors = Object.freeze({ function isPreProcessor(lang: any): lang is PreprocessLang { return lang && lang in preProcessors } - -function getCssDialect(lang: CssLang | undefined): string { - return lang === 'sss' ? 'sss' : 'css' -} diff --git a/packages/vite/src/node/plugins/dataUri.ts b/packages/vite/src/node/plugins/dataUri.ts index 8d34be298714d4..36c5c0b28b731c 100644 --- a/packages/vite/src/node/plugins/dataUri.ts +++ b/packages/vite/src/node/plugins/dataUri.ts @@ -5,59 +5,56 @@ import { URL } from 'node:url' import type { Plugin } from '../plugin' const dataUriRE = /^([^/]+\/[^;,]+)(;base64)?,([\s\S]*)$/ - -const dataUriPrefix = `/@data-uri/` +const base64RE = /base64/i +const dataUriPrefix = `\0/@data-uri/` /** * Build only, since importing from a data URI works natively. */ export function dataURIPlugin(): Plugin { - let resolved: { - [key: string]: string - } + let resolved: Map return { name: 'vite:data-uri', buildStart() { - resolved = {} + resolved = new Map() }, resolveId(id) { if (!dataUriRE.test(id)) { - return null + return } const uri = new URL(id) if (uri.protocol !== 'data:') { - return null + return } const match = uri.pathname.match(dataUriRE) if (!match) { - return null + return } const [, mime, format, data] = match if (mime !== 'text/javascript') { throw new Error( - `data URI with non-JavaScript mime type is not supported.`, + `data URI with non-JavaScript mime type is not supported. If you're using legacy JavaScript MIME types (such as 'application/javascript'), please use 'text/javascript' instead.`, ) } // decode data - const base64 = format && /base64/i.test(format.substring(1)) + const base64 = format && base64RE.test(format.substring(1)) const content = base64 ? Buffer.from(data, 'base64').toString('utf-8') : data - resolved[id] = content + resolved.set(id, content) return dataUriPrefix + id }, load(id) { if (id.startsWith(dataUriPrefix)) { - id = id.slice(dataUriPrefix.length) - return resolved[id] || null + return resolved.get(id.slice(dataUriPrefix.length)) } }, } diff --git a/packages/vite/src/node/plugins/optimizedDeps.ts b/packages/vite/src/node/plugins/optimizedDeps.ts index a40cea5c5670dd..268cafef440fff 100644 --- a/packages/vite/src/node/plugins/optimizedDeps.ts +++ b/packages/vite/src/node/plugins/optimizedDeps.ts @@ -17,7 +17,7 @@ export function optimizedDepsPlugin(config: ResolvedConfig): Plugin { return { name: 'vite:optimized-deps', - async resolveId(id, source, { ssr }) { + resolveId(id, source, { ssr }) { if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } @@ -89,7 +89,7 @@ export function optimizedDepsBuildPlugin(config: ResolvedConfig): Plugin { } }, - async resolveId(id, importer, { ssr }) { + resolveId(id, importer, { ssr }) { if (getDepsOptimizer(config, ssr)?.isOptimizedDepFile(id)) { return id } diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 39c74d5b267e93..d1b43ce08e407f 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -19,6 +19,7 @@ import { bareImportRE, cleanUrl, createDebugger, + deepImportRE, ensureVolumeInPath, fsPathFromId, getPotentialTsSrcPaths, @@ -126,6 +127,16 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { const { target: ssrTarget, noExternal: ssrNoExternal } = ssrConfig ?? {} + // In unix systems, absolute paths inside root first needs to be checked as an + // absolute URL (/root/root/path-to-file) resulting in failed checks before falling + // back to checking the path as absolute. If /root/root isn't a valid path, we can + // avoid these checks. Absolute paths inside root are common in user code as many + // paths are resolved by the user. For example for an alias. + const rootInRoot = + fs + .statSync(path.join(root, root), { throwIfNoEntry: false }) + ?.isDirectory() ?? false + return { name: 'vite:resolve', @@ -255,7 +266,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { // URL // /foo -> /fs-root/foo - if (asSrc && id.startsWith('/')) { + if (asSrc && id.startsWith('/') && (rootInRoot || !id.startsWith(root))) { const fsPath = path.resolve(root, id.slice(1)) if ((res = tryFsResolve(fsPath, options))) { isDebug && debug(`[url] ${colors.cyan(id)} -> ${colors.dim(res)}`) @@ -663,32 +674,12 @@ export function tryNodeResolve( ): PartialResolvedId | undefined { const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options - const possiblePkgIds: string[] = [] - for (let prevSlashIndex = -1; ; ) { - let slashIndex = id.indexOf('/', prevSlashIndex + 1) - if (slashIndex < 0) { - slashIndex = id.length - } - - const part = id.slice(prevSlashIndex + 1, (prevSlashIndex = slashIndex)) - if (!part) { - break - } - - // Assume path parts with an extension are not package roots, except for the - // first path part (since periods are sadly allowed in package names). - // At the same time, skip the first path part if it begins with "@" - // (since "@foo/bar" should be treated as the top-level path). - if (possiblePkgIds.length ? path.extname(part) : part[0] === '@') { - continue - } - - const possiblePkgId = id.slice(0, slashIndex) - possiblePkgIds.push(possiblePkgId) - } + // check for deep import, e.g. "my-lib/foo" + const deepMatch = id.match(deepImportRE) + const pkgId = deepMatch ? deepMatch[1] || deepMatch[2] : id let basedir: string - if (dedupe?.some((id) => possiblePkgIds.includes(id))) { + if (dedupe?.includes(pkgId)) { basedir = root } else if ( importer && @@ -700,36 +691,8 @@ export function tryNodeResolve( basedir = root } - let pkg: PackageData | undefined - let pkgId: string | undefined - // nearest package.json - let nearestPkg: PackageData | undefined - - const rootPkgId = possiblePkgIds[0] - - const rootPkg = rootPkgId - ? resolvePackageData(rootPkgId, basedir, preserveSymlinks, packageCache) - : undefined - - const nearestPkgId = [...possiblePkgIds].reverse().find((pkgId) => { - nearestPkg = resolvePackageData( - pkgId, - basedir, - preserveSymlinks, - packageCache, - )! - return nearestPkg - })! - - if (rootPkg?.data?.exports) { - pkgId = rootPkgId - pkg = rootPkg - } else { - pkgId = nearestPkgId - pkg = nearestPkg - } - - if (!pkg || !nearestPkg) { + const pkg = resolvePackageData(pkgId, basedir, preserveSymlinks, packageCache) + if (!pkg) { // if import can't be found, check if it's an optional peer dep. // if so, we can resolve to a special id that errors only when imported. if ( @@ -757,13 +720,8 @@ export function tryNodeResolve( return } - let resolveId = resolvePackageEntry - let unresolvedId = pkgId - const isDeepImport = unresolvedId !== id - if (isDeepImport) { - resolveId = resolveDeepImport - unresolvedId = '.' + id.slice(pkgId.length) - } + const resolveId = deepMatch ? resolveDeepImport : resolvePackageEntry + const unresolvedId = deepMatch ? '.' + id.slice(pkgId.length) : pkgId let resolved: string | undefined try { @@ -804,14 +762,10 @@ export function tryNodeResolve( return resolved } let resolvedId = id - if (isDeepImport) { - if (!pkg?.data.exports && path.extname(id) !== resolvedExt) { - resolvedId = resolved.id.slice(resolved.id.indexOf(id)) - isDebug && - debug( - `[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`, - ) - } + if (deepMatch && !pkg?.data.exports && path.extname(id) !== resolvedExt) { + resolvedId = resolved.id.slice(resolved.id.indexOf(id)) + isDebug && + debug(`[processResult] ${colors.cyan(id)} -> ${colors.dim(resolvedId)}`) } return { ...resolved, id: resolvedId, external: true } } @@ -828,8 +782,6 @@ export function tryNodeResolve( } const ext = path.extname(resolved) - const isCJS = - ext === '.cjs' || (ext === '.js' && nearestPkg.data.type !== 'module') if ( !options.ssrOptimizeCheck && @@ -864,7 +816,12 @@ export function tryNodeResolve( // The only optimized deps are the ones explicitly listed in the config. (!options.ssrOptimizeCheck && !isBuild && ssr) || // Only optimize non-external CJS deps during SSR by default - (ssr && !isCJS && !(include?.includes(pkgId) || include?.includes(id))) + (ssr && + !( + ext === '.cjs' || + (ext === '.js' && resolvePkg(resolved, options)?.data.type !== 'module') + ) && + !(include?.includes(pkgId) || include?.includes(id))) if (options.ssrOptimizeCheck) { return { diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index aae1a4a1423cda..197b3feeabe0bc 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -287,25 +287,40 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { : 'classic' : 'module' const workerOptions = workerType === 'classic' ? '' : ',{type: "module"}' + if (isBuild) { getDepsOptimizer(config, ssr)?.registerWorkersSource(id) if (query.inline != null) { const chunk = await bundleWorkerEntry(config, id, query) - // inline as blob data url - return { - code: `const encodedJs = "${Buffer.from(chunk.code).toString( - 'base64', - )}"; - const blob = typeof window !== "undefined" && window.Blob && new Blob([atob(encodedJs)], { type: "text/javascript;charset=utf-8" }); - export default function WorkerWrapper() { - const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); - try { - return objURL ? new ${workerConstructor}(objURL) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); - } finally { - objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL); - } - }`, + const encodedJs = `const encodedJs = "${Buffer.from( + chunk.code, + ).toString('base64')}";` + + const code = + // Using blob URL for SharedWorker results in multiple instances of a same worker + workerConstructor === 'Worker' + ? `${encodedJs} + const blob = typeof window !== "undefined" && window.Blob && new Blob([atob(encodedJs)], { type: "text/javascript;charset=utf-8" }); + export default function WorkerWrapper() { + let objURL; + try { + objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); + if (!objURL) throw '' + return new ${workerConstructor}(objURL) + } catch(e) { + return new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); + } finally { + objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL); + } + }` + : `${encodedJs} + export default function WorkerWrapper() { + return new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); + } + ` + return { + code, // Empty sourcemap to suppress Rollup warning map: { mappings: '' }, } diff --git a/packages/vite/src/node/server/sourcemap.ts b/packages/vite/src/node/server/sourcemap.ts index 4c3931fe357181..f5c57cadb5b72b 100644 --- a/packages/vite/src/node/server/sourcemap.ts +++ b/packages/vite/src/node/server/sourcemap.ts @@ -12,7 +12,7 @@ const debug = createDebugger('vite:sourcemap', { // Virtual modules should be prefixed with a null byte to avoid a // false positive "missing source" warning. We also check for certain // prefixes used for special handling in esbuildDepPlugin. -const virtualSourceRE = /^(?:\0|dep:|browser-external:)/ +const virtualSourceRE = /^(?:dep:|browser-external:|virtual:)|\0/ interface SourceMapLike { sources: string[] diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 72a62d5e095a65..02b7f6d48c80fe 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -353,17 +353,7 @@ export function prettifyUrl(url: string, root: string): string { url = removeTimestampQuery(url) const isAbsoluteFile = url.startsWith(root) if (isAbsoluteFile || url.startsWith(FS_PREFIX)) { - let file = path.relative(root, isAbsoluteFile ? url : fsPathFromId(url)) - const seg = file.split('/') - const npmIndex = seg.indexOf(`node_modules`) - const isSourceMap = file.endsWith('.map') - if (npmIndex > 0) { - file = seg[npmIndex + 1] - if (file.startsWith('@')) { - file = `${file}/${seg[npmIndex + 2]}` - } - file = `npm: ${colors.dim(file)}${isSourceMap ? ` (source map)` : ``}` - } + const file = path.relative(root, isAbsoluteFile ? url : fsPathFromId(url)) return colors.dim(file) } else { return colors.dim(url) diff --git a/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts b/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts new file mode 100644 index 00000000000000..4da121a652d0db --- /dev/null +++ b/playground/css-codesplit/__tests__/css-codesplit-consistent.spec.ts @@ -0,0 +1,15 @@ +import { beforeEach, describe, expect, test } from 'vitest' +import { findAssetFile, isBuild, startDefaultServe } from '~utils' + +beforeEach(async () => { + await startDefaultServe() +}) + +for (let i = 0; i < 5; i++) { + describe.runIf(isBuild)('css-codesplit build', () => { + test('should be consistent with same content', () => { + expect(findAssetFile(/style-.+\.css/)).toMatch('h2{color:#00f}') + expect(findAssetFile(/style2-.+\.css/)).toBe('') + }) + }) +} diff --git a/playground/css-codesplit/__tests__/css-codesplit.spec.ts b/playground/css-codesplit/__tests__/css-codesplit.spec.ts index e1b4f26fc6a9e3..6aae9619c5e0e9 100644 --- a/playground/css-codesplit/__tests__/css-codesplit.spec.ts +++ b/playground/css-codesplit/__tests__/css-codesplit.spec.ts @@ -30,7 +30,7 @@ test('style order should be consistent when style tag is inserted by JS', async describe.runIf(isBuild)('build', () => { test('should remove empty chunk', async () => { - expect(findAssetFile(/style.*\.js$/)).toBe('') + expect(findAssetFile(/style-.*\.js$/)).toBe('') expect(findAssetFile('main.*.js$')).toMatch(`/* empty css`) expect(findAssetFile('other.*.js$')).toMatch(`/* empty css`) expect(findAssetFile(/async.*\.js$/)).toBe('') diff --git a/playground/css-codesplit/style2.css b/playground/css-codesplit/style2.css new file mode 100644 index 00000000000000..2b4bb3671e654b --- /dev/null +++ b/playground/css-codesplit/style2.css @@ -0,0 +1,3 @@ +h2 { + color: blue; +} diff --git a/playground/css-codesplit/style2.js b/playground/css-codesplit/style2.js new file mode 100644 index 00000000000000..ab7ebb9eb632a6 --- /dev/null +++ b/playground/css-codesplit/style2.js @@ -0,0 +1 @@ +import './style2.css' diff --git a/playground/css-codesplit/vite.config.js b/playground/css-codesplit/vite.config.js index 962dbbb103192e..3e0d3ac3540be5 100644 --- a/playground/css-codesplit/vite.config.js +++ b/playground/css-codesplit/vite.config.js @@ -8,6 +8,7 @@ export default defineConfig({ input: { main: resolve(__dirname, './index.html'), other: resolve(__dirname, './other.js'), + style2: resolve(__dirname, './style2.js'), }, output: { manualChunks(id) { diff --git a/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/playground/optimize-deps/__tests__/optimize-deps.spec.ts index bb0841e5b72f65..f023d1c22ded8d 100644 --- a/playground/optimize-deps/__tests__/optimize-deps.spec.ts +++ b/playground/optimize-deps/__tests__/optimize-deps.spec.ts @@ -6,6 +6,7 @@ import { isBuild, isServe, page, + viteTestUrl, } from '~utils' test('default + named imports from cjs dep (react)', async () => { @@ -200,3 +201,16 @@ test.runIf(isServe)('error on builtin modules usage', () => { ]), ) }) + +test('pre bundle css require', async () => { + if (isServe) { + const response = page.waitForResponse(/@vitejs_test-dep-css-require\.js/) + await page.goto(viteTestUrl) + const content = await (await response).text() + expect(content).toMatch( + /import\s"\/@fs.+@vitejs\/test-dep-css-require\/style\.css"/, + ) + } + + expect(await getColor('.css-require')).toBe('red') +}) diff --git a/playground/optimize-deps/dep-css-require/index.cjs b/playground/optimize-deps/dep-css-require/index.cjs new file mode 100644 index 00000000000000..f3f8dd4ea41465 --- /dev/null +++ b/playground/optimize-deps/dep-css-require/index.cjs @@ -0,0 +1 @@ +require('./style.css') diff --git a/playground/optimize-deps/dep-css-require/package.json b/playground/optimize-deps/dep-css-require/package.json new file mode 100644 index 00000000000000..8e4a0aaf9f14ba --- /dev/null +++ b/playground/optimize-deps/dep-css-require/package.json @@ -0,0 +1,6 @@ +{ + "name": "@vitejs/test-dep-css-require", + "private": true, + "version": "0.0.0", + "main": "index.cjs" +} diff --git a/playground/optimize-deps/dep-css-require/style.css b/playground/optimize-deps/dep-css-require/style.css new file mode 100644 index 00000000000000..e88cf23879cc71 --- /dev/null +++ b/playground/optimize-deps/dep-css-require/style.css @@ -0,0 +1,3 @@ +.css-require { + color: red; +} diff --git a/playground/optimize-deps/index.html b/playground/optimize-deps/index.html index 921bf244c08d8d..8c5719075650ce 100644 --- a/playground/optimize-deps/index.html +++ b/playground/optimize-deps/index.html @@ -96,6 +96,9 @@

Flatten Id

Non Optimized Module isn't duplicated

+

Pre bundle css require

+
css require
+