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/LICENSE.md b/packages/vite/LICENSE.md index d9c1270715bb5a..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 diff --git a/packages/vite/package.json b/packages/vite/package.json index 2baf81a7b9ba45..9020c73de7341d 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -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", 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__/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/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/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/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: