Skip to content

Commit fc007df

Browse files
authoredNov 14, 2022
perf: regexp perf issues, refactor regexp stylistic issues (#10905)
fix #10900
1 parent 92a206b commit fc007df

38 files changed

+156
-89
lines changed
 

‎.eslintrc.cjs

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ module.exports = defineConfig({
77
extends: [
88
'eslint:recommended',
99
'plugin:node/recommended',
10-
'plugin:@typescript-eslint/recommended'
10+
'plugin:@typescript-eslint/recommended',
11+
'plugin:regexp/recommended'
1112
],
12-
plugins: ['import'],
13+
plugins: ['import', 'regexp'],
1314
parser: '@typescript-eslint/parser',
1415
parserOptions: {
1516
sourceType: 'module',
@@ -97,7 +98,9 @@ module.exports = defineConfig({
9798
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
9899
allowSeparatedGroups: false
99100
}
100-
]
101+
],
102+
103+
'regexp/no-contradiction-with-assertion': 'error'
101104
},
102105
overrides: [
103106
{

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"eslint-define-config": "^1.11.0",
6767
"eslint-plugin-import": "^2.26.0",
6868
"eslint-plugin-node": "^11.1.0",
69+
"eslint-plugin-regexp": "^1.10.0",
6970
"execa": "^6.1.0",
7071
"fast-glob": "^3.2.12",
7172
"fs-extra": "^10.1.0",

‎packages/create-vite/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ function copy(src: string, dest: string) {
388388
}
389389

390390
function isValidPackageName(projectName: string) {
391-
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
391+
return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(
392392
projectName
393393
)
394394
}
@@ -399,7 +399,7 @@ function toValidPackageName(projectName: string) {
399399
.toLowerCase()
400400
.replace(/\s+/g, '-')
401401
.replace(/^[._]/, '')
402-
.replace(/[^a-z0-9-~]+/g, '-')
402+
.replace(/[^a-z\d\-~]+/g, '-')
403403
}
404404

405405
function copyDir(srcDir: string, destDir: string) {

‎packages/plugin-react/src/fast-refresh.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ if (import.meta.hot) {
5656
RefreshRuntime.register(type, __SOURCE__ + " " + id)
5757
};
5858
window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
59-
}`.replace(/[\n]+/gm, '')
59+
}`.replace(/\n+/g, '')
6060

6161
const timeout = `
6262
if (!window.__vite_plugin_react_timeout) {

‎packages/plugin-react/src/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
110110
// - import * as React from 'react';
111111
// - import React from 'react';
112112
// - import React, {useEffect} from 'react';
113-
const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/
113+
const importReactRE = /(?:^|\n)import\s+(?:\*\s+as\s+)?React(?:,|\s+)/
114114

115115
// Any extension, including compound ones like '.bs.js'
116-
const fileExtensionRE = /\.[^\/\s\?]+$/
116+
const fileExtensionRE = /\.[^/\s?]+$/
117117

118118
const viteBabel: Plugin = {
119119
name: 'vite:react-babel',
@@ -202,7 +202,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
202202
filepath.match(fileExtensionRE) ||
203203
[]
204204

205-
if (/\.(mjs|[tj]sx?)$/.test(extension)) {
205+
if (/\.(?:mjs|[tj]sx?)$/.test(extension)) {
206206
const isJSX = extension.endsWith('x')
207207
const isNodeModules = id.includes('/node_modules/')
208208
const isProjectFile =

‎packages/plugin-vue/src/handleHotUpdate.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type { ResolvedOptions } from '.'
1111

1212
const debug = _debug('vite:hmr')
1313

14-
const directRequestRE = /(\?|&)direct\b/
14+
const directRequestRE = /(?:\?|&)direct\b/
1515

1616
/**
1717
* Vite-specific HMR handling
@@ -148,7 +148,7 @@ export async function handleHotUpdate(
148148
affectedModules.add(mainModule)
149149
} else if (mainModule && !affectedModules.has(mainModule)) {
150150
const styleImporters = [...mainModule.importers].filter((m) =>
151-
/\.css($|\?)/.test(m.url)
151+
/\.css(?:$|\?)/.test(m.url)
152152
)
153153
styleImporters.forEach((m) => affectedModules.add(m))
154154
}

‎packages/vite/src/node/config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ export async function resolveConfig(
465465
)
466466

467467
const clientAlias = [
468-
{ find: /^[\/]?@vite\/env/, replacement: () => ENV_ENTRY },
469-
{ find: /^[\/]?@vite\/client/, replacement: () => CLIENT_ENTRY }
468+
{ find: /^\/?@vite\/env/, replacement: () => ENV_ENTRY },
469+
{ find: /^\/?@vite\/client/, replacement: () => CLIENT_ENTRY }
470470
]
471471

472472
// resolve alias with internal client alias

‎packages/vite/src/node/constants.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ export const DEFAULT_CONFIG_FILES = [
4646

4747
export const JS_TYPES_RE = /\.(?:j|t)sx?$|\.mjs$/
4848

49-
export const OPTIMIZABLE_ENTRY_RE = /\.(?:[cm]?[jt]s)$/
49+
export const OPTIMIZABLE_ENTRY_RE = /\.[cm]?[jt]s$/
5050

51-
export const SPECIAL_QUERY_RE = /[\?&](?:worker|sharedworker|raw|url)\b/
51+
export const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/
5252

5353
/**
5454
* Prefix for resolved fs paths, since windows paths may not be valid as URLs.
@@ -129,7 +129,7 @@ export const DEFAULT_ASSETS_RE = new RegExp(
129129
`\\.(` + KNOWN_ASSET_TYPES.join('|') + `)(\\?.*)?$`
130130
)
131131

132-
export const DEP_VERSION_RE = /[\?&](v=[\w\.-]+)\b/
132+
export const DEP_VERSION_RE = /[?&](v=[\w.-]+)\b/
133133

134134
export const loopbackHosts = new Set([
135135
'localhost',

‎packages/vite/src/node/optimizer/esbuildDepPlugin.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ export function esbuildCjsExternalPlugin(externals: string[]): Plugin {
265265
name: 'cjs-external',
266266
setup(build) {
267267
const escape = (text: string) =>
268-
`^${text.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}$`
268+
`^${text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}$`
269269
const filter = new RegExp(externals.map(escape).join('|'))
270270

271271
build.onResolve({ filter: /.*/, namespace: 'external' }, (args) => ({

‎packages/vite/src/node/optimizer/scan.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const htmlTypesRE = /\.(html|vue|svelte|astro|imba)$/
4040
// since even missed imports can be caught at runtime, and false positives will
4141
// simply be ignored.
4242
export const importsRE =
43-
/(?<!\/\/.*)(?<=^|;|\*\/)\s*import(?!\s+type)(?:[\w*{}\n\r\t, ]+from\s*)?\s*("[^"]+"|'[^']+')\s*(?=$|;|\/\/|\/\*)/gm
43+
/(?<!\/\/.*)(?<=^|;|\*\/)\s*import(?!\s+type)(?:[\w*{}\n\r\t, ]+from)?\s*("[^"]+"|'[^']+')\s*(?=$|;|\/\/|\/\*)/gm
4444

4545
export async function scanImports(config: ResolvedConfig): Promise<{
4646
deps: Record<string, string>
@@ -149,13 +149,13 @@ function globEntries(pattern: string | string[], config: ResolvedConfig) {
149149
}
150150

151151
const scriptModuleRE =
152-
/(<script\b[^>]*type\s*=\s*(?:"module"|'module')[^>]*>)(.*?)<\/script>/gims
153-
export const scriptRE = /(<script\b(?:\s[^>]*>|>))(.*?)<\/script>/gims
152+
/(<script\b[^>]+type\s*=\s*(?:"module"|'module')[^>]*>)(.*?)<\/script>/gis
153+
export const scriptRE = /(<script(?:\s[^>]*>|>))(.*?)<\/script>/gis
154154
export const commentRE = /<!--.*?-->/gs
155-
const srcRE = /\bsrc\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im
156-
const typeRE = /\btype\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im
157-
const langRE = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im
158-
const contextRE = /\bcontext\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im
155+
const srcRE = /\bsrc\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i
156+
const typeRE = /\btype\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i
157+
const langRE = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i
158+
const contextRE = /\bcontext\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i
159159

160160
function esbuildScanPlugin(
161161
config: ResolvedConfig,

‎packages/vite/src/node/plugins/asset.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { FS_PREFIX } from '../constants'
2121

2222
export const assetUrlRE = /__VITE_ASSET__([a-z\d]+)__(?:\$_(.*?)__)?/g
2323

24-
const rawRE = /(\?|&)raw(?:&|$)/
24+
const rawRE = /(?:\?|&)raw(?:&|$)/
2525
const urlRE = /(\?|&)url(?:&|$)/
2626

2727
const assetCache = new WeakMap<ResolvedConfig, Map<string, string>>()
@@ -164,7 +164,7 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
164164
return
165165
}
166166

167-
id = id.replace(urlRE, '$1').replace(/[\?&]$/, '')
167+
id = id.replace(urlRE, '$1').replace(/[?&]$/, '')
168168
const url = await fileToUrl(id, config, this)
169169
return `export default ${JSON.stringify(url)}`
170170
},

‎packages/vite/src/node/plugins/assetImportMetaUrl.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
3838
) {
3939
let s: MagicString | undefined
4040
const assetImportMetaUrlRE =
41-
/\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*,?\s*\)/g
41+
/\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g
4242
const cleanString = stripLiteral(code)
4343

4444
let match: RegExpExecArray | null

‎packages/vite/src/node/plugins/css.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,14 @@ export interface CSSModulesOptions {
104104

105105
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)($|\\?)`
106106
const cssLangRE = new RegExp(cssLangs)
107+
// eslint-disable-next-line regexp/no-unused-capturing-group
107108
const cssModuleRE = new RegExp(`\\.module${cssLangs}`)
108-
const directRequestRE = /(\?|&)direct\b/
109-
const htmlProxyRE = /(\?|&)html-proxy\b/
109+
const directRequestRE = /(?:\?|&)direct\b/
110+
const htmlProxyRE = /(?:\?|&)html-proxy\b/
110111
const commonjsProxyRE = /\?commonjs-proxy/
111-
const inlineRE = /(\?|&)inline\b/
112-
const inlineCSSRE = /(\?|&)inline-css\b/
113-
const usedRE = /(\?|&)used\b/
112+
const inlineRE = /(?:\?|&)inline\b/
113+
const inlineCSSRE = /(?:\?|&)inline-css\b/
114+
const usedRE = /(?:\?|&)used\b/
114115
const varRE = /^var\(/i
115116

116117
const cssBundleName = 'style.css'
@@ -1163,11 +1164,13 @@ type CssUrlReplacer = (
11631164
) => string | Promise<string>
11641165
// https://drafts.csswg.org/css-syntax-3/#identifier-code-point
11651166
export const cssUrlRE =
1166-
/(?<=^|[^\w\-\u0080-\uffff])url\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/
1167+
/(?<=^|[^\w\-\u0080-\uffff])url\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/
11671168
export const cssDataUriRE =
1168-
/(?<=^|[^\w\-\u0080-\uffff])data-uri\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/
1169+
/(?<=^|[^\w\-\u0080-\uffff])data-uri\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/
11691170
export const importCssRE = /@import ('[^']+\.css'|"[^"]+\.css"|[^'")]+\.css)/
1170-
const cssImageSetRE = /(?<=image-set\()((?:[\w\-]+\([^\)]*\)|[^)])*)(?=\))/
1171+
// Assuming a function name won't be longer than 256 chars
1172+
// eslint-disable-next-line regexp/no-unused-capturing-group -- doesn't detect asyncReplace usage
1173+
const cssImageSetRE = /(?<=image-set\()((?:[\w\-]{1,256}\([^)]*\)|[^)])*)(?=\))/
11711174

11721175
const UrlRewritePostcssPlugin: PostCSS.PluginCreator<{
11731176
replacer: CssUrlReplacer
@@ -1223,7 +1226,7 @@ function rewriteCssUrls(
12231226
): Promise<string> {
12241227
return asyncReplace(css, cssUrlRE, async (match) => {
12251228
const [matched, rawUrl] = match
1226-
return await doUrlReplace(rawUrl, matched, replacer)
1229+
return await doUrlReplace(rawUrl.trim(), matched, replacer)
12271230
})
12281231
}
12291232

@@ -1233,7 +1236,7 @@ function rewriteCssDataUris(
12331236
): Promise<string> {
12341237
return asyncReplace(css, cssDataUriRE, async (match) => {
12351238
const [matched, rawUrl] = match
1236-
return await doUrlReplace(rawUrl, matched, replacer, 'data-uri')
1239+
return await doUrlReplace(rawUrl.trim(), matched, replacer, 'data-uri')
12371240
})
12381241
}
12391242

@@ -1250,7 +1253,7 @@ function rewriteImportCss(
12501253
// TODO: image and cross-fade could contain a "url" that needs to be processed
12511254
// https://drafts.csswg.org/css-images-4/#image-notation
12521255
// https://drafts.csswg.org/css-images-4/#cross-fade-function
1253-
const cssNotProcessedRE = /(gradient|element|cross-fade|image)\(/
1256+
const cssNotProcessedRE = /(?:gradient|element|cross-fade|image)\(/
12541257

12551258
async function rewriteCssImageSet(
12561259
css: string,
@@ -1379,7 +1382,7 @@ export async function hoistAtRules(css: string): Promise<string> {
13791382
// to top when multiple files are concatenated.
13801383
// match until semicolon that's not in quotes
13811384
const atImportRE =
1382-
/@import\s*(?:url\([^\)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm
1385+
/@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g
13831386
while ((match = atImportRE.exec(cleanCss))) {
13841387
s.remove(match.index, match.index + match[0].length)
13851388
// Use `appendLeft` instead of `prepend` to preserve original @import order
@@ -1389,7 +1392,7 @@ export async function hoistAtRules(css: string): Promise<string> {
13891392
// #6333
13901393
// CSS @charset must be the top-first in the file, hoist the first to top
13911394
const atCharsetRE =
1392-
/@charset\s*(?:"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm
1395+
/@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g
13931396
let foundCharset = false
13941397
while ((match = atCharsetRE.exec(cleanCss))) {
13951398
s.remove(match.index, match.index + match[0].length)

‎packages/vite/src/node/plugins/define.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { transformStableResult } from '../utils'
55
import { isCSSRequest } from './css'
66
import { isHTMLRequest } from './html'
77

8-
const nonJsRe = /\.(json)($|\?)/
8+
const nonJsRe = /\.json(?:$|\?)/
99
const isNonJsRequest = (request: string): boolean => nonJsRe.test(request)
1010

1111
export function definePlugin(config: ResolvedConfig): Plugin {

‎packages/vite/src/node/plugins/esbuild.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ import { searchForWorkspaceRoot } from '..'
2727
const debug = createDebugger('vite:esbuild')
2828

2929
const INJECT_HELPERS_IIFE_RE =
30-
/^(.*)((?:const|var) [^\s]+=function\([^)]*?\){"use strict";)/s
30+
/^(.*?)((?:const|var) \S+=function\([^)]*\)\{"use strict";)/s
3131
const INJECT_HELPERS_UMD_RE =
32-
/^(.*)(\(function\([^)]*?\){.+amd.+function\([^)]*?\){"use strict";)/s
32+
/^(.*?)(\(function\([^)]*\)\{.+amd.+function\([^)]*\)\{"use strict";)/s
3333

3434
let server: ViteDevServer
3535

‎packages/vite/src/node/plugins/html.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ const htmlProxyRE = /\?html-proxy=?(?:&inline-css)?&index=(\d+)\.(js|css)$/
4343
const inlineCSSRE = /__VITE_INLINE_CSS__([a-z\d]{8}_\d+)__/g
4444
// Do not allow preceding '.', but do allow preceding '...' for spread operations
4545
const inlineImportRE =
46-
/(?<!(?<!\.\.)\.)\bimport\s*\(("([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*')\)/g
47-
const htmlLangRE = /\.(html|htm)$/
46+
/(?<!(?<!\.\.)\.)\bimport\s*\(("(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*')\)/g
47+
const htmlLangRE = /\.(?:html|htm)$/
4848

4949
const importMapRE =
50-
/[ \t]*<script[^>]*type\s*=\s*["']?importmap["']?[^>]*>.*?<\/script>/is
51-
const moduleScriptRE = /[ \t]*<script[^>]*type\s*=\s*["']?module["']?[^>]*>/is
50+
/[ \t]*<script[^>]*type\s*=\s*(?:"importmap"|'importmap'|importmap)[^>]*>.*?<\/script>/is
51+
const moduleScriptRE =
52+
/[ \t]*<script[^>]*type\s*=\s*(?:"module"|'module'|module)[^>]*>/i
5253

5354
export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id)
5455

@@ -196,7 +197,7 @@ export function getScriptInfo(node: DefaultTreeAdapterMap['element']): {
196197
return { src, sourceCodeLocation, isModule, isAsync }
197198
}
198199

199-
const attrValueStartRE = /=[\s\t\n\r]*(.)/
200+
const attrValueStartRE = /=\s*(.)/
200201

201202
export function overwriteAttrValue(
202203
s: MagicString,

‎packages/vite/src/node/plugins/importAnalysis.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ const debug = createDebugger('vite:import-analysis')
7171

7272
const clientDir = normalizePath(CLIENT_DIR)
7373

74-
const skipRE = /\.(map|json)($|\?)/
74+
const skipRE = /\.(?:map|json)(?:$|\?)/
7575
export const canSkipImportAnalysis = (id: string): boolean =>
7676
skipRE.test(id) || isDirectCSSRequest(id)
7777

78-
const optimizedDepChunkRE = /\/chunk-[A-Z0-9]{8}\.js/
79-
const optimizedDepDynamicRE = /-[A-Z0-9]{8}\.js/
78+
const optimizedDepChunkRE = /\/chunk-[A-Z\d]{8}\.js/
79+
const optimizedDepDynamicRE = /-[A-Z\d]{8}\.js/
8080

8181
export function isExplicitImportRequired(url: string): boolean {
8282
return !isJSRequest(cleanUrl(url)) && !isCSSRequest(url)
@@ -347,7 +347,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
347347
// query can break 3rd party plugin's extension checks.
348348
if (
349349
(isRelative || isSelfImport) &&
350-
!/[\?&]import=?\b/.test(url) &&
350+
!/[?&]import=?\b/.test(url) &&
351351
!url.match(DEP_VERSION_RE)
352352
) {
353353
const versionMatch = importer.match(DEP_VERSION_RE)
@@ -583,7 +583,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
583583
.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '')
584584
.trim()
585585
if (
586-
!/^('.*'|".*"|`.*`)$/.test(url) ||
586+
!/^(?:'.*'|".*"|`.*`)$/.test(url) ||
587587
isExplicitImportRequired(url.slice(1, -1))
588588
) {
589589
needQueryInjectHelper = true

‎packages/vite/src/node/plugins/importAnalysisBuild.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ const preloadMarkerWithQuote = `"${preloadMarker}"` as const
3838
const dynamicImportPrefixRE = /import\s*\(/
3939

4040
// TODO: abstract
41-
const optimizedDepChunkRE = /\/chunk-[A-Z0-9]{8}\.js/
42-
const optimizedDepDynamicRE = /-[A-Z0-9]{8}\.js/
41+
const optimizedDepChunkRE = /\/chunk-[A-Z\d]{8}\.js/
42+
const optimizedDepDynamicRE = /-[A-Z\d]{8}\.js/
4343

4444
function toRelativePath(filename: string, importer: string) {
4545
const relPath = path.relative(path.dirname(importer), filename)

‎packages/vite/src/node/plugins/json.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ export interface JsonOptions {
2626
}
2727

2828
// Custom json filter for vite
29-
const jsonExtRE = /\.json($|\?)(?!commonjs-(proxy|external))/
29+
const jsonExtRE = /\.json(?:$|\?)(?!commonjs-(?:proxy|external))/
3030

31-
const jsonLangs = `\\.(json|json5)($|\\?)`
31+
const jsonLangs = `\\.(?:json|json5)(?:$|\\?)`
3232
const jsonLangRE = new RegExp(jsonLangs)
3333
export const isJSONRequest = (request: string): boolean =>
3434
jsonLangRE.test(request)
@@ -71,7 +71,7 @@ export function jsonPlugin(
7171
map: { mappings: '' }
7272
}
7373
} catch (e) {
74-
const errorMessageList = /[\d]+/.exec(e.message)
74+
const errorMessageList = /\d+/.exec(e.message)
7575
const position = errorMessageList && parseInt(errorMessageList[0], 10)
7676
const msg = position
7777
? `, invalid JSON syntax found at line ${position}`

‎packages/vite/src/node/plugins/resolve.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const browserExternalId = '__vite-browser-external'
5555
// special id for packages that are optional peer deps
5656
export const optionalPeerDepId = '__vite-optional-peer-dep'
5757

58-
const nodeModulesInPathRE = /(^|\/)node_modules\//
58+
const nodeModulesInPathRE = /(?:^|\/)node_modules\//
5959

6060
const isDebug = process.env.DEBUG
6161
const debug = createDebugger('vite:resolve-details', {

‎packages/vite/src/node/plugins/splitVendorChunk.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { UserConfig } from '../../node'
88
import type { Plugin } from '../plugin'
99

1010
// This file will be built for both ESM and CJS. Avoid relying on other modules as possible.
11-
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\\?)`
11+
const cssLangs = `\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)`
1212
const cssLangRE = new RegExp(cssLangs)
1313
export const isCSSRequest = (request: string): boolean =>
1414
cssLangRE.test(request)

‎packages/vite/src/node/plugins/workerImportMetaUrl.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function getWorkerType(raw: string, clean: string, i: number): WorkerType {
4141
// need to find in comment code
4242
const workerOptString = raw
4343
.substring(commaIndex + 1, endIndex)
44-
.replace(/}[^]*,/g, '}') // strip trailing comma for parsing
44+
.replace(/\}[\s\S]*,/g, '}') // strip trailing comma for parsing
4545

4646
const hasViteIgnore = ignoreFlagRE.test(workerOptString)
4747
if (hasViteIgnore) {
@@ -91,11 +91,11 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
9191
let s: MagicString | undefined
9292
const cleanString = stripLiteral(code)
9393
const workerImportMetaUrlRE =
94-
/\bnew\s+(Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g
94+
/\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g
9595

9696
let match: RegExpExecArray | null
9797
while ((match = workerImportMetaUrlRE.exec(cleanString))) {
98-
const { 0: allExp, 2: exp, 3: emptyUrl, index } = match
98+
const { 0: allExp, 1: exp, 2: emptyUrl, index } = match
9999
const urlIndex = allExp.indexOf(exp) + index
100100

101101
const urlStart = cleanString.indexOf(emptyUrl, index)

‎packages/vite/src/node/server/sourcemap.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const debug = createDebugger('vite:sourcemap', {
1212
// Virtual modules should be prefixed with a null byte to avoid a
1313
// false positive "missing source" warning. We also check for certain
1414
// prefixes used for special handling in esbuildDepPlugin.
15-
const virtualSourceRE = /^(\0|dep:|browser-external:)/
15+
const virtualSourceRE = /^(?:\0|dep:|browser-external:)/
1616

1717
interface SourceMapLike {
1818
sources: string[]

‎packages/vite/src/node/ssr/ssrExternal.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function cjsSsrResolveExternals(
8383
}
8484

8585
const CJS_CONTENT_RE =
86-
/\bmodule\.exports\b|\bexports[.\[]|\brequire\s*\(|\bObject\.(defineProperty|defineProperties|assign)\s*\(\s*exports\b/
86+
/\bmodule\.exports\b|\bexports[.[]|\brequire\s*\(|\bObject\.(?:defineProperty|defineProperties|assign)\s*\(\s*exports\b/
8787

8888
// TODO: use import()
8989
const _require = createRequire(import.meta.url)

‎packages/vite/src/node/ssr/ssrStacktrace.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function ssrRewriteStacktrace(
2020
.split('\n')
2121
.map((line) => {
2222
return line.replace(
23-
/^ {4}at (?:(.+?)\s+\()?(?:(.+?):(\d+)(?::(\d+))?)\)?/,
23+
/^ {4}at (?:(\S.*?)\s\()?(.+?):(\d+)(?::(\d+))?\)?/,
2424
(input, varName, url, line, column) => {
2525
if (!url) return input
2626

@@ -42,11 +42,12 @@ export function ssrRewriteStacktrace(
4242
return input
4343
}
4444

45+
const trimedVarName = varName.trim()
4546
const source = `${pos.source}:${pos.line}:${pos.column}`
46-
if (!varName || varName === 'eval') {
47+
if (!trimedVarName || trimedVarName === 'eval') {
4748
return ` at ${source}`
4849
} else {
49-
return ` at ${varName} (${source})`
50+
return ` at ${trimedVarName} (${source})`
5051
}
5152
}
5253
)

‎packages/vite/src/node/utils.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ export function unwrapId(id: string): string {
7676

7777
export const flattenId = (id: string): string =>
7878
id
79-
.replace(/[\/:]/g, '_')
80-
.replace(/[\.]/g, '__')
79+
.replace(/[/:]/g, '_')
80+
.replace(/\./g, '__')
8181
.replace(/(\s*>\s*)/g, '___')
8282

8383
export const normalizeId = (id: string): string =>
@@ -276,7 +276,7 @@ export const isDataUrl = (url: string): boolean => dataUrlRE.test(url)
276276
export const virtualModuleRE = /^virtual-module:.*/
277277
export const virtualModulePrefix = 'virtual-module:'
278278

279-
const knownJsSrcRE = /\.((j|t)sx?|m[jt]s|vue|marko|svelte|astro|imba)($|\?)/
279+
const knownJsSrcRE = /\.(?:[jt]sx?|m[jt]s|vue|marko|svelte|astro|imba)(?:$|\?)/
280280
export const isJSRequest = (url: string): boolean => {
281281
url = cleanUrl(url)
282282
if (knownJsSrcRE.test(url)) {
@@ -288,8 +288,8 @@ export const isJSRequest = (url: string): boolean => {
288288
return false
289289
}
290290

291-
const knownTsRE = /\.(ts|mts|cts|tsx)$/
292-
const knownTsOutputRE = /\.(js|mjs|cjs|jsx)$/
291+
const knownTsRE = /\.(?:ts|mts|cts|tsx)$/
292+
const knownTsOutputRE = /\.(?:js|mjs|cjs|jsx)$/
293293
export const isTsRequest = (url: string): boolean => knownTsRE.test(url)
294294
export const isPossibleTsOutput = (url: string): boolean =>
295295
knownTsOutputRE.test(cleanUrl(url))
@@ -311,7 +311,7 @@ const internalPrefixes = [
311311
ENV_PUBLIC_PATH
312312
]
313313
const InternalPrefixRE = new RegExp(`^(?:${internalPrefixes.join('|')})`)
314-
const trailingSeparatorRE = /[\?&]$/
314+
const trailingSeparatorRE = /[?&]$/
315315
export const isImportRequest = (url: string): boolean => importQueryRE.test(url)
316316
export const isInternalRequest = (url: string): boolean =>
317317
InternalPrefixRE.test(url)
@@ -684,7 +684,7 @@ function splitSrcSet(srcs: string) {
684684
const parts: string[] = []
685685
// There could be a ',' inside of url(data:...), linear-gradient(...) or "data:..."
686686
const cleanedSrcs = srcs.replace(
687-
/(?:url|image|gradient|cross-fade)\([^\)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'/g,
687+
/(?:url|image|gradient|cross-fade)\([^)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'/g,
688688
blankReplacer
689689
)
690690
let startIndex = 0
@@ -908,9 +908,9 @@ export function toUpperCaseDriveLetter(pathName: string): string {
908908
}
909909

910910
// Taken from https://stackoverflow.com/a/36328890
911-
export const multilineCommentsRE = /\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\//gm
911+
export const multilineCommentsRE = /\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\//g
912912
export const singlelineCommentsRE = /\/\/.*/g
913-
export const requestQuerySplitRE = /\?(?!.*[\/|\}])/
913+
export const requestQuerySplitRE = /\?(?!.*[/|}])/
914914

915915
// @ts-expect-error
916916
export const usingDynamicImport = typeof jest === 'undefined'

‎playground/cli-module/__tests__/serve.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ async function startedOnPort(serverProcess, port, timeout) {
120120
// hack, console output may contain color code gibberish
121121
// skip gibberish between localhost: and port number
122122
const match = str.match(
123-
/(http:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):)(?:.*)(\d{4})/
123+
/(http:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):).*(\d{4})/
124124
)
125125
if (match) {
126126
const startedPort = parseInt(match[2], 10)

‎playground/cli/__tests__/serve.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ async function startedOnPort(serverProcess, port, timeout) {
120120
// hack, console output may contain color code gibberish
121121
// skip gibberish between localhost: and port number
122122
const match = str.match(
123-
/(http:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):)(?:.*)(\d{4})/
123+
/(http:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):).*(\d{4})/
124124
)
125125
if (match) {
126126
const startedPort = parseInt(match[2], 10)

‎playground/css/__tests__/css.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
// in later assertions to ensure CSS HMR doesn't reload the page
1919
test('imported css', async () => {
2020
const css = await page.textContent('.imported-css')
21-
expect(css).toMatch(/\.imported ?{/)
21+
expect(css).toMatch(/\.imported ?\{/)
2222
if (isBuild) {
2323
expect(css.trim()).not.toContain('\n') // check minified
2424
}

‎playground/lib/__tests__/lib.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe.runIf(isBuild)('build', () => {
2424
expect(await page.textContent('.iife')).toBe('It works')
2525
const code = readFile('dist/my-lib-custom-filename.iife.js')
2626
// esbuild helpers are injected inside of the IIFE wrapper
27-
expect(code).toMatch(/^var MyLib=function\(\){"use strict";/)
27+
expect(code).toMatch(/^var MyLib=function\(\)\{"use strict";/)
2828
})
2929

3030
test('Library mode does not include `preload`', async () => {

‎playground/tsconfig-json-load-error/__tests__/tsconfig-json-load-error.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe.runIf(isBuild)('build', () => {
1414
test('should throw an error on build', () => {
1515
expect(serveError).toBeTruthy()
1616
expect(serveError.message).toMatch(
17-
/^parsing .* failed: SyntaxError: Unexpected token } in JSON at position \d+$/
17+
/^parsing .* failed: SyntaxError: Unexpected token \} in JSON at position \d+$/
1818
)
1919
clearServeError() // got expected error, null it here so testsuite does not fail from rethrow in afterAll
2020
})
@@ -46,7 +46,7 @@ describe.runIf(isServe)('server', () => {
4646
})
4747
// use regex with variable filename and position values because they are different on win
4848
expect(message).toMatch(
49-
/^parsing .* failed: SyntaxError: Unexpected token } in JSON at position \d+$/
49+
/^parsing .* failed: SyntaxError: Unexpected token \} in JSON at position \d+$/
5050
)
5151
})
5252

‎playground/vue-server-origin/__tests__/vue-server-origin.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { isBuild, page } from '~utils'
33

44
test('should render', async () => {
55
const expected = isBuild
6-
? /assets\/asset\.[0-9a-f]+\.png/
6+
? /assets\/asset\.[\da-f]+\.png/
77
: 'http://localhost/server-origin/test/assets/asset.png'
88

99
expect(await page.getAttribute('img', 'src')).toMatch(expected)

‎playground/worker/__tests__/sourcemap-hidden/sourcemap-hidden-worker.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ describe.runIf(isBuild)('build', () => {
114114
})
115115

116116
function getSourceMapUrl(code: string): string {
117-
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g
117+
const regex = /\/\/[#@]\ssource(?:Mapping)?URL=\s*(\S+)/
118118
const results = regex.exec(code)
119119

120120
if (results && results.length >= 2) {

‎playground/worker/__tests__/sourcemap-inline/sourcemap-inline-worker.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe.runIf(isBuild)('build', () => {
9797
})
9898

9999
function getSourceMapUrl(code: string): string {
100-
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g
100+
const regex = /\/\/[#@]\ssource(?:Mapping)?URL=\s*(\S+)/
101101
const results = regex.exec(code)
102102

103103
if (results && results.length >= 2) {

‎playground/worker/__tests__/sourcemap/sourcemap-worker.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ describe.runIf(isBuild)('build', () => {
115115
})
116116

117117
function getSourceMapUrl(code: string): string {
118-
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g
118+
const regex = /\/\/[#@]\ssource(?:Mapping)?URL=\s*(\S+)/
119119
const results = regex.exec(code)
120120

121121
if (results && results.length >= 2) {

‎pnpm-lock.yaml

+58
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎scripts/rollupLicensePlugin.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ function licensePlugin(licenseFilePath, licenseTitle, packageName) {
9090
'\n' +
9191
licenseText
9292
.trim()
93-
.replace(/(\r\n|\r)/gm, '\n')
93+
.replace(/(\r\n|\r)/g, '\n')
9494
.split('\n')
9595
.map((line) => `> ${line}`)
9696
.join('\n') +

‎scripts/verifyCommit.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const msg = readFileSync(msgPath, 'utf-8').trim()
99

1010
const releaseRE = /^v\d/
1111
const commitRE =
12-
/^(revert: )?(feat|fix|docs|dx|refactor|perf|test|workflow|build|ci|chore|types|wip|release|deps)(\(.+\))?: .{1,50}/
12+
/^(?:revert: )?(?:feat|fix|docs|dx|refactor|perf|test|workflow|build|ci|chore|types|wip|release|deps)(?:\(.+\))?: .{1,50}/
1313

1414
if (!releaseRE.test(msg) && !commitRE.test(msg)) {
1515
console.log()

0 commit comments

Comments
 (0)
Please sign in to comment.