diff --git a/package.json b/package.json index 4ae32724899a1c..47f36632fc7767 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,11 @@ "peerDependencies": { "postcss": "*" } + }, + "acorn-walk": { + "peerDependencies": { + "acorn": "*" + } } } } diff --git a/packages/vite/CHANGELOG.md b/packages/vite/CHANGELOG.md index d4da1f544b535a..c889efd5f8ad00 100644 --- a/packages/vite/CHANGELOG.md +++ b/packages/vite/CHANGELOG.md @@ -1,3 +1,11 @@ +## 3.2.5 (2022-12-05) + +* chore: cherry pick more v4 bug fixes to v3 (#11189) ([eba9b42](https://github.com/vitejs/vite/commit/eba9b42)), closes [#11189](https://github.com/vitejs/vite/issues/11189) [#10949](https://github.com/vitejs/vite/issues/10949) [#11056](https://github.com/vitejs/vite/issues/11056) [#8663](https://github.com/vitejs/vite/issues/8663) [#10958](https://github.com/vitejs/vite/issues/10958) [#11120](https://github.com/vitejs/vite/issues/11120) [#11122](https://github.com/vitejs/vite/issues/11122) [#11123](https://github.com/vitejs/vite/issues/11123) [#11132](https://github.com/vitejs/vite/issues/11132) +* chore: cherry pick v4 bug fix to v3 (#11110) ([c93a526](https://github.com/vitejs/vite/commit/c93a526)), closes [#11110](https://github.com/vitejs/vite/issues/11110) [#10941](https://github.com/vitejs/vite/issues/10941) [#10987](https://github.com/vitejs/vite/issues/10987) [#10985](https://github.com/vitejs/vite/issues/10985) [#11067](https://github.com/vitejs/vite/issues/11067) +* fix: relocated logger to respect config. (#10787) (#10967) ([bc3b5a9](https://github.com/vitejs/vite/commit/bc3b5a9)), closes [#10787](https://github.com/vitejs/vite/issues/10787) [#10967](https://github.com/vitejs/vite/issues/10967) + + + ## 3.2.4 (2022-11-15) * fix: prevent cache on optional package resolve (v3) (#10812) (#10845) ([3ba45b9](https://github.com/vitejs/vite/commit/3ba45b9)), closes [#10812](https://github.com/vitejs/vite/issues/10812) [#10845](https://github.com/vitejs/vite/issues/10845) diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md index 3cbbd7d9679694..2a8bd0c969f14d 100644 --- a/packages/vite/LICENSE.md +++ b/packages/vite/LICENSE.md @@ -566,6 +566,35 @@ Repository: https://github.com/acornjs/acorn.git --------------------------------------- +## acorn-walk +License: MIT +By: Marijn Haverbeke, Ingvar Stepanyan, Adrian Heine +Repository: https://github.com/acornjs/acorn.git + +> MIT License +> +> Copyright (C) 2012-2020 by various contributors (see AUTHORS) +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + +--------------------------------------- + ## ansi-regex License: MIT By: Sindre Sorhus @@ -1576,13 +1605,6 @@ Repository: https://github.com/http-party/node-http-proxy.git --------------------------------------- -## icss-replace-symbols -License: ISC -By: Glen Maddern -Repository: git+https://github.com/css-modules/icss-replace-symbols.git - ---------------------------------------- - ## icss-utils License: ISC By: Glen Maddern @@ -1860,6 +1882,28 @@ License: MIT By: antonk52 Repository: https://github.com/antonk52/lilconfig +> MIT License +> +> Copyright (c) 2022 Anton Kastritskiy +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. + --------------------------------------- ## loader-utils diff --git a/packages/vite/index.cjs b/packages/vite/index.cjs index 1c8aba26da6565..525b1b7e59f84d 100644 --- a/packages/vite/index.cjs +++ b/packages/vite/index.cjs @@ -15,7 +15,8 @@ const asyncFunctions = [ 'resolveConfig', 'optimizeDeps', 'formatPostcssSourceMap', - 'loadConfigFromFile' + 'loadConfigFromFile', + 'preprocessCSS' ] asyncFunctions.forEach((name) => { module.exports[name] = (...args) => diff --git a/packages/vite/package.json b/packages/vite/package.json index 6891d1432de591..3f3c15934cc197 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -1,6 +1,6 @@ { "name": "vite", - "version": "3.2.4", + "version": "3.2.5", "type": "module", "license": "MIT", "author": "Evan You", @@ -79,6 +79,7 @@ "@rollup/plugin-typescript": "^8.5.0", "@rollup/pluginutils": "^4.2.1", "acorn": "^8.8.1", + "acorn-walk": "^8.2.0", "cac": "^6.7.14", "chokidar": "^3.5.3", "connect": "^3.7.0", @@ -109,7 +110,7 @@ "picomatch": "^2.3.1", "postcss-import": "^15.0.0", "postcss-load-config": "^4.0.1", - "postcss-modules": "^5.0.0", + "postcss-modules": "^6.0.0", "resolve.exports": "^1.1.0", "sirv": "^2.0.2", "source-map-js": "^1.0.2", diff --git a/packages/vite/src/client/overlay.ts b/packages/vite/src/client/overlay.ts index 57171b7ec13c0b..91ad9cc6fb95df 100644 --- a/packages/vite/src/client/overlay.ts +++ b/packages/vite/src/client/overlay.ts @@ -178,6 +178,7 @@ export class ErrorOverlay extends HTMLElement { } else { let curIndex = 0 let match: RegExpExecArray | null + fileRE.lastIndex = 0 while ((match = fileRE.exec(text))) { const { 0: file, index } = match if (index != null) { diff --git a/packages/vite/src/node/__tests__/config.spec.ts b/packages/vite/src/node/__tests__/config.spec.ts index b32960497e3af4..0b8aaf79e6d47c 100644 --- a/packages/vite/src/node/__tests__/config.spec.ts +++ b/packages/vite/src/node/__tests__/config.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from 'vitest' import type { InlineConfig } from '..' -import type { UserConfig, UserConfigExport } from '../config' +import type { PluginOption, UserConfig, UserConfigExport } from '../config' import { resolveConfig } from '../config' import { resolveEnvPrefix } from '../env' import { mergeConfig } from '../publicUtils' @@ -266,3 +266,51 @@ describe('preview config', () => { }) }) }) + +describe('resolveConfig', () => { + const keepScreenMergePlugin = (): PluginOption => { + return { + name: 'vite-plugin-keep-screen-merge', + config() { + return { clearScreen: false } + } + } + } + + const keepScreenOverridePlugin = (): PluginOption => { + return { + name: 'vite-plugin-keep-screen-override', + config(config) { + config.clearScreen = false + } + } + } + + test('plugin merges `clearScreen` option', async () => { + const config1: InlineConfig = { plugins: [keepScreenMergePlugin()] } + const config2: InlineConfig = { + plugins: [keepScreenMergePlugin()], + clearScreen: true + } + + const results1 = await resolveConfig(config1, 'build') + const results2 = await resolveConfig(config2, 'build') + + expect(results1.clearScreen).toBe(false) + expect(results2.clearScreen).toBe(false) + }) + + test('plugin overrides `clearScreen` option', async () => { + const config1: InlineConfig = { plugins: [keepScreenOverridePlugin()] } + const config2: InlineConfig = { + plugins: [keepScreenOverridePlugin()], + clearScreen: true + } + + const results1 = await resolveConfig(config1, 'build') + const results2 = await resolveConfig(config2, 'build') + + expect(results1.clearScreen).toBe(false) + expect(results2.clearScreen).toBe(false) + }) +}) diff --git a/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts b/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts index d1c98348c5c453..00c6f99c869cb3 100644 --- a/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/esbuild.spec.ts @@ -1,6 +1,10 @@ import { describe, expect, test } from 'vitest' import type { ResolvedConfig, UserConfig } from '../../config' -import { resolveEsbuildTranspileOptions } from '../../plugins/esbuild' +import { + ESBuildTransformResult, + resolveEsbuildTranspileOptions, + transformWithEsbuild +} from '../../plugins/esbuild' describe('resolveEsbuildTranspileOptions', () => { test('resolve default', () => { @@ -230,6 +234,16 @@ describe('resolveEsbuildTranspileOptions', () => { }) }) +describe('transformWithEsbuild', () => { + test('not throw on inline sourcemap', async () => { + const result = await transformWithEsbuild(`const foo = 'bar'`, '', { + sourcemap: 'inline' + }) + expect(result?.code).toBeTruthy() + expect(result?.map).toBeTruthy() + }) +}) + /** * Helper for `resolveEsbuildTranspileOptions` to created resolved config with types. * Note: The function only uses `build.target`, `build.minify` and `esbuild` options. diff --git a/packages/vite/src/node/__tests__/plugins/importGlob/__snapshots__/fixture.test.ts.snap b/packages/vite/src/node/__tests__/plugins/importGlob/__snapshots__/fixture.test.ts.snap index e638850c4ce0b0..e6584c954a78f6 100644 --- a/packages/vite/src/node/__tests__/plugins/importGlob/__snapshots__/fixture.test.ts.snap +++ b/packages/vite/src/node/__tests__/plugins/importGlob/__snapshots__/fixture.test.ts.snap @@ -3,38 +3,100 @@ exports[`fixture > transform 1`] = ` "import * as __vite_glob_1_0 from \\"./modules/a.ts\\";import * as __vite_glob_1_1 from \\"./modules/b.ts\\";import * as __vite_glob_1_2 from \\"./modules/index.ts\\";import { name as __vite_glob_3_0 } from \\"./modules/a.ts\\";import { name as __vite_glob_3_1 } from \\"./modules/b.ts\\";import { name as __vite_glob_3_2 } from \\"./modules/index.ts\\";import { default as __vite_glob_5_0 } from \\"./modules/a.ts?raw\\";import { default as __vite_glob_5_1 } from \\"./modules/b.ts?raw\\";import \\"types/importMeta\\"; export const basic = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\")}); -export const basicEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_1_0,\\"./modules/b.ts\\": __vite_glob_1_1,\\"./modules/index.ts\\": __vite_glob_1_2}); +export const basicEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_1_0,\\"./modules/b.ts\\": __vite_glob_1_1,\\"./modules/index.ts\\": __vite_glob_1_2 + +}); export const ignore = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\")}); -export const namedEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_3_0,\\"./modules/b.ts\\": __vite_glob_3_1,\\"./modules/index.ts\\": __vite_glob_3_2}); -export const namedDefault = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\").then(m => m[\\"default\\"]),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\").then(m => m[\\"default\\"]),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\").then(m => m[\\"default\\"])}); -export const eagerAs = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_5_0,\\"./modules/b.ts\\": __vite_glob_5_1}); -export const rawImportModule = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts?raw\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts?raw\\")}); -export const excludeSelf = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts\\")}); +export const namedEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_3_0,\\"./modules/b.ts\\": __vite_glob_3_1,\\"./modules/index.ts\\": __vite_glob_3_2 + + +}); +export const namedDefault = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\").then(m => m[\\"default\\"]),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\").then(m => m[\\"default\\"]),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\").then(m => m[\\"default\\"]) + +}); +export const eagerAs = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_5_0,\\"./modules/b.ts\\": __vite_glob_5_1 + + +}); +export const rawImportModule = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts?raw\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts?raw\\") + + +}); +export const excludeSelf = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts\\") + +}); export const customQueryString = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?custom\\")}); -export const customQueryObject = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?foo=bar&raw=true\\")}); -export const parent = /* #__PURE__ */ Object.assign({}); -export const rootMixedRelative = /* #__PURE__ */ Object.assign({\\"/css.spec.ts\\": () => import(\\"../../css.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/define.spec.ts\\": () => import(\\"../../define.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/esbuild.spec.ts\\": () => import(\\"../../esbuild.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/import.spec.ts\\": () => import(\\"../../import.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/index.ts\\": () => import(\\"../fixture-b/index.ts?url\\").then(m => m[\\"default\\"])}); -export const cleverCwd1 = /* #__PURE__ */ Object.assign({\\"./node_modules/framework/pages/hello.page.js\\": () => import(\\"./node_modules/framework/pages/hello.page.js\\")}); -export const cleverCwd2 = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"../fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts\\"),\\"../fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts\\")}); +export const customQueryObject = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?foo=bar&raw=true\\") + + + + +}); +export const parent = /* #__PURE__ */ Object.assign({ + +}); +export const rootMixedRelative = /* #__PURE__ */ Object.assign({\\"/css.spec.ts\\": () => import(\\"../../css.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/define.spec.ts\\": () => import(\\"../../define.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/esbuild.spec.ts\\": () => import(\\"../../esbuild.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/import.spec.ts\\": () => import(\\"../../import.spec.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts?url\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/index.ts\\": () => import(\\"../fixture-b/index.ts?url\\").then(m => m[\\"default\\"]) + + +}); +export const cleverCwd1 = /* #__PURE__ */ Object.assign({\\"./node_modules/framework/pages/hello.page.js\\": () => import(\\"./node_modules/framework/pages/hello.page.js\\") + +}); +export const cleverCwd2 = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"../fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts\\"),\\"../fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts\\") + + + +}); " `; exports[`fixture > transform with restoreQueryExtension 1`] = ` "import * as __vite_glob_1_0 from \\"./modules/a.ts\\";import * as __vite_glob_1_1 from \\"./modules/b.ts\\";import * as __vite_glob_1_2 from \\"./modules/index.ts\\";import { name as __vite_glob_3_0 } from \\"./modules/a.ts\\";import { name as __vite_glob_3_1 } from \\"./modules/b.ts\\";import { name as __vite_glob_3_2 } from \\"./modules/index.ts\\";import { default as __vite_glob_5_0 } from \\"./modules/a.ts?raw\\";import { default as __vite_glob_5_1 } from \\"./modules/b.ts?raw\\";import \\"types/importMeta\\"; export const basic = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\")}); -export const basicEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_1_0,\\"./modules/b.ts\\": __vite_glob_1_1,\\"./modules/index.ts\\": __vite_glob_1_2}); +export const basicEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_1_0,\\"./modules/b.ts\\": __vite_glob_1_1,\\"./modules/index.ts\\": __vite_glob_1_2 + +}); export const ignore = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\")}); -export const namedEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_3_0,\\"./modules/b.ts\\": __vite_glob_3_1,\\"./modules/index.ts\\": __vite_glob_3_2}); -export const namedDefault = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\").then(m => m[\\"default\\"]),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\").then(m => m[\\"default\\"]),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\").then(m => m[\\"default\\"])}); -export const eagerAs = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_5_0,\\"./modules/b.ts\\": __vite_glob_5_1}); -export const rawImportModule = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts?raw\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts?raw\\")}); -export const excludeSelf = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts\\")}); +export const namedEager = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_3_0,\\"./modules/b.ts\\": __vite_glob_3_1,\\"./modules/index.ts\\": __vite_glob_3_2 + + +}); +export const namedDefault = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\").then(m => m[\\"default\\"]),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\").then(m => m[\\"default\\"]),\\"./modules/index.ts\\": () => import(\\"./modules/index.ts\\").then(m => m[\\"default\\"]) + +}); +export const eagerAs = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": __vite_glob_5_0,\\"./modules/b.ts\\": __vite_glob_5_1 + + +}); +export const rawImportModule = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts?raw\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts?raw\\") + + +}); +export const excludeSelf = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts\\") + +}); export const customQueryString = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?custom&lang.ts\\")}); -export const customQueryObject = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?foo=bar&raw=true&lang.ts\\")}); -export const parent = /* #__PURE__ */ Object.assign({}); -export const rootMixedRelative = /* #__PURE__ */ Object.assign({\\"/css.spec.ts\\": () => import(\\"../../css.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/define.spec.ts\\": () => import(\\"../../define.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/esbuild.spec.ts\\": () => import(\\"../../esbuild.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/import.spec.ts\\": () => import(\\"../../import.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/index.ts\\": () => import(\\"../fixture-b/index.ts?url&lang.ts\\").then(m => m[\\"default\\"])}); -export const cleverCwd1 = /* #__PURE__ */ Object.assign({\\"./node_modules/framework/pages/hello.page.js\\": () => import(\\"./node_modules/framework/pages/hello.page.js\\")}); -export const cleverCwd2 = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"../fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts\\"),\\"../fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts\\")}); +export const customQueryObject = /* #__PURE__ */ Object.assign({\\"./sibling.ts\\": () => import(\\"./sibling.ts?foo=bar&raw=true&lang.ts\\") + + + + +}); +export const parent = /* #__PURE__ */ Object.assign({ + +}); +export const rootMixedRelative = /* #__PURE__ */ Object.assign({\\"/css.spec.ts\\": () => import(\\"../../css.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/define.spec.ts\\": () => import(\\"../../define.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/esbuild.spec.ts\\": () => import(\\"../../esbuild.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/import.spec.ts\\": () => import(\\"../../import.spec.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts?url&lang.ts\\").then(m => m[\\"default\\"]),\\"/importGlob/fixture-b/index.ts\\": () => import(\\"../fixture-b/index.ts?url&lang.ts\\").then(m => m[\\"default\\"]) + + +}); +export const cleverCwd1 = /* #__PURE__ */ Object.assign({\\"./node_modules/framework/pages/hello.page.js\\": () => import(\\"./node_modules/framework/pages/hello.page.js\\") + +}); +export const cleverCwd2 = /* #__PURE__ */ Object.assign({\\"./modules/a.ts\\": () => import(\\"./modules/a.ts\\"),\\"./modules/b.ts\\": () => import(\\"./modules/b.ts\\"),\\"../fixture-b/a.ts\\": () => import(\\"../fixture-b/a.ts\\"),\\"../fixture-b/b.ts\\": () => import(\\"../fixture-b/b.ts\\") + + + +}); " `; diff --git a/packages/vite/src/node/__tests__/plugins/importGlob/fixture.test.ts b/packages/vite/src/node/__tests__/plugins/importGlob/fixture.test.ts index 7b3206df31e82a..d5ac651bd54747 100644 --- a/packages/vite/src/node/__tests__/plugins/importGlob/fixture.test.ts +++ b/packages/vite/src/node/__tests__/plugins/importGlob/fixture.test.ts @@ -22,6 +22,24 @@ describe('fixture', async () => { ).toMatchSnapshot() }) + it('preserve line count', async () => { + const getTransformedLineCount = async (code: string) => + (await transformGlobImport(code, 'virtual:module', root, resolveId))?.s + .toString() + .split('\n').length + + expect(await getTransformedLineCount("import.meta.glob('./*.js')")).toBe(1) + expect( + await getTransformedLineCount( + ` + import.meta.glob( + './*.js' + ) + `.trim() + ) + ).toBe(3) + }) + it('virtual modules', async () => { const root = resolve(__dirname, './fixture-a') const code = [ diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 0019cc0ddebe2a..77fc70aeea48e0 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -408,12 +408,6 @@ export async function resolveConfig( } } - // Define logger - const logger = createLogger(config.logLevel, { - allowClearScreen: config.clearScreen, - customLogger: config.customLogger - }) - // user config may provide an alternative mode. But --mode has a higher priority mode = inlineConfig.mode || config.mode || mode configEnv.mode = mode @@ -457,6 +451,12 @@ export async function resolveConfig( config.build.commonjsOptions = { include: [] } } + // Define logger + const logger = createLogger(config.logLevel, { + allowClearScreen: config.clearScreen, + customLogger: config.customLogger + }) + // resolve root const resolvedRoot = normalizePath( config.root ? path.resolve(config.root) : process.cwd() @@ -529,9 +529,11 @@ export async function resolveConfig( ? path.join(path.dirname(pkgPath), `node_modules/.vite`) : path.join(resolvedRoot, `.vite`) - const assetsFilter = config.assetsInclude - ? createFilter(config.assetsInclude) - : () => false + const assetsFilter = + config.assetsInclude && + (!(config.assetsInclude instanceof Array) || config.assetsInclude.length) + ? createFilter(config.assetsInclude) + : () => false // create an internal resolver to be used in special scenarios, e.g. // optimizer & handling css @imports diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 94447b9403393b..a1d6c1b86c6291 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -708,7 +708,8 @@ export async function addManuallyIncludedOptimizeDeps( const resolve = config.createResolver({ asSrc: false, scan: true, - ssrOptimizeCheck: ssr + ssrOptimizeCheck: ssr, + ssrConfig: config.ssr }) for (const id of [...optimizeDepsInclude, ...extra]) { // normalize 'foo >bar` as 'foo > bar' to prevent same id being added diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 7764705d76694c..3bacfa02abe043 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -531,11 +531,8 @@ function extractImportPaths(code: string) { let js = '' let m + importsRE.lastIndex = 0 while ((m = importsRE.exec(code)) != null) { - // This is necessary to avoid infinite loops with zero-width matches - if (m.index === importsRE.lastIndex) { - importsRE.lastIndex++ - } js += `\nimport ${m[1]}` } return js diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 8a74736715bd9c..ee96fef25cc343 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -75,6 +75,7 @@ export function renderAssetUrlInJS( // In both cases, the wrapping should already be fine + assetUrlRE.lastIndex = 0 while ((match = assetUrlRE.exec(code))) { s ||= new MagicString(code) const [full, hash, postfix = ''] = match @@ -101,6 +102,7 @@ export function renderAssetUrlInJS( // Replace __VITE_PUBLIC_ASSET__5aa0ddc0__ with absolute paths const publicAssetUrlMap = publicAssetUrlCache.get(config)! + publicAssetUrlRE.lastIndex = 0 while ((match = publicAssetUrlRE.exec(code))) { s ||= new MagicString(code) const [full, hash] = match diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index a582ba52404b20..5bc03bcd260153 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -907,9 +907,9 @@ async function compileCSS( modulesOptions.getJSON(cssFileName, _modules, outputFileName) } }, - async resolve(id: string) { + async resolve(id: string, importer: string) { for (const key of getCssResolversKeys(atImportResolvers)) { - const resolved = await atImportResolvers[key](id) + const resolved = await atImportResolvers[key](id, importer) if (resolved) { return path.resolve(resolved) } diff --git a/packages/vite/src/node/plugins/define.ts b/packages/vite/src/node/plugins/define.ts index e683ba4d0175db..30ea8171db90db 100644 --- a/packages/vite/src/node/plugins/define.ts +++ b/packages/vite/src/node/plugins/define.ts @@ -85,7 +85,7 @@ export function definePlugin(config: ResolvedConfig): Plugin { .join('|') + // Mustn't be followed by a char that can be part of an identifier // or an assignment (but allow equality operators) - ')(?![\\p{L}\\p{N}_$]|\\s*?=[^=])', + ')(?:(?<=\\.)|(?![\\p{L}\\p{N}_$]|\\s*?=[^=]))', 'gu' ) : null diff --git a/packages/vite/src/node/plugins/esbuild.ts b/packages/vite/src/node/plugins/esbuild.ts index 43c319f2713761..4c698f652d3452 100644 --- a/packages/vite/src/node/plugins/esbuild.ts +++ b/packages/vite/src/node/plugins/esbuild.ts @@ -145,9 +145,10 @@ export async function transformWithEsbuild( inMap as RawSourceMap ]) as SourceMap } else { - map = resolvedOptions.sourcemap - ? JSON.parse(result.map) - : { mappings: '' } + map = + resolvedOptions.sourcemap && resolvedOptions.sourcemap !== 'inline' + ? JSON.parse(result.map) + : { mappings: '' } } if (Array.isArray(map.sources)) { map.sources = map.sources.map((it) => toUpperCaseDriveLetter(it)) diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index c13a334ba7b7da..18e7fd75daf4e6 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -396,6 +396,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { const cleanCode = stripLiteral(scriptNode.value) let match: RegExpExecArray | null + inlineImportRE.lastIndex = 0 while ((match = inlineImportRE.exec(cleanCode))) { const { 1: url, index } = match const startUrl = cleanCode.indexOf(url, index) @@ -777,6 +778,7 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { // no use assets plugin because it will emit file let match: RegExpExecArray | null let s: MagicString | undefined + inlineCSSRE.lastIndex = 0 while ((match = inlineCSSRE.exec(result))) { s ||= new MagicString(result) const { 0: full, 1: scopedName } = match diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index f0aac1e8dc98b5..e3e6bf92ab979a 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -13,6 +13,7 @@ import type { TemplateLiteral } from 'estree' import { parseExpressionAt } from 'acorn' +import { findNodeAt } from 'acorn-walk' import MagicString from 'magic-string' import fg from 'fast-glob' import { stringifyQuery } from 'ufo' @@ -154,15 +155,9 @@ export async function parseImportGlob( } } - if (ast.type === 'SequenceExpression') - ast = ast.expressions[0] as CallExpression - - // immediate property access, call expression is nested - // import.meta.glob(...)['prop'] - if (ast.type === 'MemberExpression') ast = ast.object as CallExpression - - if (ast.type !== 'CallExpression') - throw err(`Expect CallExpression, got ${ast.type}`) + const found = findNodeAt(ast as any, start, undefined, 'CallExpression') + if (!found) throw err(`Expect CallExpression, got ${ast.type}`) + ast = found.node as unknown as CallExpression if (ast.arguments.length < 1 || ast.arguments.length > 2) throw err(`Expected 1-2 arguments, but got ${ast.arguments.length}`) @@ -438,9 +433,15 @@ export async function transformGlobImport( files.forEach((i) => matchedFiles.add(i)) + const originalLineBreakCount = + code.slice(start, end).match(/\n/g)?.length ?? 0 + const lineBreaks = + originalLineBreakCount > 0 + ? '\n'.repeat(originalLineBreakCount) + : '' const replacement = `/* #__PURE__ */ Object.assign({${objectProps.join( ',' - )}})` + )}${lineBreaks}})` s.overwrite(start, end, replacement) return staticImports diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 94b6562b1b5706..716559c11d08cf 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -806,11 +806,11 @@ export function tryNodeResolve( : OPTIMIZABLE_ENTRY_RE.test(resolved) let exclude = depsOptimizer?.options.exclude - let include = depsOptimizer?.options.exclude + let include = depsOptimizer?.options.include if (options.ssrOptimizeCheck) { // we don't have the depsOptimizer exclude = options.ssrConfig?.optimizeDeps?.exclude - include = options.ssrConfig?.optimizeDeps?.exclude + include = options.ssrConfig?.optimizeDeps?.include } const skipOptimization = @@ -819,7 +819,10 @@ export function tryNodeResolve( exclude?.includes(pkgId) || exclude?.includes(nestedPath) || SPECIAL_QUERY_RE.test(resolved) || - (!isBuild && ssr) || + // During dev SSR, we don't have a way to reload the module graph if + // a non-optimized dep is found. So we need to skip optimization here. + // 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 && diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index 02d0dd3d74ece4..31b79cac8ca8d5 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -336,6 +336,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { let match: RegExpExecArray | null s = new MagicString(code) + workerAssetUrlRE.lastIndex = 0 // Replace "__VITE_WORKER_ASSET__5aa0ddc0__" using relative paths const workerMap = workerCache.get(config.mainConfig || config)! diff --git a/packages/vite/src/node/server/middlewares/htmlFallback.ts b/packages/vite/src/node/server/middlewares/htmlFallback.ts index 314f4ec2a63e7f..7976d24c0b09f0 100644 --- a/packages/vite/src/node/server/middlewares/htmlFallback.ts +++ b/packages/vite/src/node/server/middlewares/htmlFallback.ts @@ -14,17 +14,15 @@ export function htmlFallbackMiddleware( rewrites: [ { from: /\/$/, - to({ parsedUrl }: any) { + to({ parsedUrl, request }: any) { const rewritten = decodeURIComponent(parsedUrl.pathname) + 'index.html' if (fs.existsSync(path.join(root, rewritten))) { return rewritten - } else { - if (spaFallback) { - return `/index.html` - } } + + return spaFallback ? `/index.html` : request.url } } ] diff --git a/playground/define/__tests__/define.spec.ts b/playground/define/__tests__/define.spec.ts index 43787ef0adb112..8c27686bce1703 100644 --- a/playground/define/__tests__/define.spec.ts +++ b/playground/define/__tests__/define.spec.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest' import viteConfig from '../vite.config' -import { page } from '~utils' +import { isBuild, page } from '~utils' test('string', async () => { const defines = viteConfig.define @@ -44,4 +44,10 @@ test('string', async () => { expect(await page.textContent('.define-in-dep')).toBe( defines.__STRINGIFIED_OBJ__ ) + expect(await page.textContent('.import-meta-env-undefined')).toBe( + isBuild ? '({}).UNDEFINED' : 'import.meta.env.UNDEFINED' + ) + expect(await page.textContent('.process-env-undefined')).toBe( + isBuild ? '({}).UNDEFINED' : 'process.env.UNDEFINED' + ) }) diff --git a/playground/define/commonjs-dep/index.js b/playground/define/commonjs-dep/index.js index 23e0bf1b32e32f..9be5641e04b844 100644 --- a/playground/define/commonjs-dep/index.js +++ b/playground/define/commonjs-dep/index.js @@ -1 +1,5 @@ -module.exports = { defined: __STRINGIFIED_OBJ__ } +module.exports = { + defined: __STRINGIFIED_OBJ__, + importMetaEnvUndefined: 'import.meta.env.UNDEFINED', + processEnvUndefined: 'process.env.UNDEFINED' +} diff --git a/playground/define/index.html b/playground/define/index.html index c4f4c598aba563..06b2f4f9479d38 100644 --- a/playground/define/index.html +++ b/playground/define/index.html @@ -17,6 +17,10 @@

Define

define variable in html: __EXP__

import json:

define in dep:

+

+ import.meta.env.UNDEFINED: +

+

process.env.UNDEFINED: