Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9e23ace

Browse files
GalacticHypernovadanielroe
authored andcommitted
perf(kit,nuxt,vite,webpack): hoist regex patterns (#29620)
1 parent 56ceb18 commit 9e23ace

File tree

33 files changed

+134
-73
lines changed

33 files changed

+134
-73
lines changed

packages/kit/src/compatibility.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { readPackageJSON } from 'pkg-types'
33
import type { Nuxt, NuxtCompatibility, NuxtCompatibilityIssues } from '@nuxt/schema'
44
import { useNuxt } from './context'
55

6+
const SEMANTIC_VERSION_RE = /-\d+\.[0-9a-f]+/
67
export function normalizeSemanticVersion (version: string) {
7-
return version.replace(/-\d+\.[0-9a-f]+/, '') // Remove edge prefix
8+
return version.replace(SEMANTIC_VERSION_RE, '') // Remove edge prefix
89
}
910

1011
const builderMap = {
@@ -121,6 +122,7 @@ export function isNuxt3 (nuxt: Nuxt = useNuxt()) {
121122
return isNuxtMajorVersion(3, nuxt)
122123
}
123124

125+
const NUXT_VERSION_RE = /^v/g
124126
/**
125127
* Get nuxt version
126128
*/
@@ -129,5 +131,5 @@ export function getNuxtVersion (nuxt: Nuxt | any = useNuxt() /* TODO: LegacyNuxt
129131
if (typeof rawVersion !== 'string') {
130132
throw new TypeError('Cannot determine nuxt version! Is current instance passed?')
131133
}
132-
return rawVersion.replace(/^v/g, '')
134+
return rawVersion.replace(NUXT_VERSION_RE, '')
133135
}

packages/kit/src/components.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Component, ComponentsDir } from '@nuxt/schema'
33
import { useNuxt } from './context'
44
import { assertNuxtCompatibility } from './compatibility'
55
import { logger } from './logger'
6+
import { MODE_RE } from './utils'
67

78
/**
89
* Register a directory to be scanned for components and imported only when used.
@@ -32,7 +33,7 @@ export async function addComponent (opts: AddComponentOptions) {
3233
nuxt.options.components = nuxt.options.components || []
3334

3435
if (!opts.mode) {
35-
const [, mode = 'all'] = opts.filePath.match(/\.(server|client)(\.\w+)*$/) || []
36+
const [, mode = 'all'] = opts.filePath.match(MODE_RE) || []
3637
opts.mode = mode as 'all' | 'client' | 'server'
3738
}
3839

packages/kit/src/layout.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import { useNuxt } from './context'
66
import { logger } from './logger'
77
import { addTemplate } from './template'
88

9+
const LAYOUT_RE = /["']/g
910
export function addLayout (this: any, template: NuxtTemplate | string, name?: string) {
1011
const nuxt = useNuxt()
1112
const { filename, src } = addTemplate(template)
12-
const layoutName = kebabCase(name || parse(filename).name).replace(/["']/g, '')
13+
const layoutName = kebabCase(name || parse(filename).name).replace(LAYOUT_RE, '')
1314

1415
if (isNuxt2(nuxt)) {
1516
// Nuxt 2 adds layouts in options

packages/kit/src/nitro.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import { normalize } from 'pathe'
44
import { useNuxt } from './context'
55
import { toArray } from './utils'
66

7+
const HANDLER_METHOD_RE = /\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/
78
/**
89
* normalize handler object
910
*
1011
*/
1112
function normalizeHandlerMethod (handler: NitroEventHandler) {
1213
// retrieve method from handler file name
13-
const [, method = undefined] = handler.handler.match(/\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/) || []
14+
const [, method = undefined] = handler.handler.match(HANDLER_METHOD_RE) || []
1415
return {
1516
method,
1617
...handler,

packages/kit/src/plugin.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { NuxtPlugin, NuxtPluginTemplate } from '@nuxt/schema'
33
import { useNuxt } from './context'
44
import { addTemplate } from './template'
55
import { resolveAlias } from './resolve'
6+
import { MODE_RE } from './utils'
67

78
/**
89
* Normalize a nuxt plugin object
@@ -27,7 +28,7 @@ export function normalizePlugin (plugin: NuxtPlugin | string): NuxtPlugin {
2728
plugin.mode = 'server'
2829
}
2930
if (!plugin.mode) {
30-
const [, mode = 'all'] = plugin.src.match(/\.(server|client)(\.\w+)*$/) || []
31+
const [, mode = 'all'] = plugin.src.match(MODE_RE) || []
3132
plugin.mode = mode as 'all' | 'client' | 'server'
3233
}
3334

packages/kit/src/template.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ export async function updateTemplates (options?: { filter?: (template: ResolvedN
123123
return await tryUseNuxt()?.hooks.callHook('builder:generateApp', options)
124124
}
125125

126+
const EXTENSION_RE = /\b\.\w+$/g
127+
// Exclude bridge alias types to support Volar
128+
const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/]
126129
export async function _generateTypes (nuxt: Nuxt) {
127130
const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir)
128131
const relativeRootDir = relativeWithDot(nuxt.options.buildDir, nuxt.options.rootDir)
@@ -225,9 +228,6 @@ export async function _generateTypes (nuxt: Nuxt) {
225228

226229
const aliases: Record<string, string> = nuxt.options.alias
227230

228-
// Exclude bridge alias types to support Volar
229-
const excludedAlias = [/^@vue\/.*$/, /^#internal\/nuxt/]
230-
231231
const basePath = tsConfig.compilerOptions!.baseUrl
232232
? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl)
233233
: nuxt.options.buildDir
@@ -260,7 +260,7 @@ export async function _generateTypes (nuxt: Nuxt) {
260260
} else {
261261
const path = stats?.isFile()
262262
// remove extension
263-
? relativePath.replace(/\b\.\w+$/g, '')
263+
? relativePath.replace(EXTENSION_RE, '')
264264
// non-existent file probably shouldn't be resolved
265265
: aliases[alias]!
266266

@@ -289,7 +289,7 @@ export async function _generateTypes (nuxt: Nuxt) {
289289
tsConfig.compilerOptions!.paths[alias] = await Promise.all(paths.map(async (path: string) => {
290290
if (!isAbsolute(path)) { return path }
291291
const stats = await fsp.stat(path).catch(() => null /* file does not exist */)
292-
return relativeWithDot(nuxt.options.buildDir, stats?.isFile() ? path.replace(/\b\.\w+$/g, '') /* remove extension */ : path)
292+
return relativeWithDot(nuxt.options.buildDir, stats?.isFile() ? path.replace(EXTENSION_RE, '') /* remove extension */ : path)
293293
}))
294294
}
295295

@@ -349,6 +349,7 @@ function renderAttr (key: string, value?: string) {
349349
return value ? `${key}="${value}"` : ''
350350
}
351351

352+
const RELATIVE_WITH_DOT_RE = /^([^.])/
352353
function relativeWithDot (from: string, to: string) {
353-
return relative(from, to).replace(/^([^.])/, './$1') || '.'
354+
return relative(from, to).replace(RELATIVE_WITH_DOT_RE, './$1') || '.'
354355
}

packages/kit/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
export function toArray<T> (value: T | T[]): T[] {
33
return Array.isArray(value) ? value : [value]
44
}
5+
6+
export const MODE_RE = /\.(server|client)(\.\w+)*$/

packages/nuxt/src/app/components/nuxt-island.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const SSR_UID_RE = /data-island-uid="([^"]*)"/
2222
const DATA_ISLAND_UID_RE = /data-island-uid(="")?(?!="[^"])/g
2323
const SLOTNAME_RE = /data-island-slot="([^"]*)"/g
2424
const SLOT_FALLBACK_RE = / data-island-slot="([^"]*)"[^>]*>/g
25+
const ISLAND_SCOPE_ID_RE = /^<[^> ]*/
2526

2627
let id = 1
2728
const getId = import.meta.client ? () => (id++).toString() : randomUUID
@@ -142,7 +143,7 @@ export default defineComponent({
142143
let html = ssrHTML.value
143144

144145
if (props.scopeId) {
145-
html = html.replace(/^<[^> ]*/, full => full + ' ' + props.scopeId)
146+
html = html.replace(ISLAND_SCOPE_ID_RE, full => full + ' ' + props.scopeId)
146147
}
147148

148149
if (import.meta.client && !canLoadClientComponent.value) {

packages/nuxt/src/app/components/nuxt-link.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,12 @@ function useObserver (): { observe: ObserveFn } | undefined {
521521
return _observer
522522
}
523523

524+
const IS_2G_RE = /2g/
524525
function isSlowConnection () {
525526
if (import.meta.server) { return }
526527

527528
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
528529
const cn = (navigator as any).connection as { saveData: boolean, effectiveType: string } | null
529-
if (cn && (cn.saveData || /2g/.test(cn.effectiveType))) { return true }
530+
if (cn && (cn.saveData || IS_2G_RE.test(cn.effectiveType))) { return true }
530531
return false
531532
}

packages/nuxt/src/app/components/utils.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ export const _wrapIf = (component: Component, props: any, slots: any) => {
1515
return { default: () => props ? h(component, props, slots) : slots.default?.() }
1616
}
1717

18+
const ROUTE_KEY_PARENTHESES_RE = /(:\w+)\([^)]+\)/g
19+
const ROUTE_KEY_SYMBOLS_RE = /(:\w+)[?+*]/g
20+
const ROUTE_KEY_NORMAL_RE = /:\w+/g
1821
// TODO: consider refactoring into single utility
1922
// See https://github.com/nuxt/nuxt/tree/main/packages/nuxt/src/pages/runtime/utils.ts#L8-L19
2023
function generateRouteKey (route: RouteLocationNormalized) {
2124
const source = route?.meta.key ?? route.path
22-
.replace(/(:\w+)\([^)]+\)/g, '$1')
23-
.replace(/(:\w+)[?+*]/g, '$1')
24-
.replace(/:\w+/g, r => route.params[r.slice(1)]?.toString() || '')
25+
.replace(ROUTE_KEY_PARENTHESES_RE, '$1')
26+
.replace(ROUTE_KEY_SYMBOLS_RE, '$1')
27+
.replace(ROUTE_KEY_NORMAL_RE, r => route.params[r.slice(1)]?.toString() || '')
2528
return typeof source === 'function' ? source(route) : source
2629
}
2730

0 commit comments

Comments
 (0)