diff --git a/docs/config/build-options.md b/docs/config/build-options.md index 9bff0380a..891b2e958 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -130,7 +130,7 @@ In this case, you need to set `build.cssTarget` to `chrome61` to prevent vite fr ## build.cssMinify - **Type:** `boolean | 'esbuild' | 'lightningcss'` -- **Default:** the same as [`build.minify`](#build-minify) +- **Default:** the same as [`build.minify`](#build-minify) for client, `'esbuild'` for SSR This option allows users to override CSS minification specifically instead of defaulting to `build.minify`, so you can configure minification for JS and CSS separately. Vite uses `esbuild` by default to minify CSS. Set the option to `'lightningcss'` to use [Lightning CSS](https://lightningcss.dev/minification.html) instead. If selected, it can be configured using [`css.lightningcss`](./shared-options.md#css-lightningcss). diff --git a/docs/config/shared-options.md b/docs/config/shared-options.md index 3502d31a2..0ea4aeeb6 100644 --- a/docs/config/shared-options.md +++ b/docs/config/shared-options.md @@ -217,7 +217,7 @@ Inline PostCSS config or a custom directory to search PostCSS config from (defau For inline PostCSS config, it expects the same format as `postcss.config.js`. But for `plugins` property, only [array format](https://github.com/postcss/postcss-load-config/blob/main/README.md#array) can be used. -The search is done using [postcss-load-config](https://github.com/postcss/postcss-load-config) and only the supported config file names are loaded. +The search is done using [postcss-load-config](https://github.com/postcss/postcss-load-config) and only the supported config file names are loaded. Config files outside the workspace root (or the [project root](/guide/#index-html-and-project-root) if no workspace is found) are not searched by default. You can specify a custom path outside of the root to load the specific config file instead if needed. Note if an inline config is provided, Vite will not search for other PostCSS config sources. @@ -345,12 +345,12 @@ Whether to support named imports from `.json` files. ## json.stringify -- **Type:** `boolean` -- **Default:** `false` +- **Type:** `boolean | 'auto'` +- **Default:** `'auto'` If set to `true`, imported JSON will be transformed into `export default JSON.parse("...")` which is significantly more performant than Object literals, especially when the JSON file is large. -Enabling this disables named imports. +If set to `'auto'`, the data will be stringified only if [the data is bigger than 10kB](https://v8.dev/blog/cost-of-javascript-2019#json:~:text=A%20good%20rule%20of%20thumb%20is%20to%20apply%20this%20technique%20for%20objects%20of%2010%20kB%20or%20larger). ## esbuild diff --git a/docs/guide/api-javascript.md b/docs/guide/api-javascript.md index 5a883c75e..c0a7a3d50 100644 --- a/docs/guide/api-javascript.md +++ b/docs/guide/api-javascript.md @@ -128,8 +128,8 @@ interface ViteDevServer { */ moduleGraph: ModuleGraph /** - * The resolved urls Vite prints on the CLI. null in middleware mode or - * before `server.listen` is called. + * The resolved urls Vite prints on the CLI (URL-encoded). Returns `null` + * in middleware mode or if the server is not listening on any port. */ resolvedUrls: ResolvedServerUrls | null /** @@ -274,8 +274,8 @@ interface PreviewServer { */ httpServer: http.Server /** - * The resolved urls Vite prints on the CLI. - * null before server is listening. + * The resolved urls Vite prints on the CLI (URL-encoded). Returns `null` + * if the server is not listening on any port. */ resolvedUrls: ResolvedServerUrls | null /** diff --git a/docs/guide/migration.md b/docs/guide/migration.md index 003b31f4b..f4c11d580 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -10,6 +10,27 @@ Some internal APIs have been removed due to changes in Vite's implementation. If The experimental Vite Runtime API evolved into the Module Runner API, released in Vite 6 as part of the new experimental [Environment API](/guide/api-environment). Given that the feature was experimental the removal of the previous API introduced in Vite 5.1 isn't a breaking change, but users will need to update their use to the Module Runner equivalent as part of migrating to Vite 6. +## General Changes + +### JSON stringify + +In Vite 5, when [`json.stringify: true`](/config/shared-options#json-stringify) is set, [`json.namedExports`](/config/shared-options#json-namedexports) was disabled. + +From Vite 6, even when `json.stringify: true` is set, `json.namedExports` is not disabled and the value is respected. If you wish to achieve the previous behavior, you can set `json.namedExports: false`. + +Vite 6 also introduces a new default value for `json.stringify` which is `'auto'`, which will only stringify large JSON files. To disable this behavior, set `json.stringify: false`. + +## Advanced + +There are other breaking changes which only affect few users. + +- [[#15637] fix!: default `build.cssMinify` to `'esbuild'` for SSR](https://github.com/vitejs/vite/pull/15637) + - [`build.cssMinify`](/config/build-options#build-cssminify) is now enabled by default even for SSR builds. +- [[#18209] refactor!: bump minimal terser version to 5.16.0](https://github.com/vitejs/vite/pull/18209) + - Minimal supported terser version for [`build.minify: 'terser'`](/config/build-options#build-minify) was bumped to 5.16.0 from 5.4.0. +- [[#18243] chore(deps)!: migrate `fast-glob` to `tinyglobby`](https://github.com/vitejs/vite/pull/18243) + - Range braces (`{01..03}` ⇒ `['01', '02', '03']`) and incremental braces (`{2..8..2}` ⇒ `['2', '4', '6', '8']`) are no longer supported in globs. + ## Migration from v4 Check the [Migration from v4 Guide](https://v5.vite.dev/guide/migration.html) in the Vite v5 docs first to see the needed changes to port your app to Vite 5, and then proceed with the changes on this page. diff --git a/package.json b/package.json index a48ecc09c..921cf3d0a 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "playwright-chromium": "^1.48.1", "prettier": "3.3.3", "rimraf": "^5.0.10", - "rollup": "^4.22.5", + "rollup": "^4.23.0", "rollup-plugin-esbuild": "^6.1.1", "simple-git-hooks": "^2.11.1", "tslib": "^2.8.0", diff --git a/packages/create-vite/template-preact-ts/tsconfig.app.json b/packages/create-vite/template-preact-ts/tsconfig.app.json index 634dfa3cf..00a7cc1e9 100644 --- a/packages/create-vite/template-preact-ts/tsconfig.app.json +++ b/packages/create-vite/template-preact-ts/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", diff --git a/packages/create-vite/template-preact-ts/tsconfig.node.json b/packages/create-vite/template-preact-ts/tsconfig.node.json index 9dad70185..abcd7f0da 100644 --- a/packages/create-vite/template-preact-ts/tsconfig.node.json +++ b/packages/create-vite/template-preact-ts/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", diff --git a/packages/create-vite/template-qwik-ts/tsconfig.app.json b/packages/create-vite/template-qwik-ts/tsconfig.app.json index 0052c0d84..0d65579a4 100644 --- a/packages/create-vite/template-qwik-ts/tsconfig.app.json +++ b/packages/create-vite/template-qwik-ts/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", diff --git a/packages/create-vite/template-qwik-ts/tsconfig.node.json b/packages/create-vite/template-qwik-ts/tsconfig.node.json index 9dad70185..abcd7f0da 100644 --- a/packages/create-vite/template-qwik-ts/tsconfig.node.json +++ b/packages/create-vite/template-qwik-ts/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", diff --git a/packages/create-vite/template-react-ts/tsconfig.app.json b/packages/create-vite/template-react-ts/tsconfig.app.json index 5a2def4b7..f867de0dd 100644 --- a/packages/create-vite/template-react-ts/tsconfig.app.json +++ b/packages/create-vite/template-react-ts/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], diff --git a/packages/create-vite/template-react-ts/tsconfig.node.json b/packages/create-vite/template-react-ts/tsconfig.node.json index 9dad70185..abcd7f0da 100644 --- a/packages/create-vite/template-react-ts/tsconfig.node.json +++ b/packages/create-vite/template-react-ts/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", diff --git a/packages/create-vite/template-solid-ts/tsconfig.app.json b/packages/create-vite/template-solid-ts/tsconfig.app.json index c6ab232ad..c811fcbb3 100644 --- a/packages/create-vite/template-solid-ts/tsconfig.app.json +++ b/packages/create-vite/template-solid-ts/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", diff --git a/packages/create-vite/template-solid-ts/tsconfig.node.json b/packages/create-vite/template-solid-ts/tsconfig.node.json index 9dad70185..abcd7f0da 100644 --- a/packages/create-vite/template-solid-ts/tsconfig.node.json +++ b/packages/create-vite/template-solid-ts/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", diff --git a/packages/create-vite/template-vue-ts/tsconfig.app.json b/packages/create-vite/template-vue-ts/tsconfig.app.json index 909eec5c6..cb88a5a6c 100644 --- a/packages/create-vite/template-vue-ts/tsconfig.app.json +++ b/packages/create-vite/template-vue-ts/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", diff --git a/packages/create-vite/template-vue-ts/tsconfig.node.json b/packages/create-vite/template-vue-ts/tsconfig.node.json index 9dad70185..abcd7f0da 100644 --- a/packages/create-vite/template-vue-ts/tsconfig.node.json +++ b/packages/create-vite/template-vue-ts/tsconfig.node.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", diff --git a/packages/vite/package.json b/packages/vite/package.json index 9a05f9f84..862705103 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -87,7 +87,7 @@ "dependencies": { "esbuild": "^0.24.0", "postcss": "^8.4.47", - "rollup": "^4.22.5" + "rollup": "^4.23.0" }, "optionalDependencies": { "fsevents": "~2.3.3" @@ -133,7 +133,7 @@ "pathe": "^1.1.2", "periscopic": "^4.0.2", "picocolors": "^1.1.1", - "picomatch": "^2.3.1", + "picomatch": "^4.0.2", "postcss-import": "^16.1.0", "postcss-load-config": "^4.0.2", "postcss-modules": "^6.0.0", diff --git a/packages/vite/src/node/__tests__/plugins/json.spec.ts b/packages/vite/src/node/__tests__/plugins/json.spec.ts index b95d31eef..18438a007 100644 --- a/packages/vite/src/node/__tests__/plugins/json.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/json.spec.ts @@ -1,5 +1,9 @@ -import { expect, test } from 'vitest' -import { extractJsonErrorPosition } from '../../plugins/json' +import { describe, expect, test } from 'vitest' +import { + type JsonOptions, + extractJsonErrorPosition, + jsonPlugin, +} from '../../plugins/json' const getErrorMessage = (input: string) => { try { @@ -24,3 +28,109 @@ test('can extract json error position', () => { ) } }) + +describe('transform', () => { + const transform = (input: string, opts: JsonOptions, isBuild: boolean) => { + const plugin = jsonPlugin(opts, isBuild) + return (plugin.transform! as Function)(input, 'test.json').code + } + + test('namedExports: true, stringify: false', () => { + const actual = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: true, stringify: false }, + false, + ) + expect(actual).toMatchInlineSnapshot(` + "export const a = 1; + export default { + a: a, + "🫠": "", + "const": false + }; + " + `) + }) + + test('namedExports: false, stringify: false', () => { + const actual = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: false, stringify: false }, + false, + ) + expect(actual).toMatchInlineSnapshot(` + "export default { + a: 1, + "🫠": "", + "const": false + };" + `) + }) + + test('namedExports: true, stringify: true', () => { + const actual = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: true, stringify: true }, + false, + ) + expect(actual).toMatchInlineSnapshot(` + "export const a = 1; + export default { + a, + "🫠": "", + "const": false, + }; + " + `) + }) + + test('namedExports: false, stringify: true', () => { + const actualDev = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: false, stringify: true }, + false, + ) + expect(actualDev).toMatchInlineSnapshot( + `"export default JSON.parse("{\\"a\\":1,\\n\\"🫠\\": \\"\\",\\n\\"const\\": false}")"`, + ) + + const actualBuild = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: false, stringify: true }, + true, + ) + expect(actualBuild).toMatchInlineSnapshot( + `"export default JSON.parse("{\\"a\\":1,\\"🫠\\":\\"\\",\\"const\\":false}")"`, + ) + }) + + test("namedExports: true, stringify: 'auto'", () => { + const actualSmall = transform( + '{"a":1,\n"🫠": "",\n"const": false}', + { namedExports: true, stringify: 'auto' }, + false, + ) + expect(actualSmall).toMatchInlineSnapshot(` + "export const a = 1; + export default { + a, + "🫠": "", + "const": false, + }; + " + `) + const actualLargeNonObject = transform( + `{"a":1,\n"🫠": "${'vite'.repeat(3000)}",\n"const": false}`, + { namedExports: true, stringify: 'auto' }, + false, + ) + expect(actualLargeNonObject).not.toContain('JSON.parse(') + + const actualLarge = transform( + `{"a":1,\n"🫠": {\n"foo": "${'vite'.repeat(3000)}"\n},\n"const": false}`, + { namedExports: true, stringify: 'auto' }, + false, + ) + expect(actualLarge).toContain('JSON.parse(') + }) +}) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 0b5864267..26cbd6725 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -369,7 +369,7 @@ export function resolveBuildEnvironmentOptions( cssCodeSplit: !raw.lib, sourcemap: false, rollupOptions: {}, - minify: raw.ssr ? false : 'esbuild', + minify: consumer === 'server' ? false : 'esbuild', terserOptions: {}, write: true, emptyOutDir: null, @@ -434,7 +434,7 @@ export function resolveBuildEnvironmentOptions( } if (resolved.cssMinify == null) { - resolved.cssMinify = !!resolved.minify + resolved.cssMinify = consumer === 'server' ? 'esbuild' : !!resolved.minify } return resolved diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 2b1330864..2eaec3d80 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -38,17 +38,8 @@ const jsSourceMapRE = /\.[cm]?js\.map$/ const assetCache = new WeakMap>() -// chunk.name is the basename for the asset ignoring the directory structure -// For the manifest, we need to preserve the original file path and isEntry -// for CSS assets. We keep a map from referenceId to this information. -export interface GeneratedAssetMeta { - originalFileName: string - isEntry?: boolean -} -export const generatedAssetsMap = new WeakMap< - Environment, - Map ->() +/** a set of referenceId for entry CSS assets for each environment */ +export const cssEntriesMap = new WeakMap>() // add own dictionary entry by directly assigning mrmime export function registerCustomMime(): void { @@ -146,7 +137,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin { buildStart() { assetCache.set(this.environment, new Map()) - generatedAssetsMap.set(this.environment, new Map()) + cssEntriesMap.set(this.environment, new Set()) }, resolveId(id) { @@ -384,8 +375,6 @@ async function fileToBuiltUrl( originalFileName, source: content, }) - generatedAssetsMap.get(environment)!.set(referenceId, { originalFileName }) - url = `__VITE_ASSET__${referenceId}__${postfix ? `$_${postfix}__` : ``}` } diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 609cd614c..a447afa39 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -27,6 +27,12 @@ import { formatMessages, transform } from 'esbuild' import type { RawSourceMap } from '@ampproject/remapping' import { WorkerWithFallback } from 'artichokie' import { globSync } from 'tinyglobby' +import type { + LessPreprocessorBaseOptions, + SassLegacyPreprocessBaseOptions, + SassModernPreprocessBaseOptions, + StylusPreprocessorBaseOptions, +} from 'types/cssPreprocessorOptions' import { getCodeWithSourcemap, injectSourcesContent } from '../server/sourcemap' import type { EnvironmentModuleNode } from '../server/moduleGraph' import { @@ -73,13 +79,14 @@ import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' import { PartialEnvironment } from '../baseEnvironment' import type { TransformPluginContext } from '../server/pluginContainer' -import type { DevEnvironment } from '..' +import { searchForWorkspaceRoot } from '../server/searchRoot' +import { type DevEnvironment } from '..' import { addToHTMLProxyTransformResult } from './html' import { assetUrlRE, + cssEntriesMap, fileToDevUrl, fileToUrl, - generatedAssetsMap, publicAssetUrlCache, publicAssetUrlRE, publicFileToBuiltUrl, @@ -111,7 +118,14 @@ export interface CSSOptions { * In addition to options specific to each processors, Vite supports `additionalData` option. * The `additionalData` option can be used to inject extra code for each style content. */ - preprocessorOptions?: Record + preprocessorOptions?: { + scss?: SassPreprocessorOptions + sass?: SassPreprocessorOptions + less?: LessPreprocessorOptions + styl?: StylusPreprocessorOptions + stylus?: StylusPreprocessorOptions + } + /** * If this option is set, preprocessors will run in workers when possible. * `true` means the number of CPUs minus 1. @@ -434,7 +448,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { assetFileNames({ type: 'asset', name: cssAssetName, + names: [cssAssetName], originalFileName: null, + originalFileNames: [], source: '/* vite internal call, ignore */', }), ) @@ -563,8 +579,6 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { }, async renderChunk(code, chunk, opts) { - const generatedAssets = generatedAssetsMap.get(this.environment)! - let chunkCSS = '' // the chunk is empty if it's a dynamic entry chunk that only contains a CSS import const isJsChunkEmpty = code === '' && !chunk.isEntry @@ -723,7 +737,6 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { originalFileName, source: content, }) - generatedAssets.set(referenceId, { originalFileName }) const filename = this.getFileName(referenceId) chunk.viteMetadata!.importedAssets.add(cleanUrl(filename)) @@ -781,7 +794,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { originalFileName, source: chunkCSS, }) - generatedAssets.set(referenceId, { originalFileName, isEntry }) + if (isEntry) { + cssEntriesMap.get(this.environment)!.add(referenceId) + } chunk.viteMetadata!.importedCss.add(this.getFileName(referenceId)) } else if (this.environment.config.consumer === 'client') { // legacy build and inline css @@ -1135,32 +1150,15 @@ async function compileCSSPreprocessors( const atImportResolvers = getAtImportResolvers( environment.getTopLevelConfig(), ) + const opts = { + ...((preprocessorOptions && preprocessorOptions[lang]) || {}), + alias: config.resolve.alias, + // important: set this for relative import resolving + filename: cleanUrl(id), + enableSourcemap: devSourcemap ?? false, + } const preProcessor = workerController[lang] - let opts = (preprocessorOptions && preprocessorOptions[lang]) || {} - // support @import from node dependencies by default - switch (lang) { - case PreprocessLang.scss: - case PreprocessLang.sass: - opts = { - includePaths: ['node_modules'], - alias: config.resolve.alias, - ...opts, - } - break - case PreprocessLang.less: - case PreprocessLang.styl: - case PreprocessLang.stylus: - opts = { - paths: ['node_modules'], - alias: config.resolve.alias, - ...opts, - } - } - // important: set this for relative import resolving - opts.filename = cleanUrl(id) - opts.enableSourcemap = devSourcemap ?? false - const preprocessResult = await preProcessor( environment, code, @@ -1640,7 +1638,8 @@ async function resolvePostcssConfig( } else { const searchPath = typeof inlineOptions === 'string' ? inlineOptions : config.root - result = postcssrc({}, searchPath).catch((e) => { + const stopDir = searchForWorkspaceRoot(config.root) + result = postcssrc({}, searchPath, { stopDir }).catch((e) => { if (!e.message.includes('No PostCSS Config found')) { if (e instanceof Error) { const { name, message, stack } = e @@ -1977,52 +1976,43 @@ type PreprocessorAdditionalData = | PreprocessorAdditionalDataResult | Promise) -type StylePreprocessorOptions = { - [key: string]: any +type SassPreprocessorOptions = { additionalData?: PreprocessorAdditionalData +} & ( + | ({ api?: 'legacy' } & SassLegacyPreprocessBaseOptions) + | ({ api: 'modern' | 'modern-compiler' } & SassModernPreprocessBaseOptions) +) + +type LessPreprocessorOptions = { + additionalData?: PreprocessorAdditionalData +} & LessPreprocessorBaseOptions + +type StylusPreprocessorOptions = { + additionalData?: PreprocessorAdditionalData +} & StylusPreprocessorBaseOptions + +type StylePreprocessorInternalOptions = { maxWorkers?: number | true filename: string alias: Alias[] enableSourcemap: boolean } -type SassStylePreprocessorOptions = StylePreprocessorOptions & - Omit, 'data' | 'file' | 'outFile'> & { - api?: 'legacy' | 'modern' | 'modern-compiler' - } +type SassStylePreprocessorInternalOptions = StylePreprocessorInternalOptions & + SassPreprocessorOptions -type StylusStylePreprocessorOptions = StylePreprocessorOptions & { - define?: Record -} +type LessStylePreprocessorInternalOptions = StylePreprocessorInternalOptions & + LessPreprocessorOptions -type StylePreprocessor = { +type StylusStylePreprocessorInternalOptions = StylePreprocessorInternalOptions & + StylusPreprocessorOptions + +type StylePreprocessor = { process: ( environment: PartialEnvironment, source: string, root: string, - options: StylePreprocessorOptions, - resolvers: CSSAtImportResolvers, - ) => StylePreprocessorResults | Promise - close: () => void -} - -type SassStylePreprocessor = { - process: ( - environment: PartialEnvironment, - source: string, - root: string, - options: SassStylePreprocessorOptions, - resolvers: CSSAtImportResolvers, - ) => StylePreprocessorResults | Promise - close: () => void -} - -type StylusStylePreprocessor = { - process: ( - environment: PartialEnvironment, - source: string, - root: string, - options: StylusStylePreprocessorOptions, + options: Options, resolvers: CSSAtImportResolvers, ) => StylePreprocessorResults | Promise close: () => void @@ -2176,7 +2166,10 @@ const makeScssWorker = ( sassPath: string, data: string, // additionalData can a function that is not cloneable but it won't be used - options: SassStylePreprocessorOptions & { additionalData: undefined }, + options: SassStylePreprocessorInternalOptions & { + api: 'legacy' + additionalData: undefined + }, ) => { // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker const sass: typeof Sass = require(sassPath) @@ -2204,6 +2197,8 @@ const makeScssWorker = ( } const finalOptions: Sass.LegacyOptions<'async'> = { + // support @import from node dependencies by default + includePaths: ['node_modules'], ...options, data, file: options.filename, @@ -2287,7 +2282,10 @@ const makeModernScssWorker = ( sassPath: string, data: string, // additionalData can a function that is not cloneable but it won't be used - options: SassStylePreprocessorOptions & { additionalData: undefined }, + options: SassStylePreprocessorInternalOptions & { + api: 'modern' + additionalData: undefined + }, ) => { // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker const sass: typeof Sass = require(sassPath) @@ -2453,8 +2451,15 @@ type ScssWorkerResult = { const scssProcessor = ( maxWorkers: number | undefined, -): SassStylePreprocessor => { - const workerMap = new Map>() +): StylePreprocessor => { + const workerMap = new Map< + unknown, + ReturnType< + | typeof makeScssWorker + | typeof makeModernScssWorker + | typeof makeModernCompilerScssWorker + > + >() return { close() { @@ -2511,6 +2516,7 @@ const scssProcessor = ( const result = await worker.run( sassPackage.path, data, + // @ts-expect-error the correct worker is selected for `options.type` optionsWithoutAdditionalData, ) const deps = result.stats.includedFiles.map((f) => cleanScssBugUrl(f)) @@ -2706,7 +2712,9 @@ const makeLessWorker = ( lessPath: string, content: string, // additionalData can a function that is not cloneable but it won't be used - options: StylePreprocessorOptions & { additionalData: undefined }, + options: LessStylePreprocessorInternalOptions & { + additionalData: undefined + }, ) => { // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker const nodeLess: typeof Less = require(lessPath) @@ -2715,6 +2723,8 @@ const makeLessWorker = ( options.filename, ) const result = await nodeLess.render(content, { + // support @import from node dependencies by default + paths: ['node_modules'], ...options, plugins: [viteResolverPlugin, ...(options.plugins || [])], ...(options.enableSourcemap @@ -2734,7 +2744,7 @@ const makeLessWorker = ( shouldUseFake(_lessPath, _content, options) { // plugins are a function and is not serializable // in that case, fallback to running in main thread - return options.plugins?.length > 0 + return !!options.plugins && options.plugins.length > 0 }, max: maxWorkers, }, @@ -2742,7 +2752,9 @@ const makeLessWorker = ( return worker } -const lessProcessor = (maxWorkers: number | undefined): StylePreprocessor => { +const lessProcessor = ( + maxWorkers: number | undefined, +): StylePreprocessor => { const workerMap = new Map>() return { @@ -2820,12 +2832,18 @@ const makeStylWorker = (maxWorkers: number | undefined) => { content: string, root: string, // additionalData can a function that is not cloneable but it won't be used - options: StylusStylePreprocessorOptions & { additionalData: undefined }, + options: StylusStylePreprocessorInternalOptions & { + additionalData: undefined + }, ) => { // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker const nodeStylus: typeof Stylus = require(stylusPath) - const ref = nodeStylus(content, options) + const ref = nodeStylus(content, { + // support @import from node dependencies by default + paths: ['node_modules'], + ...options, + }) if (options.define) { for (const key in options.define) { ref.define(key, options.define[key]) @@ -2864,7 +2882,7 @@ const makeStylWorker = (maxWorkers: number | undefined) => { const stylProcessor = ( maxWorkers: number | undefined, -): StylusStylePreprocessor => { +): StylePreprocessor => { const workerMap = new Map>() return { @@ -2981,21 +2999,23 @@ const createPreprocessorWorkerController = (maxWorkers: number | undefined) => { const less = lessProcessor(maxWorkers) const styl = stylProcessor(maxWorkers) - const sassProcess: StylePreprocessor['process'] = ( - environment, - source, - root, - options, - resolvers, - ) => { - return scss.process( - environment, - source, - root, - { ...options, indentedSyntax: true, syntax: 'indented' }, - resolvers, - ) - } + const sassProcess: StylePreprocessor['process'] = + (environment, source, root, options, resolvers) => { + let opts: SassStylePreprocessorInternalOptions + if (options.api === 'modern' || options.api === 'modern-compiler') { + opts = { ...options, syntax: 'indented' as const } + } else { + const narrowedOptions = + options as SassStylePreprocessorInternalOptions & { + api?: 'legacy' + } + opts = { + ...narrowedOptions, + indentedSyntax: true, + } + } + return scss.process(environment, source, root, opts, resolvers) + } const close = () => { less.close() diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 6616c0f35..f660ed1d0 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -869,7 +869,8 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { // inject css link when cssCodeSplit is false if (!this.environment.config.build.cssCodeSplit) { const cssChunk = Object.values(bundle).find( - (chunk) => chunk.type === 'asset' && chunk.name === 'style.css', + (chunk) => + chunk.type === 'asset' && chunk.names.includes('style.css'), ) as OutputAsset | undefined if (cssChunk) { result = injectToHead(result, [ diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts index 09e507fee..8f49bb63f 100644 --- a/packages/vite/src/node/plugins/index.ts +++ b/packages/vite/src/node/plugins/index.ts @@ -77,6 +77,7 @@ export async function resolvePlugins( jsonPlugin( { namedExports: true, + stringify: 'auto', ...config.json, }, isBuild, diff --git a/packages/vite/src/node/plugins/json.ts b/packages/vite/src/node/plugins/json.ts index 5de486cf5..261250ba0 100644 --- a/packages/vite/src/node/plugins/json.ts +++ b/packages/vite/src/node/plugins/json.ts @@ -6,7 +6,7 @@ * https://github.com/rollup/plugins/blob/master/LICENSE */ -import { dataToEsm } from '@rollup/pluginutils' +import { dataToEsm, makeLegalIdentifier } from '@rollup/pluginutils' import { SPECIAL_QUERY_RE } from '../constants' import type { Plugin } from '../plugin' import { stripBomTag } from '../utils' @@ -19,10 +19,11 @@ export interface JsonOptions { namedExports?: boolean /** * Generate performant output as JSON.parse("stringified"). - * Enabling this will disable namedExports. - * @default false + * + * When set to 'auto', the data will be stringified only if the data is bigger than 10kB. + * @default 'auto' */ - stringify?: boolean + stringify?: boolean | 'auto' } // Custom json filter for vite @@ -47,24 +48,53 @@ export function jsonPlugin( json = stripBomTag(json) try { - if (options.stringify) { - if (isBuild) { + if (options.stringify !== false) { + if (options.namedExports) { + const parsed = JSON.parse(json) + if (typeof parsed === 'object' && parsed != null) { + const keys = Object.keys(parsed) + + let code = '' + let defaultObjectCode = '{\n' + for (const key of keys) { + if (key === makeLegalIdentifier(key)) { + code += `export const ${key} = ${serializeValue(parsed[key])};\n` + defaultObjectCode += ` ${key},\n` + } else { + defaultObjectCode += ` ${JSON.stringify(key)}: ${serializeValue(parsed[key])},\n` + } + } + defaultObjectCode += '}' + + code += `export default ${defaultObjectCode};\n` + return { + code, + map: { mappings: '' }, + } + } + } + + if ( + options.stringify === true || + // use 10kB as a threshold + // https://v8.dev/blog/cost-of-javascript-2019#:~:text=A%20good%20rule%20of%20thumb%20is%20to%20apply%20this%20technique%20for%20objects%20of%2010%20kB%20or%20larger + (options.stringify === 'auto' && json.length > 10 * 1000) + ) { + // during build, parse then double-stringify to remove all + // unnecessary whitespaces to reduce bundle size. + if (isBuild) { + json = JSON.stringify(JSON.parse(json)) + } + return { - // during build, parse then double-stringify to remove all - // unnecessary whitespaces to reduce bundle size. - code: `export default JSON.parse(${JSON.stringify( - JSON.stringify(JSON.parse(json)), - )})`, + code: `export default JSON.parse(${JSON.stringify(json)})`, map: { mappings: '' }, } - } else { - return `export default JSON.parse(${JSON.stringify(json)})` } } - const parsed = JSON.parse(json) return { - code: dataToEsm(parsed, { + code: dataToEsm(JSON.parse(json), { preferConst: true, namedExports: options.namedExports, }), @@ -81,6 +111,20 @@ export function jsonPlugin( } } +function serializeValue(value: unknown): string { + const valueAsString = JSON.stringify(value) + // use 10kB as a threshold + // https://v8.dev/blog/cost-of-javascript-2019#:~:text=A%20good%20rule%20of%20thumb%20is%20to%20apply%20this%20technique%20for%20objects%20of%2010%20kB%20or%20larger + if ( + typeof value === 'object' && + value != null && + valueAsString.length > 10 * 1000 + ) { + return `JSON.parse(${JSON.stringify(valueAsString)})` + } + return valueAsString +} + export function extractJsonErrorPosition( errorMessage: string, inputLength: number, diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index 5ea977963..69538f370 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -8,7 +8,7 @@ import type { import type { Plugin } from '../plugin' import { normalizePath, sortObjectKeys } from '../utils' import { usePerEnvironmentState } from '../environment' -import { generatedAssetsMap } from './asset' +import { cssEntriesMap } from './asset' const endsWithJSRE = /\.[cm]?js$/ @@ -127,18 +127,15 @@ export function manifestPlugin(): Plugin { return manifestChunk } - const assets = generatedAssetsMap.get(this.environment)! - const entryCssAssetFileNames = new Set() - for (const [id, asset] of assets.entries()) { - if (asset.isEntry) { - try { - const fileName = this.getFileName(id) - entryCssAssetFileNames.add(fileName) - } catch { - // The asset was generated as part of a different output option. - // It was already handled during the previous run of this plugin. - assets.delete(id) - } + const entryCssReferenceIds = cssEntriesMap.get(this.environment)! + const entryCssAssetFileNames = new Set(entryCssReferenceIds) + for (const id of entryCssReferenceIds) { + try { + const fileName = this.getFileName(id) + entryCssAssetFileNames.add(fileName) + } catch { + // The asset was generated as part of a different output option. + // It was already handled during the previous run of this plugin. } } @@ -148,28 +145,24 @@ export function manifestPlugin(): Plugin { const chunk = bundle[file] if (chunk.type === 'chunk') { manifest[getChunkName(chunk)] = createChunk(chunk) - } else if (chunk.type === 'asset' && typeof chunk.name === 'string') { + } else if (chunk.type === 'asset' && chunk.names.length > 0) { // Add every unique asset to the manifest, keyed by its original name - const src = chunk.originalFileName ?? chunk.name + const src = + chunk.originalFileNames.length > 0 + ? chunk.originalFileNames[0] + : chunk.names[0] const isEntry = entryCssAssetFileNames.has(chunk.fileName) const asset = createAsset(chunk, src, isEntry) // If JS chunk and asset chunk are both generated from the same source file, // prioritize JS chunk as it contains more information const file = manifest[src]?.file - if (file && endsWithJSRE.test(file)) continue + if (!(file && endsWithJSRE.test(file))) { + manifest[src] = asset + fileNameToAsset.set(chunk.fileName, asset) + } - manifest[src] = asset - fileNameToAsset.set(chunk.fileName, asset) - } - } - - // Add deduplicated assets to the manifest - for (const [referenceId, { originalFileName }] of assets.entries()) { - if (!manifest[originalFileName]) { - const fileName = this.getFileName(referenceId) - const asset = fileNameToAsset.get(fileName) - if (asset) { + for (const originalFileName of chunk.originalFileNames.slice(1)) { manifest[originalFileName] = asset } } diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index eeafe7a90..a6c7b7505 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -23,7 +23,9 @@ import { fileToUrl } from './asset' type WorkerBundleAsset = { fileName: string + /** @deprecated */ originalFileName: string | null + originalFileNames: string[] source: string | Uint8Array } @@ -122,6 +124,7 @@ async function bundleWorkerEntry( saveEmitWorkerAsset(config, { fileName: outputChunk.fileName, originalFileName: null, + originalFileNames: [], source: outputChunk.code, }) } @@ -159,6 +162,7 @@ function emitSourcemapForWorkerEntry( saveEmitWorkerAsset(config, { fileName: mapFileName, originalFileName: null, + originalFileNames: [], source: data, }) } @@ -193,6 +197,7 @@ export async function workerFileToUrl( saveEmitWorkerAsset(config, { fileName, originalFileName: null, + originalFileNames: [], source: outputChunk.code, }) workerMap.bundle.set(id, fileName) @@ -468,8 +473,9 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { this.emitFile({ type: 'asset', fileName: asset.fileName, - originalFileName: asset.originalFileName, source: asset.source, + // NOTE: fileName is already generated when bundling the worker + // so no need to pass originalFileNames/names }) }) workerMap.assets.clear() diff --git a/packages/vite/src/node/preview.ts b/packages/vite/src/node/preview.ts index 23753300e..fac0d37de 100644 --- a/packages/vite/src/node/preview.ts +++ b/packages/vite/src/node/preview.ts @@ -84,8 +84,8 @@ export interface PreviewServer { */ httpServer: HttpServer /** - * The resolved urls Vite prints on the CLI. - * null before server is listening. + * The resolved urls Vite prints on the CLI (URL-encoded). Returns `null` + * if the server is not listening on any port. */ resolvedUrls: ResolvedServerUrls | null /** @@ -153,6 +153,7 @@ export async function preview( async close() { teardownSIGTERMListener(closeServerAndExit) await closeHttpServer() + server.resolvedUrls = null }, resolvedUrls: null, printUrls() { diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 769ce1367..9fe74478f 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -287,8 +287,8 @@ export interface ViteDevServer { */ moduleGraph: ModuleGraph /** - * The resolved urls Vite prints on the CLI. null in middleware mode or - * before `server.listen` is called. + * The resolved urls Vite prints on the CLI (URL-encoded). Returns `null` + * in middleware mode or if the server is not listening on any port. */ resolvedUrls: ResolvedServerUrls | null /** @@ -547,7 +547,13 @@ export async function _createServer( url: string, originalCode = code, ) { - return ssrTransform(code, inMap, url, originalCode, server.config) + return ssrTransform(code, inMap, url, originalCode, { + json: { + stringify: + config.json?.stringify === true && + config.json.namedExports !== true, + }, + }) }, // environment.transformRequest and .warmupRequest don't take an options param for now, // so the logic and error handling needs to be duplicated here. diff --git a/packages/vite/src/node/server/openBrowser.ts b/packages/vite/src/node/server/openBrowser.ts index 101cd567a..eebf4b0ad 100644 --- a/packages/vite/src/node/server/openBrowser.ts +++ b/packages/vite/src/node/server/openBrowser.ts @@ -96,9 +96,7 @@ async function startBrowserProcess( if (openedBrowser) { // Try our best to reuse existing tab with AppleScript await execAsync( - `osascript openChrome.applescript "${encodeURI( - url, - )}" "${openedBrowser}"`, + `osascript openChrome.applescript "${url}" "${openedBrowser}"`, { cwd: join(VITE_PACKAGE_DIR, 'bin'), }, diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 666521867..66e81559b 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -408,14 +408,15 @@ async function loadAndTransform( if (environment._closing && environment.config.dev.recoverable) throwClosedServerError() + const topLevelConfig = environment.getTopLevelConfig() const result = environment.config.dev.moduleRunnerTransform - ? await ssrTransform( - code, - normalizedMap, - url, - originalCode, - environment.getTopLevelConfig(), - ) + ? await ssrTransform(code, normalizedMap, url, originalCode, { + json: { + stringify: + topLevelConfig.json?.stringify === true && + topLevelConfig.json.namedExports !== true, + }, + }) : ({ code, map: normalizedMap, diff --git a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts index 2caffa586..fa8bd6e52 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrTransform.spec.ts @@ -2,6 +2,7 @@ import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { assert, expect, test } from 'vitest' import type { SourceMap } from 'rollup' +import { TraceMap, originalPositionFor } from '@jridgewell/trace-mapping' import { transformWithEsbuild } from '../../plugins/esbuild' import { ssrTransform } from '../ssrTransform' @@ -445,6 +446,37 @@ test('sourcemap source', async () => { expect(map?.sourcesContent).toStrictEqual(['export const a = 1 /* */']) }) +test('sourcemap is correct for hoisted imports', async () => { + const code = `\n\n\nconsole.log(foo, bar);\nimport { foo } from 'vue';\nimport { bar } from 'vue2';` + const result = (await ssrTransform(code, null, 'input.js', code))! + + expect(result.code).toMatchInlineSnapshot(` + "const __vite_ssr_identity__ = v => v; + const __vite_ssr_import_0__ = await __vite_ssr_import__("vue", {"importedNames":["foo"]}); + const __vite_ssr_import_1__ = await __vite_ssr_import__("vue2", {"importedNames":["bar"]}); + + + + console.log(__vite_ssr_identity__(__vite_ssr_import_0__.foo), __vite_ssr_identity__(__vite_ssr_import_1__.bar)); + + " + `) + + const traceMap = new TraceMap(result.map as any) + expect(originalPositionFor(traceMap, { line: 2, column: 0 })).toStrictEqual({ + source: 'input.js', + line: 5, + column: 0, + name: null, + }) + expect(originalPositionFor(traceMap, { line: 3, column: 0 })).toStrictEqual({ + source: 'input.js', + line: 6, + column: 0, + name: null, + }) +}) + test('sourcemap with multiple sources', async () => { const code = readFixture('bundle.js') const map = readFixture('bundle.js.map') @@ -1151,3 +1183,25 @@ console.log(foo + 2) " `) }) + +test('identity function is declared before used', async () => { + expect( + await ssrTransformSimpleCode(` +import { foo } from './foo' +export default foo() +export * as bar from './bar' +console.log(bar) + `), + ).toMatchInlineSnapshot(` + "const __vite_ssr_identity__ = v => v; + const __vite_ssr_import_0__ = await __vite_ssr_import__("./foo", {"importedNames":["foo"]}); + + + __vite_ssr_exports__.default = __vite_ssr_identity__(__vite_ssr_import_0__.foo)() + const __vite_ssr_import_1__ = await __vite_ssr_import__("./bar"); + + Object.defineProperty(__vite_ssr_exports__, "bar", { enumerable: true, configurable: true, get(){ return __vite_ssr_import_1__ }}); + console.log(bar) + " + `) +}) diff --git a/packages/vite/src/node/ssr/ssrTransform.ts b/packages/vite/src/node/ssr/ssrTransform.ts index 0cd4979ae..a93b2c9d8 100644 --- a/packages/vite/src/node/ssr/ssrTransform.ts +++ b/packages/vite/src/node/ssr/ssrTransform.ts @@ -1,6 +1,6 @@ import path from 'node:path' import MagicString from 'magic-string' -import type { SourceMap } from 'rollup' +import type { RollupAstNode, SourceMap } from 'rollup' import type { ExportAllDeclaration, ExportDefaultDeclaration, @@ -99,13 +99,22 @@ async function ssrTransformScript( const declaredConst = new Set() // hoist at the start of the file, after the hashbang - const hoistIndex = hashbangRE.exec(code)?.[0].length ?? 0 + const fileStartIndex = hashbangRE.exec(code)?.[0].length ?? 0 + let hoistIndex = fileStartIndex function defineImport( index: number, - source: string, + importNode: ( + | ImportDeclaration + | (ExportNamedDeclaration & { source: Literal }) + | ExportAllDeclaration + ) & { + start: number + end: number + }, metadata?: DefineImportMetadata, ) { + const source = importNode.source.value as string deps.add(source) const importId = `__vite_ssr_import_${uid++}__` @@ -118,14 +127,23 @@ async function ssrTransformScript( } const metadataStr = metadata ? `, ${JSON.stringify(metadata)}` : '' - // There will be an error if the module is called before it is imported, - // so the module import statement is hoisted to the top - s.appendLeft( - index, + s.update( + importNode.start, + importNode.end, `const ${importId} = await ${ssrImportKey}(${JSON.stringify( source, )}${metadataStr});\n`, ) + + if (importNode.start === index) { + // no need to hoist, but update hoistIndex to keep the order + hoistIndex = importNode.end + } else { + // There will be an error if the module is called before it is imported, + // so the module import statement is hoisted to the top + s.move(importNode.start, importNode.end, index) + } + return importId } @@ -137,12 +155,12 @@ async function ssrTransformScript( ) } - const imports: (ImportDeclaration & { start: number; end: number })[] = [] - const exports: (( - | ExportNamedDeclaration - | ExportDefaultDeclaration - | ExportAllDeclaration - ) & { start: number; end: number })[] = [] + const imports: RollupAstNode[] = [] + const exports: ( + | RollupAstNode + | RollupAstNode + | RollupAstNode + )[] = [] for (const node of ast.body as Node[]) { if (node.type === 'ImportDeclaration') { @@ -161,7 +179,7 @@ async function ssrTransformScript( // import foo from 'foo' --> foo -> __import_foo__.default // import { baz } from 'foo' --> baz -> __import_foo__.baz // import * as ok from 'foo' --> ok -> __import_foo__ - const importId = defineImport(hoistIndex, node.source.value as string, { + const importId = defineImport(hoistIndex, node, { importedNames: node.specifiers .map((s) => { if (s.type === 'ImportSpecifier') @@ -170,7 +188,6 @@ async function ssrTransformScript( }) .filter(isDefined), }) - s.remove(node.start, node.end) for (const spec of node.specifiers) { if (spec.type === 'ImportSpecifier') { if (spec.imported.type === 'Identifier') { @@ -220,7 +237,7 @@ async function ssrTransformScript( // export { foo, bar } from './foo' const importId = defineImport( node.start, - node.source.value as string, + node as RollupAstNode, { importedNames: node.specifiers.map( (s) => getIdentifierNameOrLiteralValue(s.local) as string, @@ -234,13 +251,13 @@ async function ssrTransformScript( if (spec.local.type === 'Identifier') { defineExport( - node.start, + node.end, exportedAs, `${importId}.${spec.local.name}`, ) } else { defineExport( - node.start, + node.end, exportedAs, `${importId}[${JSON.stringify(spec.local.value as string)}]`, ) @@ -291,15 +308,14 @@ async function ssrTransformScript( // export * from './foo' if (node.type === 'ExportAllDeclaration') { - s.remove(node.start, node.end) - const importId = defineImport(node.start, node.source.value as string) + const importId = defineImport(node.start, node) if (node.exported) { const exportedAs = getIdentifierNameOrLiteralValue( node.exported, ) as string - defineExport(node.start, exportedAs, `${importId}`) + defineExport(node.end, exportedAs, `${importId}`) } else { - s.appendLeft(node.start, `${ssrExportAllKey}(${importId});\n`) + s.appendLeft(node.end, `${ssrExportAllKey}(${importId});\n`) } } } @@ -360,7 +376,7 @@ async function ssrTransformScript( }) if (injectIdentityFunction) { - s.prependLeft(hoistIndex, `const ${ssrIdentityFunction} = v => v;\n`) + s.prependLeft(fileStartIndex, `const ${ssrIdentityFunction} = v => v;\n`) } let map = s.generateMap({ hires: 'boundary' }) diff --git a/packages/vite/src/types/shims.d.ts b/packages/vite/src/types/shims.d.ts index 3a8c070e3..00123f17d 100644 --- a/packages/vite/src/types/shims.d.ts +++ b/packages/vite/src/types/shims.d.ts @@ -32,11 +32,6 @@ declare module 'postcss-import' { export = plugin } -// LESS' types somewhat references this which doesn't make sense in Node, -// so we have to shim it -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -declare interface HTMLLinkElement {} - // eslint-disable-next-line no-var declare var __vite_profile_session: import('node:inspector').Session | undefined // eslint-disable-next-line no-var diff --git a/packages/vite/types/cssPreprocessorOptions.d.ts b/packages/vite/types/cssPreprocessorOptions.d.ts new file mode 100644 index 000000000..5064ac18f --- /dev/null +++ b/packages/vite/types/cssPreprocessorOptions.d.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore `sass` may not be installed +import type Sass from 'sass' +// @ts-ignore `less` may not be installed +import type Less from 'less' +// @ts-ignore `less` may not be installed +import type Stylus from 'stylus' + +/* eslint-enable @typescript-eslint/ban-ts-comment */ + +export type SassLegacyPreprocessBaseOptions = Omit< + Sass.LegacyStringOptions<'async'>, + | 'data' + | 'file' + | 'outFile' + | 'sourceMap' + | 'omitSourceMapUrl' + | 'sourceMapEmbed' + | 'sourceMapRoot' +> + +export type SassModernPreprocessBaseOptions = Omit< + Sass.StringOptions<'async'>, + 'url' | 'sourceMap' +> + +export type LessPreprocessorBaseOptions = Omit< + Less.Options, + 'sourceMap' | 'filename' +> + +export type StylusPreprocessorBaseOptions = Omit< + Stylus.RenderOptions, + 'filename' +> & { define?: Record } + +declare global { + // LESS' types somewhat references this which doesn't make sense in Node, + // so we have to shim it + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface HTMLLinkElement {} +} diff --git a/playground/json/__tests__/ssr/json-ssr.spec.ts b/playground/json/__tests__/ssr/json-ssr.spec.ts index 5efbeac7d..374e7ca02 100644 --- a/playground/json/__tests__/ssr/json-ssr.spec.ts +++ b/playground/json/__tests__/ssr/json-ssr.spec.ts @@ -11,7 +11,10 @@ beforeEach(async () => { test('load json module', async () => { await untilUpdated( () => page.textContent('.fetch-json-module pre'), - 'export default JSON.parse("{\\n \\"hello\\": \\"hi\\"\\n}\\n")', + 'export const hello = "hi";\n' + + 'export default {\n' + + ' hello,\n' + + '};\n', ) }) diff --git a/playground/vitestSetup.ts b/playground/vitestSetup.ts index 2b2385209..a1a986d98 100644 --- a/playground/vitestSetup.ts +++ b/playground/vitestSetup.ts @@ -21,7 +21,7 @@ import { } from 'vite' import type { Browser, Page } from 'playwright-chromium' import type { RollupError, RollupWatcher, RollupWatcherEvent } from 'rollup' -import type { File } from 'vitest' +import type { RunnerTestFile } from 'vitest' import { beforeAll, inject } from 'vitest' // #region env @@ -81,7 +81,7 @@ export function setViteUrl(url: string): void { // #endregion beforeAll(async (s) => { - const suite = s as File + const suite = s as RunnerTestFile testPath = suite.filepath! testName = slash(testPath).match(/playground\/([\w-]+)\//)?.[1] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31e590d93..0365cbc56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,11 +113,11 @@ importers: specifier: ^5.0.10 version: 5.0.10 rollup: - specifier: ^4.22.5 - version: 4.22.5 + specifier: ^4.23.0 + version: 4.23.0 rollup-plugin-esbuild: specifier: ^6.1.1 - version: 6.1.1(esbuild@0.24.0)(rollup@4.22.5) + version: 6.1.1(esbuild@0.24.0)(rollup@4.23.0) simple-git-hooks: specifier: ^2.11.1 version: 2.11.1 @@ -234,8 +234,8 @@ importers: specifier: ^8.4.47 version: 8.4.47 rollup: - specifier: ^4.22.5 - version: 4.22.5 + specifier: ^4.23.0 + version: 4.23.0 optionalDependencies: fsevents: specifier: ~2.3.3 @@ -255,22 +255,22 @@ importers: version: 1.0.0-next.25 '@rollup/plugin-alias': specifier: ^5.1.1 - version: 5.1.1(rollup@4.22.5) + version: 5.1.1(rollup@4.23.0) '@rollup/plugin-commonjs': specifier: ^28.0.1 - version: 28.0.1(rollup@4.22.5) + version: 28.0.1(rollup@4.23.0) '@rollup/plugin-dynamic-import-vars': specifier: ^2.1.4 - version: 2.1.4(rollup@4.22.5) + version: 2.1.4(rollup@4.23.0) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.22.5) + version: 6.1.0(rollup@4.23.0) '@rollup/plugin-node-resolve': specifier: 15.3.0 - version: 15.3.0(rollup@4.22.5) + version: 15.3.0(rollup@4.23.0) '@rollup/pluginutils': specifier: ^5.1.2 - version: 5.1.2(rollup@4.22.5) + version: 5.1.3(rollup@4.23.0) '@types/escape-html': specifier: ^1.0.4 version: 1.0.4 @@ -362,8 +362,8 @@ importers: specifier: ^1.1.1 version: 1.1.1 picomatch: - specifier: ^2.3.1 - version: 2.3.1 + specifier: ^4.0.2 + version: 4.0.2 postcss-import: specifier: ^16.1.0 version: 16.1.0(postcss@8.4.47) @@ -378,13 +378,13 @@ importers: version: 2.0.2 rollup-plugin-dts: specifier: ^6.1.1 - version: 6.1.1(rollup@4.22.5)(typescript@5.6.2) + version: 6.1.1(rollup@4.23.0)(typescript@5.6.2) rollup-plugin-esbuild: specifier: ^6.1.1 - version: 6.1.1(esbuild@0.24.0)(rollup@4.22.5) + version: 6.1.1(esbuild@0.24.0)(rollup@4.23.0) rollup-plugin-license: specifier: ^3.5.3 - version: 3.5.3(picomatch@2.3.1)(rollup@4.22.5) + version: 3.5.3(picomatch@4.0.2)(rollup@4.23.0) sass: specifier: ^1.80.3 version: 1.80.3 @@ -3037,6 +3037,15 @@ packages: '@polka/url@1.0.0-next.24': resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} + '@rollup/plugin-alias@5.1.0': + resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/plugin-alias@5.1.1': resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} engines: {node: '>=14.0.0'} @@ -3082,6 +3091,15 @@ packages: rollup: optional: true + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/plugin-node-resolve@15.3.0': resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==} engines: {node: '>=14.0.0'} @@ -3109,83 +3127,92 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.22.5': - resolution: {integrity: sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==} + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.23.0': + resolution: {integrity: sha512-8OR+Ok3SGEMsAZispLx8jruuXw0HVF16k+ub2eNXKHDmdxL4cf9NlNpAzhlOhNyXzKDEJuFeq0nZm+XlNb1IFw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.22.5': - resolution: {integrity: sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==} + '@rollup/rollup-android-arm64@4.23.0': + resolution: {integrity: sha512-rEFtX1nP8gqmLmPZsXRMoLVNB5JBwOzIAk/XAcEPuKrPa2nPJ+DuGGpfQUR0XjRm8KjHfTZLpWbKXkA5BoFL3w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.22.5': - resolution: {integrity: sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==} + '@rollup/rollup-darwin-arm64@4.23.0': + resolution: {integrity: sha512-ZbqlMkJRMMPeapfaU4drYHns7Q5MIxjM/QeOO62qQZGPh9XWziap+NF9fsqPHT0KzEL6HaPspC7sOwpgyA3J9g==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.22.5': - resolution: {integrity: sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==} + '@rollup/rollup-darwin-x64@4.23.0': + resolution: {integrity: sha512-PfmgQp78xx5rBCgn2oYPQ1rQTtOaQCna0kRaBlc5w7RlA3TDGGo7m3XaptgitUZ54US9915i7KeVPHoy3/W8tA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.22.5': - resolution: {integrity: sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==} + '@rollup/rollup-linux-arm-gnueabihf@4.23.0': + resolution: {integrity: sha512-WAeZfAAPus56eQgBioezXRRzArAjWJGjNo/M+BHZygUcs9EePIuGI1Wfc6U/Ki+tMW17FFGvhCfYnfcKPh18SA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.22.5': - resolution: {integrity: sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==} + '@rollup/rollup-linux-arm-musleabihf@4.23.0': + resolution: {integrity: sha512-v7PGcp1O5XKZxKX8phTXtmJDVpE20Ub1eF6w9iMmI3qrrPak6yR9/5eeq7ziLMrMTjppkkskXyxnmm00HdtXjA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.22.5': - resolution: {integrity: sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==} + '@rollup/rollup-linux-arm64-gnu@4.23.0': + resolution: {integrity: sha512-nAbWsDZ9UkU6xQiXEyXBNHAKbzSAi95H3gTStJq9UGiS1v+YVXwRHcQOQEF/3CHuhX5BVhShKoeOf6Q/1M+Zhg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.22.5': - resolution: {integrity: sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==} + '@rollup/rollup-linux-arm64-musl@4.23.0': + resolution: {integrity: sha512-5QT/Di5FbGNPaVw8hHO1wETunwkPuZBIu6W+5GNArlKHD9fkMHy7vS8zGHJk38oObXfWdsuLMogD4sBySLJ54g==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.22.5': - resolution: {integrity: sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==} + '@rollup/rollup-linux-powerpc64le-gnu@4.23.0': + resolution: {integrity: sha512-Sefl6vPyn5axzCsO13r1sHLcmPuiSOrKIImnq34CBurntcJ+lkQgAaTt/9JkgGmaZJ+OkaHmAJl4Bfd0DmdtOQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.22.5': - resolution: {integrity: sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==} + '@rollup/rollup-linux-riscv64-gnu@4.23.0': + resolution: {integrity: sha512-o4QI2KU/QbP7ZExMse6ULotdV3oJUYMrdx3rBZCgUF3ur3gJPfe8Fuasn6tia16c5kZBBw0aTmaUygad6VB/hQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.22.5': - resolution: {integrity: sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==} + '@rollup/rollup-linux-s390x-gnu@4.23.0': + resolution: {integrity: sha512-+bxqx+V/D4FGrpXzPGKp/SEZIZ8cIW3K7wOtcJAoCrmXvzRtmdUhYNbgd+RztLzfDEfA2WtKj5F4tcbNPuqgeg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.22.5': - resolution: {integrity: sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==} + '@rollup/rollup-linux-x64-gnu@4.23.0': + resolution: {integrity: sha512-I/eXsdVoCKtSgK9OwyQKPAfricWKUMNCwJKtatRYMmDo5N859tbO3UsBw5kT3dU1n6ZcM1JDzPRSGhAUkxfLxw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.22.5': - resolution: {integrity: sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==} + '@rollup/rollup-linux-x64-musl@4.23.0': + resolution: {integrity: sha512-4ZoDZy5ShLbbe1KPSafbFh1vbl0asTVfkABC7eWqIs01+66ncM82YJxV2VtV3YVJTqq2P8HMx3DCoRSWB/N3rw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.22.5': - resolution: {integrity: sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==} + '@rollup/rollup-win32-arm64-msvc@4.23.0': + resolution: {integrity: sha512-+5Ky8dhft4STaOEbZu3/NU4QIyYssKO+r1cD3FzuusA0vO5gso15on7qGzKdNXnc1gOrsgCqZjRw1w+zL4y4hQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.22.5': - resolution: {integrity: sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==} + '@rollup/rollup-win32-ia32-msvc@4.23.0': + resolution: {integrity: sha512-0SPJk4cPZQhq9qA1UhIRumSE3+JJIBBjtlGl5PNC///BoaByckNZd53rOYD0glpTkYFBQSt7AkMeLVPfx65+BQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.22.5': - resolution: {integrity: sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==} + '@rollup/rollup-win32-x64-msvc@4.23.0': + resolution: {integrity: sha512-lqCK5GQC8fNo0+JvTSxcG7YB1UKYp8yrNLhsArlvPWN+16ovSZgoehlVHg6X0sSWPUkpjRBR5TuR12ZugowZ4g==} cpu: [x64] os: [win32] @@ -4055,6 +4082,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -5086,6 +5117,10 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + is-core-module@2.14.0: resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} engines: {node: '>= 0.4'} @@ -6225,13 +6260,13 @@ packages: peerDependencies: rollup: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + rollup@3.29.5: + resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true - rollup@4.22.5: - resolution: {integrity: sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==} + rollup@4.23.0: + resolution: {integrity: sha512-vXB4IT9/KLDrS2WRXmY22sVB2wTsTwkpxjB8Q3mnakTENcYw3FRmfdYDy/acNmls+lHmDazgrRjK/yQ6hQAtwA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -8447,28 +8482,30 @@ snapshots: '@polka/url@1.0.0-next.24': {} - '@rollup/plugin-alias@5.1.1(rollup@3.29.4)': - optionalDependencies: - rollup: 3.29.4 - - '@rollup/plugin-alias@5.1.1(rollup@4.22.5)': - optionalDependencies: - rollup: 4.22.5 - - '@rollup/plugin-commonjs@25.0.4(rollup@3.29.4)': + '@rollup/plugin-alias@5.1.0(rollup@3.29.5)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@3.29.4) + slash: 4.0.0 + optionalDependencies: + rollup: 3.29.5 + + '@rollup/plugin-alias@5.1.1(rollup@4.23.0)': + optionalDependencies: + rollup: 4.23.0 + + '@rollup/plugin-commonjs@25.0.4(rollup@3.29.5)': + dependencies: + '@rollup/pluginutils': 5.1.3(rollup@3.29.5) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.27.0 optionalDependencies: - rollup: 3.29.4 + rollup: 3.29.5 - '@rollup/plugin-commonjs@28.0.1(rollup@4.22.5)': + '@rollup/plugin-commonjs@28.0.1(rollup@4.23.0)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.22.5) + '@rollup/pluginutils': 5.1.3(rollup@4.23.0) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.4.0(picomatch@4.0.2) @@ -8476,119 +8513,128 @@ snapshots: magic-string: 0.30.12 picomatch: 4.0.2 optionalDependencies: - rollup: 4.22.5 + rollup: 4.23.0 - '@rollup/plugin-dynamic-import-vars@2.1.4(rollup@4.22.5)': + '@rollup/plugin-dynamic-import-vars@2.1.4(rollup@4.23.0)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.22.5) + '@rollup/pluginutils': 5.1.3(rollup@4.23.0) astring: 1.8.6 estree-walker: 2.0.2 magic-string: 0.30.12 tinyglobby: 0.2.9 optionalDependencies: - rollup: 4.22.5 + rollup: 4.23.0 - '@rollup/plugin-json@6.1.0(rollup@3.29.4)': + '@rollup/plugin-json@6.1.0(rollup@3.29.5)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@3.29.4) + '@rollup/pluginutils': 5.1.3(rollup@3.29.5) optionalDependencies: - rollup: 3.29.4 + rollup: 3.29.5 - '@rollup/plugin-json@6.1.0(rollup@4.22.5)': + '@rollup/plugin-json@6.1.0(rollup@4.23.0)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.22.5) + '@rollup/pluginutils': 5.1.3(rollup@4.23.0) optionalDependencies: - rollup: 4.22.5 + rollup: 4.23.0 - '@rollup/plugin-node-resolve@15.3.0(rollup@3.29.4)': + '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.5)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@3.29.4) + '@rollup/pluginutils': 5.1.3(rollup@3.29.5) + '@types/resolve': 1.20.2 + deepmerge: 4.2.2 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 3.29.5 + + '@rollup/plugin-node-resolve@15.3.0(rollup@4.23.0)': + dependencies: + '@rollup/pluginutils': 5.1.3(rollup@4.23.0) '@types/resolve': 1.20.2 deepmerge: 4.2.2 is-module: 1.0.0 resolve: 1.22.8 optionalDependencies: - rollup: 3.29.4 + rollup: 4.23.0 - '@rollup/plugin-node-resolve@15.3.0(rollup@4.22.5)': + '@rollup/plugin-replace@5.0.2(rollup@3.29.5)': dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.22.5) - '@types/resolve': 1.20.2 - deepmerge: 4.2.2 - is-module: 1.0.0 - resolve: 1.22.8 - optionalDependencies: - rollup: 4.22.5 - - '@rollup/plugin-replace@5.0.2(rollup@3.29.4)': - dependencies: - '@rollup/pluginutils': 5.1.2(rollup@3.29.4) + '@rollup/pluginutils': 5.1.3(rollup@3.29.5) magic-string: 0.27.0 optionalDependencies: - rollup: 3.29.4 + rollup: 3.29.5 - '@rollup/pluginutils@5.1.2(rollup@3.29.4)': + '@rollup/pluginutils@5.1.2(rollup@3.29.5)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 3.29.4 + rollup: 3.29.5 - '@rollup/pluginutils@5.1.2(rollup@4.22.5)': + '@rollup/pluginutils@5.1.3(rollup@3.29.5)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 - picomatch: 2.3.1 + picomatch: 4.0.2 optionalDependencies: - rollup: 4.22.5 + rollup: 3.29.5 - '@rollup/rollup-android-arm-eabi@4.22.5': + '@rollup/pluginutils@5.1.3(rollup@4.23.0)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.23.0 + + '@rollup/rollup-android-arm-eabi@4.23.0': optional: true - '@rollup/rollup-android-arm64@4.22.5': + '@rollup/rollup-android-arm64@4.23.0': optional: true - '@rollup/rollup-darwin-arm64@4.22.5': + '@rollup/rollup-darwin-arm64@4.23.0': optional: true - '@rollup/rollup-darwin-x64@4.22.5': + '@rollup/rollup-darwin-x64@4.23.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.22.5': + '@rollup/rollup-linux-arm-gnueabihf@4.23.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.22.5': + '@rollup/rollup-linux-arm-musleabihf@4.23.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.22.5': + '@rollup/rollup-linux-arm64-gnu@4.23.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.22.5': + '@rollup/rollup-linux-arm64-musl@4.23.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.22.5': + '@rollup/rollup-linux-powerpc64le-gnu@4.23.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.22.5': + '@rollup/rollup-linux-riscv64-gnu@4.23.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.22.5': + '@rollup/rollup-linux-s390x-gnu@4.23.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.22.5': + '@rollup/rollup-linux-x64-gnu@4.23.0': optional: true - '@rollup/rollup-linux-x64-musl@4.22.5': + '@rollup/rollup-linux-x64-musl@4.23.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.22.5': + '@rollup/rollup-win32-arm64-msvc@4.23.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.22.5': + '@rollup/rollup-win32-ia32-msvc@4.23.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.22.5': + '@rollup/rollup-win32-x64-msvc@4.23.0': optional: true '@sec-ant/readable-stream@0.4.1': {} @@ -9533,6 +9579,8 @@ snapshots: buffer-from@1.1.2: {} + builtin-modules@3.3.0: {} + bundle-name@4.1.0: dependencies: run-applescript: 7.0.0 @@ -10335,9 +10383,9 @@ snapshots: dependencies: reusify: 1.0.4 - fdir@6.3.0(picomatch@2.3.1): + fdir@6.3.0(picomatch@4.0.2): optionalDependencies: - picomatch: 2.3.1 + picomatch: 4.0.2 fdir@6.4.0(picomatch@4.0.2): optionalDependencies: @@ -10723,6 +10771,10 @@ snapshots: dependencies: binary-extensions: 2.2.0 + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + is-core-module@2.14.0: dependencies: hasown: 2.0.2 @@ -11925,71 +11977,71 @@ snapshots: dependencies: glob: 10.4.5 - rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.6.2): + rollup-plugin-dts@6.1.1(rollup@3.29.5)(typescript@5.6.2): dependencies: magic-string: 0.30.12 - rollup: 3.29.4 + rollup: 3.29.5 typescript: 5.6.2 optionalDependencies: '@babel/code-frame': 7.25.7 - rollup-plugin-dts@6.1.1(rollup@4.22.5)(typescript@5.6.2): + rollup-plugin-dts@6.1.1(rollup@4.23.0)(typescript@5.6.2): dependencies: magic-string: 0.30.12 - rollup: 4.22.5 + rollup: 4.23.0 typescript: 5.6.2 optionalDependencies: '@babel/code-frame': 7.25.7 - rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.22.5): + rollup-plugin-esbuild@6.1.1(esbuild@0.24.0)(rollup@4.23.0): dependencies: - '@rollup/pluginutils': 5.1.2(rollup@4.22.5) + '@rollup/pluginutils': 5.1.3(rollup@4.23.0) debug: 4.3.7 es-module-lexer: 1.5.4 esbuild: 0.24.0 get-tsconfig: 4.7.5 - rollup: 4.22.5 + rollup: 4.23.0 transitivePeerDependencies: - supports-color - rollup-plugin-license@3.5.3(picomatch@2.3.1)(rollup@4.22.5): + rollup-plugin-license@3.5.3(picomatch@4.0.2)(rollup@4.23.0): dependencies: commenting: 1.1.0 - fdir: 6.3.0(picomatch@2.3.1) + fdir: 6.3.0(picomatch@4.0.2) lodash: 4.17.21 magic-string: 0.30.12 moment: 2.30.1 package-name-regex: 2.0.6 - rollup: 4.22.5 + rollup: 4.23.0 spdx-expression-validate: 2.0.0 spdx-satisfies: 5.0.1 transitivePeerDependencies: - picomatch - rollup@3.29.4: + rollup@3.29.5: optionalDependencies: fsevents: 2.3.3 - rollup@4.22.5: + rollup@4.23.0: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.22.5 - '@rollup/rollup-android-arm64': 4.22.5 - '@rollup/rollup-darwin-arm64': 4.22.5 - '@rollup/rollup-darwin-x64': 4.22.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.22.5 - '@rollup/rollup-linux-arm-musleabihf': 4.22.5 - '@rollup/rollup-linux-arm64-gnu': 4.22.5 - '@rollup/rollup-linux-arm64-musl': 4.22.5 - '@rollup/rollup-linux-powerpc64le-gnu': 4.22.5 - '@rollup/rollup-linux-riscv64-gnu': 4.22.5 - '@rollup/rollup-linux-s390x-gnu': 4.22.5 - '@rollup/rollup-linux-x64-gnu': 4.22.5 - '@rollup/rollup-linux-x64-musl': 4.22.5 - '@rollup/rollup-win32-arm64-msvc': 4.22.5 - '@rollup/rollup-win32-ia32-msvc': 4.22.5 - '@rollup/rollup-win32-x64-msvc': 4.22.5 + '@rollup/rollup-android-arm-eabi': 4.23.0 + '@rollup/rollup-android-arm64': 4.23.0 + '@rollup/rollup-darwin-arm64': 4.23.0 + '@rollup/rollup-darwin-x64': 4.23.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.23.0 + '@rollup/rollup-linux-arm-musleabihf': 4.23.0 + '@rollup/rollup-linux-arm64-gnu': 4.23.0 + '@rollup/rollup-linux-arm64-musl': 4.23.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.23.0 + '@rollup/rollup-linux-riscv64-gnu': 4.23.0 + '@rollup/rollup-linux-s390x-gnu': 4.23.0 + '@rollup/rollup-linux-x64-gnu': 4.23.0 + '@rollup/rollup-linux-x64-musl': 4.23.0 + '@rollup/rollup-win32-arm64-msvc': 4.23.0 + '@rollup/rollup-win32-ia32-msvc': 4.23.0 + '@rollup/rollup-win32-x64-msvc': 4.23.0 fsevents: 2.3.3 run-applescript@7.0.0: {} @@ -12575,12 +12627,12 @@ snapshots: unbuild@2.0.0(sass@1.80.3)(typescript@5.6.2): dependencies: - '@rollup/plugin-alias': 5.1.1(rollup@3.29.4) - '@rollup/plugin-commonjs': 25.0.4(rollup@3.29.4) - '@rollup/plugin-json': 6.1.0(rollup@3.29.4) - '@rollup/plugin-node-resolve': 15.3.0(rollup@3.29.4) - '@rollup/plugin-replace': 5.0.2(rollup@3.29.4) - '@rollup/pluginutils': 5.1.2(rollup@3.29.4) + '@rollup/plugin-alias': 5.1.0(rollup@3.29.5) + '@rollup/plugin-commonjs': 25.0.4(rollup@3.29.5) + '@rollup/plugin-json': 6.1.0(rollup@3.29.5) + '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.5) + '@rollup/plugin-replace': 5.0.2(rollup@3.29.5) + '@rollup/pluginutils': 5.1.2(rollup@3.29.5) chalk: 5.3.0 citty: 0.1.4 consola: 3.2.3 @@ -12595,8 +12647,8 @@ snapshots: pathe: 1.1.2 pkg-types: 1.2.0 pretty-bytes: 6.1.1 - rollup: 3.29.4 - rollup-plugin-dts: 6.1.1(rollup@3.29.4)(typescript@5.6.2) + rollup: 3.29.5 + rollup-plugin-dts: 6.1.1(rollup@3.29.5)(typescript@5.6.2) scule: 1.0.0 untyped: 1.4.0 optionalDependencies: