Skip to content

Commit

Permalink
refactor: use dedicated regex methods (#15228)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red authored Dec 3, 2023
1 parent 5b85040 commit 0348137
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 67 deletions.
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

0 comments on commit 0348137

Please sign in to comment.