Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use dedicated regex methods #15228

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/vite/src/node/__tests__/plugins/css.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ require("other-module");`
`"require("some-module"),/* empty css */require("other-module");"`,
)
// So there should be no pure css chunk anymore
expect(newCode.match(/pure_css_chunk\.js/)).toBeNull()
expect(newCode).not.toContain('pure_css_chunk.js')
})

test('replaces require call in minified code that uses comma operator followed by assignment', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/vite/src/node/__tests__/scan.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ describe('optimizer-scan:script-test', () => {
`import type Bar from 'foo'`,
]
shouldFailArray.forEach((str) => {
importsRE.lastIndex = 0
expect(importsRE.test(str)).toBe(false)
})
})
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ export function onRollupWarning(
const id = warning.id
const exporter = warning.exporter
// throw unless it's commonjs external...
if (!id || !/\?commonjs-external$/.test(id)) {
if (!id || !id.endsWith('?commonjs-external')) {
throw new Error(
`[vite]: Rollup failed to resolve import "${exporter}" from "${id}".\n` +
`This is most likely unintended because it can break your application at runtime.\n` +
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/optimizer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ export function runOptimizeDeps(
}

for (const o of Object.keys(meta.outputs)) {
if (!o.match(jsMapExtensionRE)) {
if (!jsMapExtensionRE.test(o)) {
const id = path
.relative(processingCacheDirOutputPath, o)
.replace(jsExtensionRE, '')
Expand Down
18 changes: 8 additions & 10 deletions packages/vite/src/node/plugins/assetImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,13 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
) {
let s: MagicString | undefined
const assetImportMetaUrlRE =
/\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g
// eslint-disable-next-line regexp/no-unused-capturing-group -- https://github.com/ota-meshi/eslint-plugin-regexp/issues/675
/\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 { 0: exp, 1: emptyUrl, index } = match

const urlStart = cleanString.indexOf(emptyUrl, index)
const urlEnd = urlStart + emptyUrl.length
const [[startIndex, endIndex], [urlStart, urlEnd]] = match.indices!
const rawUrl = code.slice(urlStart, urlEnd)

if (!s) s = new MagicString(code)
Expand Down Expand Up @@ -93,8 +91,8 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
query: injectQuery(queryString, 'url'),
}
s.update(
index,
index + exp.length,
startIndex,
endIndex,
`new URL((import.meta.glob(${JSON.stringify(
pattern,
)}, ${JSON.stringify(
Expand Down Expand Up @@ -141,15 +139,15 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
}
}
if (!builtUrl) {
const rawExp = code.slice(index, index + exp.length)
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`,
)
builtUrl = url
}
s.update(
index,
index + exp.length,
startIndex,
endIndex,
`new URL(${JSON.stringify(builtUrl)}, import.meta.url)`,
)
}
Expand Down
22 changes: 12 additions & 10 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1288,8 +1288,6 @@ export async function preprocessCSS(
return await compileCSS(filename, code, config)
}

const postcssReturnsVirtualFilesRE = /^<.+>$/

export async function formatPostcssSourceMap(
rawMap: ExistingRawSourceMap,
file: string,
Expand All @@ -1299,7 +1297,8 @@ export async function formatPostcssSourceMap(
const sources = rawMap.sources.map((source) => {
const cleanSource = cleanUrl(decodeURIComponent(source))

if (postcssReturnsVirtualFilesRE.test(cleanSource)) {
// postcss virtual files
if (cleanSource[0] === '<' && cleanSource[cleanSource.length - 1] === '>') {
return `\0${cleanSource}`
}

Expand Down Expand Up @@ -1373,7 +1372,7 @@ async function resolvePostcssConfig(
const searchPath =
typeof inlineOptions === 'string' ? inlineOptions : config.root
result = postcssrc({}, searchPath).catch((e) => {
if (!/No PostCSS Config found/.test(e.message)) {
if (!e.message.includes('No PostCSS Config found')) {
if (e instanceof Error) {
const { name, message, stack } = e
e.name = 'Failed to load PostCSS config'
Expand Down Expand Up @@ -1654,6 +1653,11 @@ function resolveMinifyCssEsbuildOptions(
}
}

const atImportRE =
/@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g
const atCharsetRE =
/@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g

export async function hoistAtRules(css: string): Promise<string> {
const s = new MagicString(css)
const cleanCss = emptyCssComments(css)
Expand All @@ -1663,8 +1667,7 @@ export async function hoistAtRules(css: string): Promise<string> {
// CSS @import can only appear at top of the file. We need to hoist all @import
// to top when multiple files are concatenated.
// match until semicolon that's not in quotes
const atImportRE =
/@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g
atImportRE.lastIndex = 0
while ((match = atImportRE.exec(cleanCss))) {
s.remove(match.index, match.index + match[0].length)
// Use `appendLeft` instead of `prepend` to preserve original @import order
Expand All @@ -1673,8 +1676,7 @@ export async function hoistAtRules(css: string): Promise<string> {

// #6333
// CSS @charset must be the top-first in the file, hoist the first to top
const atCharsetRE =
/@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g
atCharsetRE.lastIndex = 0
let foundCharset = false
while ((match = atCharsetRE.exec(cleanCss))) {
s.remove(match.index, match.index + match[0].length)
Expand Down Expand Up @@ -2406,8 +2408,8 @@ export const convertTargets = (

for (const entry of entriesWithoutES) {
if (entry === 'esnext') continue
const index = entry.match(versionRE)?.index
if (index) {
const index = entry.search(versionRE)
if (index >= 0) {
const browser = map[entry.slice(0, index)]
if (browser === false) continue // No mapping available
if (browser) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/esbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export const buildEsbuildPlugin = (config: ResolvedConfig): Plugin => {
const esbuildCode = res.code
const contentIndex =
opts.format === 'iife'
? esbuildCode.match(IIFE_BEGIN_RE)?.index || 0
? Math.max(esbuildCode.search(IIFE_BEGIN_RE), 0)
: opts.format === 'umd'
? esbuildCode.indexOf(`(function(`) // same for minified or not
: 0
Expand Down
18 changes: 9 additions & 9 deletions packages/vite/src/node/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ const htmlProxyRE =
const inlineCSSRE = /__VITE_INLINE_CSS__([a-z\d]{8}_\d+)__/g
// Do not allow preceding '.', but do allow preceding '...' for spread operations
const inlineImportRE =
/(?<!(?<!\.\.)\.)\bimport\s*\(("(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*')\)/g
// eslint-disable-next-line regexp/no-unused-capturing-group -- https://github.com/ota-meshi/eslint-plugin-regexp/issues/675
/(?<!(?<!\.\.)\.)\bimport\s*\(("(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*')\)/dg
const htmlLangRE = /\.(?:html|htm)$/

const importMapRE =
Expand Down Expand Up @@ -926,10 +927,9 @@ export function extractImportExpressionFromClassicScript(
let match: RegExpExecArray | null
inlineImportRE.lastIndex = 0
while ((match = inlineImportRE.exec(cleanCode))) {
const { 1: url, index } = match
const startUrl = cleanCode.indexOf(url, index)
const start = startUrl + 1
const end = start + url.length - 2
const [, [urlStart, urlEnd]] = match.indices!
const start = urlStart + 1
const end = urlEnd - 1
scriptUrls.push({
start: start + startOffset,
end: end + startOffset,
Expand Down Expand Up @@ -1004,11 +1004,11 @@ export function preImportMapHook(
config: ResolvedConfig,
): IndexHtmlTransformHook {
return (html, ctx) => {
const importMapIndex = html.match(importMapRE)?.index
if (importMapIndex === undefined) return
const importMapIndex = html.search(importMapRE)
if (importMapIndex < 0) return

const importMapAppendIndex = html.match(importMapAppendRE)?.index
if (importMapAppendIndex === undefined) return
const importMapAppendIndex = html.search(importMapAppendRE)
if (importMapAppendIndex < 0) return

if (importMapAppendIndex < importMapIndex) {
const relativeHtml = normalizePath(
Expand Down
6 changes: 3 additions & 3 deletions packages/vite/src/node/plugins/importAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
if (
(isRelative || isSelfImport) &&
!hasImportInQueryParamsRE.test(url) &&
!url.match(DEP_VERSION_RE)
!DEP_VERSION_RE.test(url)
) {
const versionMatch = importer.match(DEP_VERSION_RE)
if (versionMatch) {
Expand Down Expand Up @@ -535,7 +535,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
let rewriteDone = false
if (
depsOptimizer?.isOptimizedDepFile(resolvedId) &&
!resolvedId.match(optimizedDepChunkRE)
!optimizedDepChunkRE.test(resolvedId)
) {
// for optimized cjs deps, support named imports by rewriting named imports to const assignments.
// internal optimized chunks don't need es interop and are excluded
Expand All @@ -555,7 +555,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
// Non-entry dynamic imports from dependencies will reach here as there isn't
// optimize info for them, but they don't need es interop. If the request isn't
// a dynamic import, then it is an internal Vite error
if (!file.match(optimizedDepDynamicRE)) {
if (!optimizedDepDynamicRE.test(file)) {
config.logger.error(
colors.red(
`Vite Error, ${url} optimized info should be defined`,
Expand Down
16 changes: 6 additions & 10 deletions packages/vite/src/node/plugins/importAnalysisBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const preloadMarker = `__VITE_PRELOAD__`
export const preloadBaseMarker = `__VITE_PRELOAD_BASE__`

export const preloadHelperId = '\0vite/preload-helper.js'
const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`)
const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`, 'g')

const dynamicImportPrefixRE = /import\s*\(/

Expand All @@ -63,13 +63,9 @@ function indexOfMatchInSlice(
reg: RegExp,
pos: number = 0,
): number {
if (pos !== 0) {
str = str.slice(pos)
}

const matcher = str.match(reg)

return matcher?.index !== undefined ? matcher.index + pos : -1
reg.lastIndex = pos
const result = reg.exec(str)
return result?.index ?? -1
}

/**
Expand Down Expand Up @@ -351,7 +347,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
if (url !== specifier) {
if (
depsOptimizer.isOptimizedDepFile(resolvedId) &&
!resolvedId.match(optimizedDepChunkRE)
!optimizedDepChunkRE.test(resolvedId)
) {
const file = cleanUrl(resolvedId) // Remove ?v={hash}

Expand All @@ -368,7 +364,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
// Non-entry dynamic imports from dependencies will reach here as there isn't
// optimize info for them, but they don't need es interop. If the request isn't
// a dynamic import, then it is an internal Vite error
if (!file.match(optimizedDepDynamicRE)) {
if (!optimizedDepDynamicRE.test(file)) {
config.logger.error(
colors.red(
`Vite Error, ${url} optimized info should be defined`,
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
// Inject the current browserHash version if the path doesn't have one
if (
!resolveOptions.isBuild &&
!normalizedFsPath.match(DEP_VERSION_RE)
!DEP_VERSION_RE.test(normalizedFsPath)
) {
const browserHash = optimizedDepInfoFromFile(
depsOptimizer.metadata,
Expand Down Expand Up @@ -501,7 +501,7 @@ function ensureVersionQuery(
// file path after symlinks resolution
const isNodeModule = isInNodeModules(id) || isInNodeModules(resolved)

if (isNodeModule && !resolved.match(DEP_VERSION_RE)) {
if (isNodeModule && !DEP_VERSION_RE.test(resolved)) {
const versionHash = depsOptimizer.metadata.browserHash
if (versionHash && isOptimizable(resolved, depsOptimizer.options)) {
resolved = injectQuery(resolved, `v=${versionHash}`)
Expand Down
3 changes: 2 additions & 1 deletion packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}
)
}
if (code.match(workerAssetUrlRE)) {
workerAssetUrlRE.lastIndex = 0
if (workerAssetUrlRE.test(code)) {
const toRelativeRuntime = createToImportMetaURLBasedRelativeRuntime(
outputOptions.format,
config.isWorker,
Expand Down
21 changes: 8 additions & 13 deletions packages/vite/src/node/plugins/workerImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,31 +137,26 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
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*\))/g
// eslint-disable-next-line regexp/no-unused-capturing-group -- https://github.com/ota-meshi/eslint-plugin-regexp/issues/675
/\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 { 0: allExp, 1: exp, 2: emptyUrl, index } = match
const urlIndex = allExp.indexOf(exp) + index
const [[, endIndex], [expStart, expEnd], [urlStart, urlEnd]] =
match.indices!

const urlStart = cleanString.indexOf(emptyUrl, index)
const urlEnd = urlStart + emptyUrl.length
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.`,
urlIndex,
expStart,
)
}

s ||= new MagicString(code)
const workerType = getWorkerType(
code,
cleanString,
index + allExp.length,
)
const workerType = getWorkerType(code, cleanString, endIndex)
const url = rawUrl.slice(1, -1)
let file: string | undefined
if (url[0] === '.') {
Expand Down Expand Up @@ -190,8 +185,8 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
builtUrl = injectQuery(builtUrl, `type=${workerType}`)
}
s.update(
urlIndex,
urlIndex + exp.length,
expStart,
expEnd,
// add `'' +` to skip vite:asset-import-meta-url plugin
`new URL('' + ${JSON.stringify(builtUrl)}, import.meta.url)`,
)
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ export function fsPathFromId(id: string): string {
const fsPath = normalizePath(
id.startsWith(FS_PREFIX) ? id.slice(FS_PREFIX.length) : id,
)
return fsPath[0] === '/' || fsPath.match(VOLUME_RE) ? fsPath : `/${fsPath}`
return fsPath[0] === '/' || VOLUME_RE.test(fsPath) ? fsPath : `/${fsPath}`
}

export function fsPathFromUrl(url: string): string {
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/shared/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export class HMRClient {
}

protected warnFailedUpdate(err: Error, path: string | string[]): void {
if (!err.message.match('fetch')) {
if (!err.message.includes('fetch')) {
this.logger.error(err)
}
this.logger.error(
Expand Down
2 changes: 1 addition & 1 deletion playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test('should render', async () => {
if (!isBuild) {
test('should connect', async () => {
expect(browserLogs.length).toBe(3)
expect(browserLogs.some((msg) => msg.match('connected'))).toBe(true)
expect(browserLogs.some((msg) => msg.includes('connected'))).toBe(true)
browserLogs.length = 0
})

Expand Down
2 changes: 1 addition & 1 deletion playground/hmr/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ if (import.meta.hot) {

const cssUpdate = event.updates.find(
(update) =>
update.type === 'css-update' && update.path.match('global.css'),
update.type === 'css-update' && update.path.includes('global.css'),
)
if (cssUpdate) {
text(
Expand Down
2 changes: 1 addition & 1 deletion playground/vitestGlobalSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function setup(): Promise<void> {
return !hasWindowsUnicodeFsBug
}
file = file.replace(/\\/g, '/')
return !file.includes('__tests__') && !file.match(/dist(\/|$)/)
return !file.includes('__tests__') && !/dist(?:\/|$)/.test(file)
},
})
.catch(async (error) => {
Expand Down