diff --git a/packages/vite/LICENSE.md b/packages/vite/LICENSE.md
index 477c9f826dda9b..86dfd162e42b67 100644
--- a/packages/vite/LICENSE.md
+++ b/packages/vite/LICENSE.md
@@ -360,6 +360,38 @@ Repository: lukeed/polka
---------------------------------------
+## @rolldown/pluginutils
+License: MIT
+Repository: git+https://github.com/rolldown/rolldown.git
+
+> MIT License
+>
+> Copyright (c) 2024-present VoidZero Inc. & Contributors
+>
+> 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.
+>
+> end of terms and conditions
+>
+> The licenses of externally maintained libraries from which parts of the Software is derived are listed [here](https://github.com/rolldown/rolldown/blob/main/THIRD-PARTY-LICENSE).
+
+---------------------------------------
+
## @rollup/plugin-alias, @rollup/plugin-commonjs, @rollup/plugin-dynamic-import-vars, @rollup/pluginutils
License: MIT
By: Johannes Stein
diff --git a/packages/vite/package.json b/packages/vite/package.json
index f83522bc1a860e..a1295b3019a277 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -97,6 +97,7 @@
"@jridgewell/trace-mapping": "^0.3.29",
"@oxc-project/types": "0.77.0",
"@polka/compression": "^1.0.0-next.25",
+ "@rolldown/pluginutils": "^1.0.0-beta.21",
"@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-dynamic-import-vars": "2.1.4",
diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts
index e710bbb2ba4cda..74f0220a4e9c19 100644
--- a/packages/vite/src/node/plugins/asset.ts
+++ b/packages/vite/src/node/plugins/asset.ts
@@ -166,13 +166,14 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
},
load: {
- async handler(id) {
- if (id[0] === '\0') {
+ filter: {
+ id: {
// Rollup convention, this id should be handled by the
// plugin that marked it with \0
- return
- }
-
+ exclude: /^\0/,
+ },
+ },
+ async handler(id) {
// raw requests, read from disk
if (rawRE.test(id)) {
const file = checkPublicFile(id, config) || cleanUrl(id)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index fe52cfb61fc34e..37aef68c303ad5 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -1,6 +1,7 @@
import path from 'node:path'
import MagicString from 'magic-string'
import { stripLiteral } from 'strip-literal'
+import { exactRegex } from '@rolldown/pluginutils'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import {
@@ -50,123 +51,121 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
},
transform: {
+ filter: {
+ id: {
+ exclude: [exactRegex(preloadHelperId), exactRegex(CLIENT_ENTRY)],
+ },
+ code: /new\s+URL.+import\.meta\.url/,
+ },
async handler(code, id) {
- if (
- id !== preloadHelperId &&
- id !== CLIENT_ENTRY &&
- code.includes('new URL') &&
- code.includes(`import.meta.url`)
- ) {
- let s: MagicString | undefined
- const assetImportMetaUrlRE =
- /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/dg
- const cleanString = stripLiteral(code)
-
- let match: RegExpExecArray | null
- while ((match = assetImportMetaUrlRE.exec(cleanString))) {
- const [[startIndex, endIndex], [urlStart, urlEnd]] = match.indices!
- if (hasViteIgnoreRE.test(code.slice(startIndex, urlStart))) continue
+ let s: MagicString | undefined
+ const assetImportMetaUrlRE =
+ /\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/dg
+ const cleanString = stripLiteral(code)
- const rawUrl = code.slice(urlStart, urlEnd)
+ let match: RegExpExecArray | null
+ while ((match = assetImportMetaUrlRE.exec(cleanString))) {
+ const [[startIndex, endIndex], [urlStart, urlEnd]] = match.indices!
+ if (hasViteIgnoreRE.test(code.slice(startIndex, urlStart))) continue
- if (!s) s = new MagicString(code)
+ const rawUrl = code.slice(urlStart, urlEnd)
- // potential dynamic template string
- if (rawUrl[0] === '`' && rawUrl.includes('${')) {
- const queryDelimiterIndex = getQueryDelimiterIndex(rawUrl)
- const hasQueryDelimiter = queryDelimiterIndex !== -1
- const pureUrl = hasQueryDelimiter
- ? rawUrl.slice(0, queryDelimiterIndex) + '`'
- : rawUrl
- const queryString = hasQueryDelimiter
- ? rawUrl.slice(queryDelimiterIndex, -1)
- : ''
- const ast = this.parse(pureUrl)
- const templateLiteral = (ast as any).body[0].expression
- if (templateLiteral.expressions.length) {
- const pattern = buildGlobPattern(templateLiteral)
- if (pattern.startsWith('*')) {
- // don't transform for patterns like this
- // because users won't intend to do that in most cases
- continue
- }
+ if (!s) s = new MagicString(code)
- const globOptions = {
- eager: true,
- import: 'default',
- // A hack to allow 'as' & 'query' exist at the same time
- query: injectQuery(queryString, 'url'),
- }
- s.update(
- startIndex,
- endIndex,
- `new URL((import.meta.glob(${JSON.stringify(
- pattern,
- )}, ${JSON.stringify(
- globOptions,
- )}))[${pureUrl}], import.meta.url)`,
- )
+ // potential dynamic template string
+ if (rawUrl[0] === '`' && rawUrl.includes('${')) {
+ const queryDelimiterIndex = getQueryDelimiterIndex(rawUrl)
+ const hasQueryDelimiter = queryDelimiterIndex !== -1
+ const pureUrl = hasQueryDelimiter
+ ? rawUrl.slice(0, queryDelimiterIndex) + '`'
+ : rawUrl
+ const queryString = hasQueryDelimiter
+ ? rawUrl.slice(queryDelimiterIndex, -1)
+ : ''
+ const ast = this.parse(pureUrl)
+ const templateLiteral = (ast as any).body[0].expression
+ if (templateLiteral.expressions.length) {
+ const pattern = buildGlobPattern(templateLiteral)
+ if (pattern.startsWith('*')) {
+ // don't transform for patterns like this
+ // because users won't intend to do that in most cases
continue
}
- }
- const url = rawUrl.slice(1, -1)
- if (isDataUrl(url)) {
+ const globOptions = {
+ eager: true,
+ import: 'default',
+ // A hack to allow 'as' & 'query' exist at the same time
+ query: injectQuery(queryString, 'url'),
+ }
+ s.update(
+ startIndex,
+ endIndex,
+ `new URL((import.meta.glob(${JSON.stringify(
+ pattern,
+ )}, ${JSON.stringify(
+ globOptions,
+ )}))[${pureUrl}], import.meta.url)`,
+ )
continue
}
- let file: string | undefined
- if (url[0] === '.') {
- file = slash(path.resolve(path.dirname(id), url))
- file = tryFsResolve(file, fsResolveOptions) ?? file
- } else {
- assetResolver ??= createBackCompatIdResolver(config, {
- extensions: [],
- mainFields: [],
- tryIndex: false,
- preferRelative: true,
- })
- file = await assetResolver(this.environment, url, id)
- file ??=
- url[0] === '/'
- ? slash(path.join(publicDir, url))
- : slash(path.resolve(path.dirname(id), url))
- }
+ }
- // Get final asset URL. If the file does not exist,
- // we fall back to the initial URL and let it resolve in runtime
- let builtUrl: string | undefined
- if (file) {
- try {
- if (publicDir && isParentDirectory(publicDir, file)) {
- const publicPath = '/' + path.posix.relative(publicDir, file)
- builtUrl = await fileToUrl(this, publicPath)
- } else {
- this.addWatchFile(file)
- builtUrl = await fileToUrl(this, file)
- }
- } catch {
- // do nothing, we'll log a warning after this
+ const url = rawUrl.slice(1, -1)
+ if (isDataUrl(url)) {
+ continue
+ }
+ let file: string | undefined
+ if (url[0] === '.') {
+ file = slash(path.resolve(path.dirname(id), url))
+ file = tryFsResolve(file, fsResolveOptions) ?? file
+ } else {
+ assetResolver ??= createBackCompatIdResolver(config, {
+ extensions: [],
+ mainFields: [],
+ tryIndex: false,
+ preferRelative: true,
+ })
+ file = await assetResolver(this.environment, url, id)
+ file ??=
+ url[0] === '/'
+ ? slash(path.join(publicDir, url))
+ : slash(path.resolve(path.dirname(id), url))
+ }
+
+ // Get final asset URL. If the file does not exist,
+ // we fall back to the initial URL and let it resolve in runtime
+ let builtUrl: string | undefined
+ if (file) {
+ try {
+ if (publicDir && isParentDirectory(publicDir, file)) {
+ const publicPath = '/' + path.posix.relative(publicDir, file)
+ builtUrl = await fileToUrl(this, publicPath)
+ } else {
+ this.addWatchFile(file)
+ builtUrl = await fileToUrl(this, file)
}
+ } catch {
+ // do nothing, we'll log a warning after this
}
- if (!builtUrl) {
- const rawExp = code.slice(startIndex, endIndex)
- config.logger.warnOnce(
- `\n${rawExp} doesn't exist at build time, it will remain unchanged to be resolved at runtime. ` +
- `If this is intended, you can use the /* @vite-ignore */ comment to suppress this warning.`,
- )
- builtUrl = url
- }
- s.update(
- startIndex,
- endIndex,
- `new URL(${JSON.stringify(builtUrl)}, import.meta.url)`,
- )
}
- if (s) {
- return transformStableResult(s, id, config)
+ if (!builtUrl) {
+ const rawExp = code.slice(startIndex, endIndex)
+ config.logger.warnOnce(
+ `\n${rawExp} doesn't exist at build time, it will remain unchanged to be resolved at runtime. ` +
+ `If this is intended, you can use the /* @vite-ignore */ comment to suppress this warning.`,
+ )
+ builtUrl = url
}
+ s.update(
+ startIndex,
+ endIndex,
+ `new URL(${JSON.stringify(builtUrl)}, import.meta.url)`,
+ )
+ }
+ if (s) {
+ return transformStableResult(s, id, config)
}
- return null
},
},
}
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index ffe4c4bf41b2bc..467bb6a84ef66c 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -334,9 +334,10 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
},
load: {
+ filter: {
+ id: CSS_LANGS_RE,
+ },
async handler(id) {
- if (!isCSSRequest(id)) return
-
if (urlRE.test(id)) {
if (isModuleCSSRequest(id)) {
throw new Error(
@@ -361,15 +362,13 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
},
},
transform: {
+ filter: {
+ id: {
+ include: CSS_LANGS_RE,
+ exclude: [commonjsProxyRE, SPECIAL_QUERY_RE],
+ },
+ },
async handler(raw, id) {
- if (
- !isCSSRequest(id) ||
- commonjsProxyRE.test(id) ||
- SPECIAL_QUERY_RE.test(id)
- ) {
- return
- }
-
const { environment } = this
const resolveUrl = (url: string, importer?: string) =>
idResolver(environment, url, importer)
@@ -509,15 +508,13 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
},
transform: {
+ filter: {
+ id: {
+ include: CSS_LANGS_RE,
+ exclude: [commonjsProxyRE, SPECIAL_QUERY_RE],
+ },
+ },
async handler(css, id) {
- if (
- !isCSSRequest(id) ||
- commonjsProxyRE.test(id) ||
- SPECIAL_QUERY_RE.test(id)
- ) {
- return
- }
-
css = stripBomTag(css)
// cache css compile result to map
@@ -1073,15 +1070,13 @@ export function cssAnalysisPlugin(config: ResolvedConfig): Plugin {
name: 'vite:css-analysis',
transform: {
+ filter: {
+ id: {
+ include: CSS_LANGS_RE,
+ exclude: [commonjsProxyRE, SPECIAL_QUERY_RE],
+ },
+ },
async handler(_, id) {
- if (
- !isCSSRequest(id) ||
- commonjsProxyRE.test(id) ||
- SPECIAL_QUERY_RE.test(id)
- ) {
- return
- }
-
const { moduleGraph } = this.environment as DevEnvironment
const thisModule = moduleGraph.getModuleById(id)
diff --git a/packages/vite/src/node/plugins/dynamicImportVars.ts b/packages/vite/src/node/plugins/dynamicImportVars.ts
index 1c16e7c7697218..e993bd2aa33bec 100644
--- a/packages/vite/src/node/plugins/dynamicImportVars.ts
+++ b/packages/vite/src/node/plugins/dynamicImportVars.ts
@@ -4,6 +4,7 @@ import { init, parse as parseImports } from 'es-module-lexer'
import type { ImportSpecifier } from 'es-module-lexer'
import { parseAst } from 'rollup/parseAst'
import { dynamicImportToGlob } from '@rollup/plugin-dynamic-import-vars'
+import { exactRegex } from '@rolldown/pluginutils'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import { CLIENT_ENTRY } from '../constants'
@@ -181,29 +182,27 @@ export function dynamicImportVarsPlugin(config: ResolvedConfig): Plugin {
name: 'vite:dynamic-import-vars',
resolveId: {
+ filter: { id: exactRegex(dynamicImportHelperId) },
handler(id) {
- if (id === dynamicImportHelperId) {
- return id
- }
+ return id
},
},
load: {
- handler(id) {
- if (id === dynamicImportHelperId) {
- return `export default ${dynamicImportHelper.toString()}`
- }
+ filter: { id: exactRegex(dynamicImportHelperId) },
+ handler(_id) {
+ return `export default ${dynamicImportHelper.toString()}`
},
},
transform: {
+ filter: {
+ id: { exclude: exactRegex(CLIENT_ENTRY) },
+ code: hasDynamicImportRE,
+ },
async handler(source, importer) {
const { environment } = this
- if (
- !getFilter(this)(importer) ||
- importer === CLIENT_ENTRY ||
- !hasDynamicImportRE.test(source)
- ) {
+ if (!getFilter(this)(importer)) {
return
}
diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index 56e328974cd708..a11060bbdfdb32 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -96,14 +96,14 @@ export function htmlInlineProxyPlugin(config: ResolvedConfig): Plugin {
name: 'vite:html-inline-proxy',
resolveId: {
+ filter: { id: isHtmlProxyRE },
handler(id) {
- if (isHTMLProxy(id)) {
- return id
- }
+ return id
},
},
load: {
+ filter: { id: isHtmlProxyRE },
handler(id) {
const proxyMatch = htmlProxyRE.exec(id)
if (proxyMatch) {
@@ -349,393 +349,379 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
name: 'vite:build-html',
transform: {
+ filter: { id: /\.html$/ },
async handler(html, id) {
- if (id.endsWith('.html')) {
- id = normalizePath(id)
- const relativeUrlPath = normalizePath(path.relative(config.root, id))
- const publicPath = `/${relativeUrlPath}`
- const publicBase = getBaseInHTML(relativeUrlPath, config)
-
- const publicToRelative = (filename: string) => publicBase + filename
- const toOutputPublicFilePath = (url: string) =>
- toOutputFilePathInHtml(
- url.slice(1),
- 'public',
- relativeUrlPath,
- 'html',
- config,
- publicToRelative,
- )
- // Determines true start position for the node, either the < character
- // position, or the newline at the end of the previous line's node.
- const nodeStartWithLeadingWhitespace = (
- node: DefaultTreeAdapterMap['node'],
- ) => {
- const startOffset = node.sourceCodeLocation!.startOffset
- if (startOffset === 0) return 0
-
- // Gets the offset for the start of the line including the
- // newline trailing the previous node
- const lineStartOffset =
- startOffset - node.sourceCodeLocation!.startCol
-
- //
- //
- //
- // Here we want to target the newline at the end of the previous line
- // as the start position for our target.
- //
- //
- //
- //
- // However, if there is content between our target node start and the
- // previous newline, we cannot strip it out without risking content deletion.
- let isLineEmpty = false
- try {
- const line = s.slice(Math.max(0, lineStartOffset), startOffset)
- isLineEmpty = !line.trim()
- } catch {
- // magic-string may throw if there's some content removed in the sliced string,
- // which we ignore and assume the line is not empty
- }
-
- return isLineEmpty ? lineStartOffset : startOffset
+ id = normalizePath(id)
+ const relativeUrlPath = normalizePath(path.relative(config.root, id))
+ const publicPath = `/${relativeUrlPath}`
+ const publicBase = getBaseInHTML(relativeUrlPath, config)
+
+ const publicToRelative = (filename: string) => publicBase + filename
+ const toOutputPublicFilePath = (url: string) =>
+ toOutputFilePathInHtml(
+ url.slice(1),
+ 'public',
+ relativeUrlPath,
+ 'html',
+ config,
+ publicToRelative,
+ )
+ // Determines true start position for the node, either the < character
+ // position, or the newline at the end of the previous line's node.
+ const nodeStartWithLeadingWhitespace = (
+ node: DefaultTreeAdapterMap['node'],
+ ) => {
+ const startOffset = node.sourceCodeLocation!.startOffset
+ if (startOffset === 0) return 0
+
+ // Gets the offset for the start of the line including the
+ // newline trailing the previous node
+ const lineStartOffset =
+ startOffset - node.sourceCodeLocation!.startCol
+
+ //
+ //
+ //
+ // Here we want to target the newline at the end of the previous line
+ // as the start position for our target.
+ //
+ //
+ //
+ //
+ // However, if there is content between our target node start and the
+ // previous newline, we cannot strip it out without risking content deletion.
+ let isLineEmpty = false
+ try {
+ const line = s.slice(Math.max(0, lineStartOffset), startOffset)
+ isLineEmpty = !line.trim()
+ } catch {
+ // magic-string may throw if there's some content removed in the sliced string,
+ // which we ignore and assume the line is not empty
}
- // pre-transform
- html = await applyHtmlTransforms(html, preHooks, this, {
- path: publicPath,
- filename: id,
- })
-
- let js = ''
- const s = new MagicString(html)
- const scriptUrls: ScriptAssetsUrl[] = []
- const styleUrls: ScriptAssetsUrl[] = []
- let inlineModuleIndex = -1
-
- let everyScriptIsAsync = true
- let someScriptsAreAsync = false
- let someScriptsAreDefer = false
-
- const assetUrlsPromises: Promise[] = []
-
- // for each encountered asset url, rewrite original html so that it
- // references the post-build location, ignoring empty attributes and
- // attributes that directly reference named output.
- const namedOutput = Object.keys(
- config.build.rollupOptions.input || {},
- )
- const processAssetUrl = async (
- url: string,
- shouldInline?: boolean,
- ) => {
- if (
- url !== '' && // Empty attribute
- !namedOutput.includes(url) && // Direct reference to named output
- !namedOutput.includes(removeLeadingSlash(url)) // Allow for absolute references as named output can't be an absolute path
- ) {
- try {
- return await urlToBuiltUrl(this, url, id, shouldInline)
- } catch (e) {
- if (e.code !== 'ENOENT') {
- throw e
- }
+ return isLineEmpty ? lineStartOffset : startOffset
+ }
+
+ // pre-transform
+ html = await applyHtmlTransforms(html, preHooks, this, {
+ path: publicPath,
+ filename: id,
+ })
+
+ let js = ''
+ const s = new MagicString(html)
+ const scriptUrls: ScriptAssetsUrl[] = []
+ const styleUrls: ScriptAssetsUrl[] = []
+ let inlineModuleIndex = -1
+
+ let everyScriptIsAsync = true
+ let someScriptsAreAsync = false
+ let someScriptsAreDefer = false
+
+ const assetUrlsPromises: Promise[] = []
+
+ // for each encountered asset url, rewrite original html so that it
+ // references the post-build location, ignoring empty attributes and
+ // attributes that directly reference named output.
+ const namedOutput = Object.keys(config.build.rollupOptions.input || {})
+ const processAssetUrl = async (url: string, shouldInline?: boolean) => {
+ if (
+ url !== '' && // Empty attribute
+ !namedOutput.includes(url) && // Direct reference to named output
+ !namedOutput.includes(removeLeadingSlash(url)) // Allow for absolute references as named output can't be an absolute path
+ ) {
+ try {
+ return await urlToBuiltUrl(this, url, id, shouldInline)
+ } catch (e) {
+ if (e.code !== 'ENOENT') {
+ throw e
}
}
- return url
}
+ return url
+ }
- const setModuleSideEffectPromises: Promise[] = []
- await traverseHtml(html, id, (node) => {
- if (!nodeIsElement(node)) {
- return
- }
+ const setModuleSideEffectPromises: Promise[] = []
+ await traverseHtml(html, id, (node) => {
+ if (!nodeIsElement(node)) {
+ return
+ }
- let shouldRemove = false
-
- // script tags
- if (node.nodeName === 'script') {
- const {
- src,
- srcSourceCodeLocation,
- isModule,
- isAsync,
- isIgnored,
- } = getScriptInfo(node)
-
- if (isIgnored) {
- removeViteIgnoreAttr(s, node.sourceCodeLocation!)
- } else {
- const url = src && src.value
- const isPublicFile = !!(url && checkPublicFile(url, config))
- if (isPublicFile) {
- // referencing public dir url, prefix with base
- overwriteAttrValue(
- s,
- srcSourceCodeLocation!,
- partialEncodeURIPath(toOutputPublicFilePath(url)),
- )
- }
+ let shouldRemove = false
- if (isModule) {
- inlineModuleIndex++
- if (url && !isExcludedUrl(url) && !isPublicFile) {
- setModuleSideEffectPromises.push(
- this.resolve(url, id).then((resolved) => {
- if (!resolved) {
- return Promise.reject(
- new Error(`Failed to resolve ${url} from ${id}`),
- )
- }
- // set moduleSideEffects to keep the module even if `treeshake.moduleSideEffects=false` is set
- const moduleInfo = this.getModuleInfo(resolved.id)
- if (moduleInfo) {
- moduleInfo.moduleSideEffects = true
- } else if (!resolved.external) {
- return this.load(resolved).then((mod) => {
- mod.moduleSideEffects = true
- })
- }
- }),
- )
- //
- // add it as an import
- js += `\nimport ${JSON.stringify(url)}`
- shouldRemove = true
- } else if (node.childNodes.length) {
- const scriptNode =
- node.childNodes.pop() as DefaultTreeAdapterMap['textNode']
- const contents = scriptNode.value
- //
- const filePath = id.replace(normalizePath(config.root), '')
- addToHTMLProxyCache(config, filePath, inlineModuleIndex, {
- code: contents,
- })
- js += `\nimport "${id}?html-proxy&index=${inlineModuleIndex}.js"`
- shouldRemove = true
- }
+ // script tags
+ if (node.nodeName === 'script') {
+ const { src, srcSourceCodeLocation, isModule, isAsync, isIgnored } =
+ getScriptInfo(node)
- everyScriptIsAsync &&= isAsync
- someScriptsAreAsync ||= isAsync
- someScriptsAreDefer ||= !isAsync
- } else if (url && !isPublicFile) {
- if (!isExcludedUrl(url)) {
- config.logger.warn(
- `
+ const filePath = id.replace(normalizePath(config.root), '')
+ addToHTMLProxyCache(config, filePath, inlineModuleIndex, {
+ code: contents,
+ })
+ js += `\nimport "${id}?html-proxy&index=${inlineModuleIndex}.js"`
+ shouldRemove = true
+ }
+
+ everyScriptIsAsync &&= isAsync
+ someScriptsAreAsync ||= isAsync
+ someScriptsAreDefer ||= !isAsync
+ } else if (url && !isPublicFile) {
+ if (!isExcludedUrl(url)) {
+ config.logger.warn(
+ ` asset
- for (const { start, end, url } of scriptUrls) {
- if (checkPublicFile(url, config)) {
- s.update(
- start,
- end,
- partialEncodeURIPath(toOutputPublicFilePath(url)),
- )
- } else if (!isExcludedUrl(url)) {
- s.update(
- start,
- end,
- partialEncodeURIPath(await urlToBuiltUrl(this, url, id)),
- )
- }
+ if (shouldRemove) {
+ // remove the script tag from the html. we are going to inject new
+ // ones in the end.
+ s.remove(
+ nodeStartWithLeadingWhitespace(node),
+ node.sourceCodeLocation!.endOffset,
+ )
}
+ })
+
+ isAsyncScriptMap.get(config)!.set(id, everyScriptIsAsync)
- // ignore if its url can't be resolved
- const resolvedStyleUrls = await Promise.all(
- styleUrls.map(async (styleUrl) => ({
- ...styleUrl,
- resolved: await this.resolve(styleUrl.url, id),
- })),
+ if (someScriptsAreAsync && someScriptsAreDefer) {
+ config.logger.warn(
+ `\nMixed async and defer script modules in ${id}, output script will fallback to defer. Every script, including inline ones, need to be marked as async for your output script to be async.`,
)
- for (const { start, end, url, resolved } of resolvedStyleUrls) {
- if (resolved == null) {
- config.logger.warnOnce(
- `\n${url} doesn't exist at build time, it will remain unchanged to be resolved at runtime`,
- )
- const importExpression = `\nimport ${JSON.stringify(url)}`
- js = js.replace(importExpression, '')
- } else {
- s.remove(start, end)
- }
- }
+ }
- processedHtml(this).set(id, s.toString())
+ await Promise.all(assetUrlsPromises)
- // inject module preload polyfill only when configured and needed
- const { modulePreload } = this.environment.config.build
- if (
- modulePreload !== false &&
- modulePreload.polyfill &&
- (someScriptsAreAsync || someScriptsAreDefer)
- ) {
- js = `import "${modulePreloadPolyfillId}";\n${js}`
+ // emit asset
+ for (const { start, end, url } of scriptUrls) {
+ if (checkPublicFile(url, config)) {
+ s.update(
+ start,
+ end,
+ partialEncodeURIPath(toOutputPublicFilePath(url)),
+ )
+ } else if (!isExcludedUrl(url)) {
+ s.update(
+ start,
+ end,
+ partialEncodeURIPath(await urlToBuiltUrl(this, url, id)),
+ )
}
+ }
- await Promise.all(setModuleSideEffectPromises)
+ // ignore if its url can't be resolved
+ const resolvedStyleUrls = await Promise.all(
+ styleUrls.map(async (styleUrl) => ({
+ ...styleUrl,
+ resolved: await this.resolve(styleUrl.url, id),
+ })),
+ )
+ for (const { start, end, url, resolved } of resolvedStyleUrls) {
+ if (resolved == null) {
+ config.logger.warnOnce(
+ `\n${url} doesn't exist at build time, it will remain unchanged to be resolved at runtime`,
+ )
+ const importExpression = `\nimport ${JSON.stringify(url)}`
+ js = js.replace(importExpression, '')
+ } else {
+ s.remove(start, end)
+ }
+ }
+
+ processedHtml(this).set(id, s.toString())
- // Force rollup to keep this module from being shared between other entry points.
- // If the resulting chunk is empty, it will be removed in generateBundle.
- return { code: js, moduleSideEffects: 'no-treeshake' }
+ // inject module preload polyfill only when configured and needed
+ const { modulePreload } = this.environment.config.build
+ if (
+ modulePreload !== false &&
+ modulePreload.polyfill &&
+ (someScriptsAreAsync || someScriptsAreDefer)
+ ) {
+ js = `import "${modulePreloadPolyfillId}";\n${js}`
}
+
+ await Promise.all(setModuleSideEffectPromises)
+
+ // Force rollup to keep this module from being shared between other entry points.
+ // If the resulting chunk is empty, it will be removed in generateBundle.
+ return { code: js, moduleSideEffects: 'no-treeshake' }
},
},
diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts
index 284f32f5c14380..277b609fa22e1d 100644
--- a/packages/vite/src/node/plugins/importAnalysisBuild.ts
+++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts
@@ -8,6 +8,7 @@ import { init, parse as parseImports } from 'es-module-lexer'
import type { SourceMap } from 'rollup'
import type { RawSourceMap } from '@ampproject/remapping'
import convertSourceMap from 'convert-source-map'
+import { exactRegex } from '@rolldown/pluginutils'
import { combineSourcemaps, generateCodeFrame, numberToPos } from '../utils'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
@@ -222,32 +223,27 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
return {
name: 'vite:build-import-analysis',
resolveId: {
+ filter: { id: exactRegex(preloadHelperId) },
handler(id) {
- if (id === preloadHelperId) {
- return id
- }
+ return id
},
},
load: {
- handler(id) {
- if (id === preloadHelperId) {
- const preloadCode = getPreloadCode(
- this.environment,
- !!renderBuiltUrl,
- isRelativeBase,
- )
- return { code: preloadCode, moduleSideEffects: false }
- }
+ filter: { id: exactRegex(preloadHelperId) },
+ handler(_id) {
+ const preloadCode = getPreloadCode(
+ this.environment,
+ !!renderBuiltUrl,
+ isRelativeBase,
+ )
+ return { code: preloadCode, moduleSideEffects: false }
},
},
transform: {
+ filter: { code: dynamicImportPrefixRE },
async handler(source, importer) {
- if (!dynamicImportPrefixRE.test(source)) {
- return
- }
-
await init
let imports: readonly ImportSpecifier[] = []
diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts
index e89aeb450363a7..774b4f56c4536b 100644
--- a/packages/vite/src/node/plugins/importMetaGlob.ts
+++ b/packages/vite/src/node/plugins/importMetaGlob.ts
@@ -52,8 +52,8 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
importGlobMaps.clear()
},
transform: {
+ filter: { code: 'import.meta.glob' },
async handler(code, id) {
- if (!code.includes('import.meta.glob')) return
const result = await transformGlobImport(
code,
id,
diff --git a/packages/vite/src/node/plugins/json.ts b/packages/vite/src/node/plugins/json.ts
index a516851cb03ace..7127eba2ed43fe 100644
--- a/packages/vite/src/node/plugins/json.ts
+++ b/packages/vite/src/node/plugins/json.ts
@@ -45,10 +45,10 @@ export function jsonPlugin(
name: 'vite:json',
transform: {
+ filter: {
+ id: { include: jsonExtRE, exclude: SPECIAL_QUERY_RE },
+ },
handler(json, id) {
- if (!jsonExtRE.test(id)) return null
- if (SPECIAL_QUERY_RE.test(id)) return null
-
if (inlineRE.test(id) || noInlineRE.test(id)) {
this.warn(
`\n` +
diff --git a/packages/vite/src/node/plugins/modulePreloadPolyfill.ts b/packages/vite/src/node/plugins/modulePreloadPolyfill.ts
index e662ddf7dd0857..d0558fd44f6ff4 100644
--- a/packages/vite/src/node/plugins/modulePreloadPolyfill.ts
+++ b/packages/vite/src/node/plugins/modulePreloadPolyfill.ts
@@ -1,3 +1,4 @@
+import { exactRegex } from '@rolldown/pluginutils'
import type { ResolvedConfig } from '..'
import type { Plugin } from '../plugin'
import { isModernFlag } from './importAnalysisBuild'
@@ -11,27 +12,25 @@ export function modulePreloadPolyfillPlugin(config: ResolvedConfig): Plugin {
return {
name: 'vite:modulepreload-polyfill',
resolveId: {
- handler(id) {
- if (id === modulePreloadPolyfillId) {
- return resolvedModulePreloadPolyfillId
- }
+ filter: { id: exactRegex(modulePreloadPolyfillId) },
+ handler(_id) {
+ return resolvedModulePreloadPolyfillId
},
},
load: {
- handler(id) {
- if (id === resolvedModulePreloadPolyfillId) {
- // `isModernFlag` is only available during build since it is resolved by `vite:build-import-analysis`
- if (
- config.command !== 'build' ||
- this.environment.config.consumer !== 'client'
- ) {
- return ''
- }
- if (!polyfillString) {
- polyfillString = `${isModernFlag}&&(${polyfill.toString()}());`
- }
- return { code: polyfillString, moduleSideEffects: true }
+ filter: { id: exactRegex(resolvedModulePreloadPolyfillId) },
+ handler(_id) {
+ // `isModernFlag` is only available during build since it is resolved by `vite:build-import-analysis`
+ if (
+ config.command !== 'build' ||
+ this.environment.config.consumer !== 'client'
+ ) {
+ return ''
+ }
+ if (!polyfillString) {
+ polyfillString = `${isModernFlag}&&(${polyfill.toString()}());`
}
+ return { code: polyfillString, moduleSideEffects: true }
},
},
}
diff --git a/packages/vite/src/node/plugins/wasm.ts b/packages/vite/src/node/plugins/wasm.ts
index 9b47ca9d302d5f..98cd50309aed59 100644
--- a/packages/vite/src/node/plugins/wasm.ts
+++ b/packages/vite/src/node/plugins/wasm.ts
@@ -1,3 +1,4 @@
+import { exactRegex } from '@rolldown/pluginutils'
import type { Plugin } from '../plugin'
import { fileToUrl } from './asset'
@@ -52,23 +53,19 @@ export const wasmHelperPlugin = (): Plugin => {
name: 'vite:wasm-helper',
resolveId: {
+ filter: { id: exactRegex(wasmHelperId) },
handler(id) {
- if (id === wasmHelperId) {
- return id
- }
+ return id
},
},
load: {
+ filter: { id: [exactRegex(wasmHelperId), wasmInitRE] },
async handler(id) {
if (id === wasmHelperId) {
return `export default ${wasmHelperCode}`
}
- if (!wasmInitRE.test(id)) {
- return
- }
-
const url = await fileToUrl(this, id)
return `
@@ -85,11 +82,8 @@ export const wasmFallbackPlugin = (): Plugin => {
name: 'vite:wasm-fallback',
load: {
- handler(id) {
- if (!id.endsWith('.wasm')) {
- return
- }
-
+ filter: { id: /\.wasm$/ },
+ handler(_id) {
throw new Error(
'"ESM integration proposal for Wasm" is not supported currently. ' +
'Use vite-plugin-wasm or other community plugins to handle this. ' +
diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
index c8c98520b0987d..8eb97cdd0d1e14 100644
--- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
@@ -181,16 +181,8 @@ async function getWorkerType(
return 'classic'
}
-function isIncludeWorkerImportMetaUrl(code: string): boolean {
- if (
- (code.includes('new Worker') || code.includes('new SharedWorker')) &&
- code.includes('new URL') &&
- code.includes(`import.meta.url`)
- ) {
- return true
- }
- return false
-}
+const workerImportMetaUrlRE =
+ /new\s+(?:Worker|SharedWorker)\s*\(\s*new\s+URL.+?import\.meta\.url/s
export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const isBuild = config.command === 'build'
@@ -213,85 +205,84 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
},
shouldTransformCachedModule({ code }) {
- if (isBuild && config.build.watch && isIncludeWorkerImportMetaUrl(code)) {
+ if (isBuild && config.build.watch && workerImportMetaUrlRE.test(code)) {
return true
}
},
transform: {
+ filter: { code: workerImportMetaUrlRE },
async handler(code, id) {
- if (isIncludeWorkerImportMetaUrl(code)) {
- let s: MagicString | undefined
- const cleanString = stripLiteral(code)
- const workerImportMetaUrlRE =
- /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/dg
-
- let match: RegExpExecArray | null
- while ((match = workerImportMetaUrlRE.exec(cleanString))) {
- const [[, endIndex], [expStart, expEnd], [urlStart, urlEnd]] =
- match.indices!
-
- const rawUrl = code.slice(urlStart, urlEnd)
-
- // potential dynamic template string
- if (rawUrl[0] === '`' && rawUrl.includes('${')) {
- this.error(
- `\`new URL(url, import.meta.url)\` is not supported in dynamic template string.`,
- expStart,
- )
- }
+ let s: MagicString | undefined
+ const cleanString = stripLiteral(code)
+ const workerImportMetaUrlRE =
+ /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/dg
+
+ let match: RegExpExecArray | null
+ while ((match = workerImportMetaUrlRE.exec(cleanString))) {
+ const [[, endIndex], [expStart, expEnd], [urlStart, urlEnd]] =
+ match.indices!
+
+ const rawUrl = code.slice(urlStart, urlEnd)
+
+ // potential dynamic template string
+ if (rawUrl[0] === '`' && rawUrl.includes('${')) {
+ this.error(
+ `\`new URL(url, import.meta.url)\` is not supported in dynamic template string.`,
+ expStart,
+ )
+ }
- s ||= new MagicString(code)
- const workerType = await getWorkerType(code, cleanString, endIndex)
- const url = rawUrl.slice(1, -1)
- let file: string | undefined
- if (url[0] === '.') {
- file = path.resolve(path.dirname(id), url)
- file = slash(tryFsResolve(file, fsResolveOptions) ?? file)
- } else {
- workerResolver ??= createBackCompatIdResolver(config, {
- extensions: [],
- tryIndex: false,
- preferRelative: true,
- })
- file = await workerResolver(this.environment, url, id)
- file ??=
- url[0] === '/'
- ? slash(path.join(config.publicDir, url))
- : slash(path.resolve(path.dirname(id), url))
- }
+ s ||= new MagicString(code)
+ const workerType = await getWorkerType(code, cleanString, endIndex)
+ const url = rawUrl.slice(1, -1)
+ let file: string | undefined
+ if (url[0] === '.') {
+ file = path.resolve(path.dirname(id), url)
+ file = slash(tryFsResolve(file, fsResolveOptions) ?? file)
+ } else {
+ workerResolver ??= createBackCompatIdResolver(config, {
+ extensions: [],
+ tryIndex: false,
+ preferRelative: true,
+ })
+ file = await workerResolver(this.environment, url, id)
+ file ??=
+ url[0] === '/'
+ ? slash(path.join(config.publicDir, url))
+ : slash(path.resolve(path.dirname(id), url))
+ }
- if (
- isBuild &&
- config.isWorker &&
- config.bundleChain.at(-1) === cleanUrl(file)
- ) {
- s.update(expStart, expEnd, 'self.location.href')
+ if (
+ isBuild &&
+ config.isWorker &&
+ config.bundleChain.at(-1) === cleanUrl(file)
+ ) {
+ s.update(expStart, expEnd, 'self.location.href')
+ } else {
+ let builtUrl: string
+ if (isBuild) {
+ builtUrl = await workerFileToUrl(config, file)
} else {
- let builtUrl: string
- if (isBuild) {
- builtUrl = await workerFileToUrl(config, file)
- } else {
- builtUrl = await fileToUrl(this, cleanUrl(file))
- builtUrl = injectQuery(
- builtUrl,
- `${WORKER_FILE_ID}&type=${workerType}`,
- )
- }
- s.update(
- expStart,
- expEnd,
- `new URL(/* @vite-ignore */ ${JSON.stringify(builtUrl)}, import.meta.url)`,
+ builtUrl = await fileToUrl(this, cleanUrl(file))
+ builtUrl = injectQuery(
+ builtUrl,
+ `${WORKER_FILE_ID}&type=${workerType}`,
)
}
+ s.update(
+ expStart,
+ expEnd,
+ `new URL(/* @vite-ignore */ ${JSON.stringify(builtUrl)}, import.meta.url)`,
+ )
}
+ }
- if (s) {
- return transformStableResult(s, id, config)
- }
-
- return null
+ if (s) {
+ return transformStableResult(s, id, config)
}
+
+ return null
},
},
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9750fc3dbf74c1..c9823bfbb4722f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -263,6 +263,9 @@ importers:
'@polka/compression':
specifier: ^1.0.0-next.25
version: 1.0.0-next.25
+ '@rolldown/pluginutils':
+ specifier: ^1.0.0-beta.21
+ version: 1.0.0-beta.21
'@rollup/plugin-alias':
specifier: ^5.1.1
version: 5.1.1(rollup@4.40.1)
@@ -1827,6 +1830,10 @@ packages:
resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==}
engines: {node: '>=6.9.0'}
+ '@babel/generator@7.27.5':
+ resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==}
+ engines: {node: '>=6.9.0'}
+
'@babel/generator@7.28.0':
resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==}
engines: {node: '>=6.9.0'}
@@ -2220,8 +2227,8 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-regenerator@7.28.0':
- resolution: {integrity: sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==}
+ '@babel/plugin-transform-regenerator@7.28.1':
+ resolution: {integrity: sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -2323,10 +2330,6 @@ packages:
resolution: {integrity: sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==}
engines: {node: '>=6.9.0'}
- '@babel/types@7.28.0':
- resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==}
- engines: {node: '>=6.9.0'}
-
'@babel/types@7.28.1':
resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==}
engines: {node: '>=6.9.0'}
@@ -2651,8 +2654,8 @@ packages:
'@iconify-json/logos@1.2.4':
resolution: {integrity: sha512-XC4If5D/hbaZvUkTV8iaZuGlQCyG6CNOlaAaJaGa13V5QMYwYjgtKk3vPP8wz3wtTVNVEVk3LRx1fOJz+YnSMw==}
- '@iconify-json/simple-icons@1.2.43':
- resolution: {integrity: sha512-JERgKGFRfZdyjGyTvVBVW5rftahy9tNUX+P+0QUnbaAEWvEMexXHE9863YVMVrIRhoj/HybGsibg8ZWieo/NDg==}
+ '@iconify-json/simple-icons@1.2.44':
+ resolution: {integrity: sha512-CdWgSPygwDlDbKtDWjvi3NtUefnkoepXv90n3dQxJerqzD9kI+nEJOiWUBM+eOyMYQKtxBpLWFBrgeotF0IZKw==}
'@iconify-json/vscode-icons@1.2.23':
resolution: {integrity: sha512-gFTcKecKra2/b5SbGDgHGI/l8CuikHyBPmqGlK+YCmS8AK72dtDQbUekdoACsju/3TYS37QvdPoOQwnyx2LdYg==}
@@ -3112,6 +3115,9 @@ packages:
'@rolldown/pluginutils@1.0.0-beta.19':
resolution: {integrity: sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==}
+ '@rolldown/pluginutils@1.0.0-beta.21':
+ resolution: {integrity: sha512-OTjWr7XYqRZaSzi6dTe0fP25EEsYEQ2H04xIedXG3D0Hrs+Bpe3V5L48R6y+R5ohTygp1ijC09mbrd7vlslpzA==}
+
'@rolldown/pluginutils@1.0.0-beta.29':
resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==}
@@ -4039,11 +4045,11 @@ packages:
'@vitest/utils@3.2.4':
resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
- '@volar/language-core@2.4.17':
- resolution: {integrity: sha512-chmRZMbKmcGpKMoO7Reb70uiLrzo0KWC2CkFttKUuKvrE+VYgi+fL9vWMJ07Fv5ulX0V1TAyyacN9q3nc5/ecA==}
+ '@volar/language-core@2.4.20':
+ resolution: {integrity: sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA==}
- '@volar/source-map@2.4.17':
- resolution: {integrity: sha512-QDybtQyO3Ms/NjFqNHTC5tbDN2oK5VH7ZaKrcubtfHBDj63n2pizHC3wlMQ+iT55kQXZUUAbmBX5L1C8CHFeBw==}
+ '@volar/source-map@2.4.20':
+ resolution: {integrity: sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg==}
'@vue/compiler-core@3.4.38':
resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==}
@@ -4084,8 +4090,8 @@ packages:
'@vue/devtools-shared@7.7.7':
resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==}
- '@vue/language-core@3.0.1':
- resolution: {integrity: sha512-sq+/Mc1IqIexWEQ+Q2XPiDb5SxSvY5JPqHnMOl/PlF5BekslzduX8dglSkpC17VeiAQB6dpS+4aiwNLJRduCNw==}
+ '@vue/language-core@3.0.3':
+ resolution: {integrity: sha512-I9wY0ULMN9tMSua+2C7g+ez1cIziVMUzIHlDYGSl2rtru3Eh4sXj95vZ+4GBuXwwPnEmYfzSApVbXiVbI8V5Gg==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
@@ -4349,11 +4355,11 @@ packages:
resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==}
engines: {node: '>=18'}
- brace-expansion@1.1.12:
- resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
+ brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
- brace-expansion@2.0.2:
- resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
@@ -4599,8 +4605,8 @@ packages:
resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
engines: {node: '>=12.13'}
- core-js-compat@3.43.0:
- resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==}
+ core-js-compat@3.44.0:
+ resolution: {integrity: sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==}
core-js@3.44.0:
resolution: {integrity: sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==}
@@ -7038,16 +7044,16 @@ packages:
engines: {node: '>=18.0.0'}
hasBin: true
- twoslash-protocol@0.3.2:
- resolution: {integrity: sha512-lWIL1dGcMr7cywSLSn8ufCoeyPab3bIwPE6DmAlQYQSMjJUgzzRvSz/LsQ179eNJafRghYDlIgF2v7pmsjV3Ww==}
+ twoslash-protocol@0.3.3:
+ resolution: {integrity: sha512-26NXjXEj+2NgytwOjjhFtNpQI7Zgct6PTyLg6JO7fIbO7MIm+kx89IxvBustgBOSKxoWjNBN2LXjNHHMD7+k0g==}
- twoslash-vue@0.3.2:
- resolution: {integrity: sha512-PzhlfoJBVSNx2H/fA/7vROIsr3s0EMoE4mxaP6k/4kj03woQ8vU0CqEhSfvCojYv4v6xYQJDyHFNhqzQuWT6Vg==}
+ twoslash-vue@0.3.3:
+ resolution: {integrity: sha512-CoIvzNK9QRJUUTTEzT0bFcf5kJc9wgBQHRcj5VcmhzFvcSdk/hevExeahcSHClpz1eE4EHJtma2+1wbK+GOjeg==}
peerDependencies:
typescript: ^5.5.0
- twoslash@0.3.2:
- resolution: {integrity: sha512-TB+ja888uMKhbng8HzpTHm+JfxIWbngIHPy4nKEt2N93MFjpqmkqn8ppnPhIKj4kDnrohEsiogMF7T1gMY06rw==}
+ twoslash@0.3.3:
+ resolution: {integrity: sha512-Yen1RBSYh/NUR6tfK6xT7DsXkBYby7lfp078Q7XoJR5dtAeG9jB5PVL1oF2sZwHapLjaqcZNlw7GSB8himZNsQ==}
peerDependencies:
typescript: ^5.5.0
@@ -7537,7 +7543,7 @@ snapshots:
'@babel/parser': 7.28.0
'@babel/template': 7.27.2
'@babel/traverse': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
convert-source-map: 2.0.0
debug: 4.4.1
gensync: 1.0.0-beta.2
@@ -7546,21 +7552,29 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@babel/generator@7.27.5':
+ dependencies:
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.27.7
+ '@jridgewell/gen-mapping': 0.3.8
+ '@jridgewell/trace-mapping': 0.3.29
+ jsesc: 3.1.0
+
'@babel/generator@7.28.0':
dependencies:
'@babel/parser': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
'@jridgewell/gen-mapping': 0.3.12
'@jridgewell/trace-mapping': 0.3.29
jsesc: 3.1.0
'@babel/helper-annotate-as-pure@7.27.1':
dependencies:
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
'@babel/helper-annotate-as-pure@7.27.3':
dependencies:
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
'@babel/helper-compilation-targets@7.27.2':
dependencies:
@@ -7578,7 +7592,7 @@ snapshots:
'@babel/helper-optimise-call-expression': 7.27.1
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0)
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
- '@babel/traverse': 7.28.0
+ '@babel/traverse': 7.27.7
semver: 6.3.1
transitivePeerDependencies:
- supports-color
@@ -7605,15 +7619,15 @@ snapshots:
'@babel/helper-member-expression-to-functions@7.27.1':
dependencies:
- '@babel/traverse': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/traverse': 7.27.7
+ '@babel/types': 7.27.7
transitivePeerDependencies:
- supports-color
'@babel/helper-module-imports@7.27.1':
dependencies:
'@babel/traverse': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
transitivePeerDependencies:
- supports-color
@@ -7628,7 +7642,7 @@ snapshots:
'@babel/helper-optimise-call-expression@7.27.1':
dependencies:
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
'@babel/helper-plugin-utils@7.27.1': {}
@@ -7637,7 +7651,7 @@ snapshots:
'@babel/core': 7.28.0
'@babel/helper-annotate-as-pure': 7.27.1
'@babel/helper-wrap-function': 7.27.1
- '@babel/traverse': 7.28.0
+ '@babel/traverse': 7.27.7
transitivePeerDependencies:
- supports-color
@@ -7646,14 +7660,14 @@ snapshots:
'@babel/core': 7.28.0
'@babel/helper-member-expression-to-functions': 7.27.1
'@babel/helper-optimise-call-expression': 7.27.1
- '@babel/traverse': 7.28.0
+ '@babel/traverse': 7.27.7
transitivePeerDependencies:
- supports-color
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
dependencies:
- '@babel/traverse': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/traverse': 7.27.7
+ '@babel/types': 7.27.7
transitivePeerDependencies:
- supports-color
@@ -7666,15 +7680,15 @@ snapshots:
'@babel/helper-wrap-function@7.27.1':
dependencies:
'@babel/template': 7.27.2
- '@babel/traverse': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/traverse': 7.27.7
+ '@babel/types': 7.27.7
transitivePeerDependencies:
- supports-color
'@babel/helpers@7.27.6':
dependencies:
'@babel/template': 7.27.2
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
'@babel/parser@7.27.5':
dependencies:
@@ -7682,7 +7696,7 @@ snapshots:
'@babel/parser@7.28.0':
dependencies:
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.0)':
dependencies:
@@ -7913,7 +7927,7 @@ snapshots:
'@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0)
'@babel/helper-plugin-utils': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
- '@babel/traverse': 7.28.0
+ '@babel/traverse': 7.27.7
transitivePeerDependencies:
- supports-color
@@ -8005,7 +8019,7 @@ snapshots:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-transform-regenerator@7.28.0(@babel/core@7.28.0)':
+ '@babel/plugin-transform-regenerator@7.28.1(@babel/core@7.28.0)':
dependencies:
'@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
@@ -8127,7 +8141,7 @@ snapshots:
'@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.0)
- '@babel/plugin-transform-regenerator': 7.28.0(@babel/core@7.28.0)
+ '@babel/plugin-transform-regenerator': 7.28.1(@babel/core@7.28.0)
'@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.0)
'@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.0)
@@ -8143,7 +8157,7 @@ snapshots:
babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.0)
babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.0)
babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.0)
- core-js-compat: 3.43.0
+ core-js-compat: 3.44.0
semver: 6.3.1
transitivePeerDependencies:
- supports-color
@@ -8161,15 +8175,15 @@ snapshots:
dependencies:
'@babel/code-frame': 7.27.1
'@babel/parser': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
'@babel/traverse@7.27.7':
dependencies:
'@babel/code-frame': 7.27.1
- '@babel/generator': 7.28.0
+ '@babel/generator': 7.27.5
'@babel/parser': 7.28.0
'@babel/template': 7.27.2
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
debug: 4.4.1
globals: 11.12.0
transitivePeerDependencies:
@@ -8182,7 +8196,7 @@ snapshots:
'@babel/helper-globals': 7.28.0
'@babel/parser': 7.28.0
'@babel/template': 7.27.2
- '@babel/types': 7.28.0
+ '@babel/types': 7.28.1
debug: 4.4.1
transitivePeerDependencies:
- supports-color
@@ -8192,11 +8206,6 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
- '@babel/types@7.28.0':
- dependencies:
- '@babel/helper-string-parser': 7.27.1
- '@babel/helper-validator-identifier': 7.27.1
-
'@babel/types@7.28.1':
dependencies:
'@babel/helper-string-parser': 7.27.1
@@ -8451,7 +8460,7 @@ snapshots:
dependencies:
'@iconify/types': 2.0.0
- '@iconify-json/simple-icons@1.2.43':
+ '@iconify-json/simple-icons@1.2.44':
dependencies:
'@iconify/types': 2.0.0
@@ -8540,7 +8549,7 @@ snapshots:
'@img/sharp-wasm32@0.33.5':
dependencies:
- '@emnapi/runtime': 1.4.3
+ '@emnapi/runtime': 1.4.5
optional: true
'@img/sharp-win32-ia32@0.33.5':
@@ -8832,6 +8841,8 @@ snapshots:
'@rolldown/pluginutils@1.0.0-beta.19': {}
+ '@rolldown/pluginutils@1.0.0-beta.21': {}
+
'@rolldown/pluginutils@1.0.0-beta.29': {}
'@rollup/plugin-alias@5.1.1(rollup@4.40.1)':
@@ -8991,7 +9002,7 @@ snapshots:
dependencies:
'@shikijs/core': 3.8.1
'@shikijs/types': 3.8.1
- twoslash: 0.3.2(typescript@5.7.3)
+ twoslash: 0.3.3(typescript@5.7.3)
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
@@ -9014,8 +9025,8 @@ snapshots:
mdast-util-gfm: 3.1.0
mdast-util-to-hast: 13.2.0
shiki: 3.8.1
- twoslash: 0.3.2(typescript@5.7.3)
- twoslash-vue: 0.3.2(typescript@5.7.3)
+ twoslash: 0.3.3(typescript@5.7.3)
+ twoslash-vue: 0.3.3(typescript@5.7.3)
vue: 3.5.17(typescript@5.7.3)
transitivePeerDependencies:
- '@nuxt/kit'
@@ -9724,11 +9735,11 @@ snapshots:
loupe: 3.1.4
tinyrainbow: 2.0.0
- '@volar/language-core@2.4.17':
+ '@volar/language-core@2.4.20':
dependencies:
- '@volar/source-map': 2.4.17
+ '@volar/source-map': 2.4.20
- '@volar/source-map@2.4.17': {}
+ '@volar/source-map@2.4.20': {}
'@vue/compiler-core@3.4.38':
dependencies:
@@ -9815,16 +9826,16 @@ snapshots:
dependencies:
rfdc: 1.4.1
- '@vue/language-core@3.0.1(typescript@5.7.3)':
+ '@vue/language-core@3.0.3(typescript@5.7.3)':
dependencies:
- '@volar/language-core': 2.4.17
+ '@volar/language-core': 2.4.20
'@vue/compiler-dom': 3.5.17
'@vue/compiler-vue2': 2.7.16
'@vue/shared': 3.5.17
alien-signals: 2.0.5
- minimatch: 10.0.3
muggle-string: 0.4.1
path-browserify: 1.0.1
+ picomatch: 4.0.3
optionalDependencies:
typescript: 5.7.3
@@ -10023,7 +10034,7 @@ snapshots:
dependencies:
'@babel/core': 7.28.0
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.0)
- core-js-compat: 3.43.0
+ core-js-compat: 3.44.0
transitivePeerDependencies:
- supports-color
@@ -10036,7 +10047,7 @@ snapshots:
babel-walk@3.0.0-canary-5:
dependencies:
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
bail@2.0.2: {}
@@ -10068,12 +10079,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- brace-expansion@1.1.12:
+ brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
- brace-expansion@2.0.2:
+ brace-expansion@2.0.1:
dependencies:
balanced-match: 1.0.2
@@ -10252,7 +10263,7 @@ snapshots:
constantinople@4.0.1:
dependencies:
'@babel/parser': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
content-disposition@1.0.0:
dependencies:
@@ -10308,7 +10319,7 @@ snapshots:
dependencies:
is-what: 4.1.16
- core-js-compat@3.43.0:
+ core-js-compat@3.44.0:
dependencies:
browserslist: 4.25.1
@@ -11692,7 +11703,7 @@ snapshots:
minimatch@10.0.1:
dependencies:
- brace-expansion: 2.0.2
+ brace-expansion: 2.0.1
minimatch@10.0.3:
dependencies:
@@ -11700,11 +11711,11 @@ snapshots:
minimatch@3.1.2:
dependencies:
- brace-expansion: 1.1.12
+ brace-expansion: 1.1.11
minimatch@9.0.5:
dependencies:
- brace-expansion: 2.0.2
+ brace-expansion: 2.0.1
minimist@1.2.8: {}
@@ -12937,21 +12948,21 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
- twoslash-protocol@0.3.2: {}
+ twoslash-protocol@0.3.3: {}
- twoslash-vue@0.3.2(typescript@5.7.3):
+ twoslash-vue@0.3.3(typescript@5.7.3):
dependencies:
- '@vue/language-core': 3.0.1(typescript@5.7.3)
- twoslash: 0.3.2(typescript@5.7.3)
- twoslash-protocol: 0.3.2
+ '@vue/language-core': 3.0.3(typescript@5.7.3)
+ twoslash: 0.3.3(typescript@5.7.3)
+ twoslash-protocol: 0.3.3
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
- twoslash@0.3.2(typescript@5.7.3):
+ twoslash@0.3.3(typescript@5.7.3):
dependencies:
'@typescript/vfs': 1.6.1(typescript@5.7.3)
- twoslash-protocol: 0.3.2
+ twoslash-protocol: 0.3.3
typescript: 5.7.3
transitivePeerDependencies:
- supports-color
@@ -13158,7 +13169,7 @@ snapshots:
dependencies:
'@docsearch/css': 3.9.0
'@docsearch/js': 3.9.0(@algolia/client-search@5.20.3)(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
- '@iconify-json/simple-icons': 1.2.43
+ '@iconify-json/simple-icons': 1.2.44
'@shikijs/core': 3.7.0
'@shikijs/transformers': 3.7.0
'@shikijs/types': 3.7.0
@@ -13271,7 +13282,7 @@ snapshots:
with@7.0.2:
dependencies:
'@babel/parser': 7.28.0
- '@babel/types': 7.28.0
+ '@babel/types': 7.27.7
assert-never: 1.4.0
babel-walk: 3.0.0-canary-5