Skip to content

Commit fc007df

Browse files
authored
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}`

0 commit comments

Comments
 (0)