-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
perf: regexp perf issues, refactor regexp stylistic issues #10905
Changes from all commits
3a365d1
9963f71
68be9c7
14a0e88
7e1fb2f
d6eabdf
a243549
b4c527a
59f35c8
dc06c5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,7 @@ const htmlTypesRE = /\.(html|vue|svelte|astro|imba)$/ | |
// since even missed imports can be caught at runtime, and false positives will | ||
// simply be ignored. | ||
export const importsRE = | ||
/(?<!\/\/.*)(?<=^|;|\*\/)\s*import(?!\s+type)(?:[\w*{}\n\r\t, ]+from\s*)?\s*("[^"]+"|'[^']+')\s*(?=$|;|\/\/|\/\*)/gm | ||
/(?<!\/\/.*)(?<=^|;|\*\/)\s*import(?!\s+type)(?:[\w*{}\n\r\t, ]+from)?\s*("[^"]+"|'[^']+')\s*(?=$|;|\/\/|\/\*)/gm | ||
|
||
export async function scanImports(config: ResolvedConfig): Promise<{ | ||
deps: Record<string, string> | ||
|
@@ -149,13 +149,13 @@ function globEntries(pattern: string | string[], config: ResolvedConfig) { | |
} | ||
|
||
const scriptModuleRE = | ||
/(<script\b[^>]*type\s*=\s*(?:"module"|'module')[^>]*>)(.*?)<\/script>/gims | ||
export const scriptRE = /(<script\b(?:\s[^>]*>|>))(.*?)<\/script>/gims | ||
/(<script\b[^>]+type\s*=\s*(?:"module"|'module')[^>]*>)(.*?)<\/script>/gis | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because |
||
export const scriptRE = /(<script(?:\s[^>]*>|>))(.*?)<\/script>/gis | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because |
||
export const commentRE = /<!--.*?-->/gs | ||
const srcRE = /\bsrc\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im | ||
const typeRE = /\btype\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im | ||
const langRE = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im | ||
const contextRE = /\bcontext\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/im | ||
const srcRE = /\bsrc\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i | ||
const typeRE = /\btype\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i | ||
const langRE = /\blang\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i | ||
const contextRE = /\bcontext\s*=\s*(?:"([^"]+)"|'([^']+)'|([^\s'">]+))/i | ||
|
||
function esbuildScanPlugin( | ||
config: ResolvedConfig, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,7 @@ 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 | ||
/\bnew\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*(?:,\s*)?\)/g | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
const cleanString = stripLiteral(code) | ||
|
||
let match: RegExpExecArray | null | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,13 +111,14 @@ export interface CSSModulesOptions { | |
|
||
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)($|\\?)` | ||
const cssLangRE = new RegExp(cssLangs) | ||
// eslint-disable-next-line regexp/no-unused-capturing-group | ||
const cssModuleRE = new RegExp(`\\.module${cssLangs}`) | ||
const directRequestRE = /(\?|&)direct\b/ | ||
const htmlProxyRE = /(\?|&)html-proxy\b/ | ||
const directRequestRE = /(?:\?|&)direct\b/ | ||
const htmlProxyRE = /(?:\?|&)html-proxy\b/ | ||
const commonjsProxyRE = /\?commonjs-proxy/ | ||
const inlineRE = /(\?|&)inline\b/ | ||
const inlineCSSRE = /(\?|&)inline-css\b/ | ||
const usedRE = /(\?|&)used\b/ | ||
const inlineRE = /(?:\?|&)inline\b/ | ||
const inlineCSSRE = /(?:\?|&)inline-css\b/ | ||
const usedRE = /(?:\?|&)used\b/ | ||
const varRE = /^var\(/i | ||
|
||
const cssBundleName = 'style.css' | ||
|
@@ -1175,11 +1176,13 @@ type CssUrlReplacer = ( | |
) => string | Promise<string> | ||
// https://drafts.csswg.org/css-syntax-3/#identifier-code-point | ||
export const cssUrlRE = | ||
/(?<=^|[^\w\-\u0080-\uffff])url\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/ | ||
/(?<=^|[^\w\-\u0080-\uffff])url\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/ | ||
export const cssDataUriRE = | ||
/(?<=^|[^\w\-\u0080-\uffff])data-uri\(\s*('[^']+'|"[^"]+"|[^'")]+)\s*\)/ | ||
/(?<=^|[^\w\-\u0080-\uffff])data-uri\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/ | ||
Comment on lines
-1178
to
+1181
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
export const importCssRE = /@import ('[^']+\.css'|"[^"]+\.css"|[^'")]+\.css)/ | ||
const cssImageSetRE = /(?<=image-set\()((?:[\w\-]+\([^\)]*\)|[^)])*)(?=\))/ | ||
// Assuming a function name won't be longer than 256 chars | ||
// eslint-disable-next-line regexp/no-unused-capturing-group -- doesn't detect asyncReplace usage | ||
const cssImageSetRE = /(?<=image-set\()((?:[\w\-]{1,256}\([^)]*\)|[^)])*)(?=\))/ | ||
|
||
const UrlRewritePostcssPlugin: PostCSS.PluginCreator<{ | ||
replacer: CssUrlReplacer | ||
|
@@ -1235,7 +1238,7 @@ function rewriteCssUrls( | |
): Promise<string> { | ||
return asyncReplace(css, cssUrlRE, async (match) => { | ||
const [matched, rawUrl] = match | ||
return await doUrlReplace(rawUrl, matched, replacer) | ||
return await doUrlReplace(rawUrl.trim(), matched, replacer) | ||
}) | ||
} | ||
|
||
|
@@ -1245,7 +1248,7 @@ function rewriteCssDataUris( | |
): Promise<string> { | ||
return asyncReplace(css, cssDataUriRE, async (match) => { | ||
const [matched, rawUrl] = match | ||
return await doUrlReplace(rawUrl, matched, replacer, 'data-uri') | ||
return await doUrlReplace(rawUrl.trim(), matched, replacer, 'data-uri') | ||
}) | ||
} | ||
|
||
|
@@ -1262,7 +1265,7 @@ function rewriteImportCss( | |
// TODO: image and cross-fade could contain a "url" that needs to be processed | ||
// https://drafts.csswg.org/css-images-4/#image-notation | ||
// https://drafts.csswg.org/css-images-4/#cross-fade-function | ||
const cssNotProcessedRE = /(gradient|element|cross-fade|image)\(/ | ||
const cssNotProcessedRE = /(?:gradient|element|cross-fade|image)\(/ | ||
|
||
async function rewriteCssImageSet( | ||
css: string, | ||
|
@@ -1391,7 +1394,7 @@ export async function hoistAtRules(css: string): Promise<string> { | |
// to top when multiple files are concatenated. | ||
// match until semicolon that's not in quotes | ||
const atImportRE = | ||
/@import\s*(?:url\([^\)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm | ||
/@import(?:\s*(?:url\([^)]*\)|"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g | ||
Comment on lines
-1394
to
+1397
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
while ((match = atImportRE.exec(cleanCss))) { | ||
s.remove(match.index, match.index + match[0].length) | ||
// Use `appendLeft` instead of `prepend` to preserve original @import order | ||
|
@@ -1401,7 +1404,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*(?:"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm | ||
/@charset(?:\s*(?:"(?:[^"]|(?<=\\)")*"|'(?:[^']|(?<=\\)')*').*?|[^;]*);/g | ||
let foundCharset = false | ||
while ((match = atCharsetRE.exec(cleanCss))) { | ||
s.remove(match.index, match.index + match[0].length) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
\s*
can be matched by the next\s*
.