Skip to content

Commit

Permalink
perf: avoid parseRequest (#15617)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy authored Jan 16, 2024
1 parent bdb826c commit 0cacfad
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 78 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`parse positives > ? in url 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mo\\\\?ds/*.js", {"query":"url","import":"*"})), \`./mo?ds/\${base ?? foo}.js\`)"`;
exports[`parse positives > ? in url 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mo\\\\?ds/*.js", {"query":"?url","import":"*"})), \`./mo?ds/\${base ?? foo}.js\`)"`;
exports[`parse positives > ? in variables 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"raw","import":"*"})), \`./mods/\${base ?? foo}.js\`)"`;
exports[`parse positives > ? in variables 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"?raw","import":"*"})), \`./mods/\${base ?? foo}.js\`)"`;
exports[`parse positives > ? in worker 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mo\\\\?ds/*.js", {"query":"worker","import":"*"})), \`./mo?ds/\${base ?? foo}.js\`)"`;
exports[`parse positives > ? in worker 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mo\\\\?ds/*.js", {"query":"?worker","import":"*"})), \`./mo?ds/\${base ?? foo}.js\`)"`;
exports[`parse positives > alias path 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js")), \`./mods/\${base}.js\`)"`;
Expand All @@ -14,8 +14,8 @@ exports[`parse positives > with ../ and itself 1`] = `"__variableDynamicImportRu
exports[`parse positives > with multi ../ and itself 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("../../plugins/dynamicImportVar/*.js")), \`./\${name}.js\`)"`;
exports[`parse positives > with query 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":{"foo":"bar"}})), \`./mods/\${base}.js\`)"`;
exports[`parse positives > with query 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"?foo=bar"})), \`./mods/\${base}.js\`)"`;
exports[`parse positives > with query raw 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"raw","import":"*"})), \`./mods/\${base}.js\`)"`;
exports[`parse positives > with query raw 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"?raw","import":"*"})), \`./mods/\${base}.js\`)"`;
exports[`parse positives > with query url 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"url","import":"*"})), \`./mods/\${base}.js\`)"`;
exports[`parse positives > with query url 1`] = `"__variableDynamicImportRuntimeHelper((import.meta.glob("./mods/*.js", {"query":"?url","import":"*"})), \`./mods/\${base}.js\`)"`;
9 changes: 6 additions & 3 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import {
isObject,
joinUrlSegments,
normalizePath,
parseRequest,
processSrcSet,
removeDirectQuery,
removeUrlQuery,
Expand Down Expand Up @@ -171,6 +170,7 @@ export function resolveCSSOptions(
const cssModuleRE = new RegExp(`\\.module${CSS_LANGS_RE.source}`)
const directRequestRE = /[?&]direct\b/
const htmlProxyRE = /[?&]html-proxy\b/
const htmlProxyIndexRE = /&index=(\d+)/
const commonjsProxyRE = /\?commonjs-proxy/
const inlineRE = /[?&]inline\b/
const inlineCSSRE = /[?&]inline-css\b/
Expand Down Expand Up @@ -474,12 +474,15 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
const inlineCSS = inlineCSSRE.test(id)
const isHTMLProxy = htmlProxyRE.test(id)
if (inlineCSS && isHTMLProxy) {
const query = parseRequest(id)
if (styleAttrRE.test(id)) {
css = css.replace(/"/g, '"')
}
const index = htmlProxyIndexRE.exec(id)?.[1]
if (index == null) {
throw new Error(`HTML proxy index in "${id}" not found`)
}
addToHTMLProxyTransformResult(
`${getHash(cleanUrl(id))}_${Number.parseInt(query!.index)}`,
`${getHash(cleanUrl(id))}_${Number.parseInt(index)}`,
css,
)
return `export default ''`
Expand Down
37 changes: 20 additions & 17 deletions packages/vite/src/node/plugins/dynamicImportVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import { CLIENT_ENTRY } from '../constants'
import {
createFilter,
normalizePath,
parseRequest,
rawRE,
requestQueryMaybeEscapedSplitRE,
requestQuerySplitRE,
transformStableResult,
urlRE,
} from '../utils'
import { toAbsoluteGlob } from './importMetaGlob'
import { hasViteIgnoreRE } from './importAnalysis'
import { workerOrSharedWorkerRE } from './worker'

export const dynamicImportHelperId = '\0vite/dynamic-import-helper.js'

Expand Down Expand Up @@ -53,9 +55,6 @@ function parseDynamicImportPattern(
strings: string,
): DynamicImportPattern | null {
const filename = strings.slice(1, -1)
const rawQuery = parseRequest(filename)
let globParams: DynamicImportRequest | null = null

const ast = (
parseJS(strings, {
ecmaVersion: 'latest',
Expand All @@ -73,19 +72,23 @@ function parseDynamicImportPattern(
requestQueryMaybeEscapedSplitRE,
2,
)
const [rawPattern] = filename.split(requestQuerySplitRE, 2)

const globQuery = (['worker', 'url', 'raw'] as const).find(
(key) => rawQuery && key in rawQuery,
)
if (globQuery) {
globParams = {
query: globQuery,
import: '*',
}
} else if (rawQuery) {
globParams = {
query: rawQuery,
let [rawPattern, search] = filename.split(requestQuerySplitRE, 2)
let globParams: DynamicImportRequest | null = null
if (search) {
search = '?' + search
if (
workerOrSharedWorkerRE.test(search) ||
urlRE.test(search) ||
rawRE.test(search)
) {
globParams = {
query: search,
import: '*',
}
} else {
globParams = {
query: search,
}
}
}

Expand Down
59 changes: 22 additions & 37 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { ResolvedConfig } from '../config'
import type { Plugin } from '../plugin'
import type { ViteDevServer } from '../server'
import { ENV_ENTRY, ENV_PUBLIC_PATH } from '../constants'
import { cleanUrl, getHash, injectQuery, parseRequest } from '../utils'
import { cleanUrl, getHash, injectQuery, urlRE } from '../utils'
import {
createToImportMetaURLBasedRelativeRuntime,
onRollupWarning,
Expand All @@ -28,6 +28,10 @@ interface WorkerCache {

export type WorkerType = 'classic' | 'module' | 'ignore'

export const workerOrSharedWorkerRE = /(?:\?|&)(worker|sharedworker)(?:&|$)/
const workerFileRE = /(?:\?|&)worker_file&type=(\w+)(?:&|$)/
const inlineRE = /[?&]inline\b/

export const WORKER_FILE_ID = 'worker_file'
const workerCache = new WeakMap<ResolvedConfig, WorkerCache>()

Expand All @@ -43,7 +47,6 @@ function saveEmitWorkerAsset(
async function bundleWorkerEntry(
config: ResolvedConfig,
id: string,
query: Record<string, string> | null,
): Promise<OutputChunk> {
// bundle the file as entry to support imports
const { rollup } = await import('rollup')
Expand Down Expand Up @@ -99,12 +102,11 @@ async function bundleWorkerEntry(
} finally {
await bundle.close()
}
return emitSourcemapForWorkerEntry(config, query, chunk)
return emitSourcemapForWorkerEntry(config, chunk)
}

function emitSourcemapForWorkerEntry(
config: ResolvedConfig,
query: Record<string, string> | null,
chunk: OutputChunk,
): OutputChunk {
const { map: sourcemap } = chunk
Expand Down Expand Up @@ -144,12 +146,11 @@ function encodeWorkerAssetFileName(
export async function workerFileToUrl(
config: ResolvedConfig,
id: string,
query: Record<string, string> | null,
): Promise<string> {
const workerMap = workerCache.get(config.mainConfig || config)!
let fileName = workerMap.bundle.get(id)
if (!fileName) {
const outputChunk = await bundleWorkerEntry(config, id, query)
const outputChunk = await bundleWorkerEntry(config, id)
fileName = outputChunk.fileName
saveEmitWorkerAsset(config, {
fileName,
Expand Down Expand Up @@ -191,18 +192,6 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
let server: ViteDevServer
const isWorker = config.isWorker

const isWorkerQueryId = (id: string) => {
const parsedQuery = parseRequest(id)
if (
parsedQuery &&
(parsedQuery.worker ?? parsedQuery.sharedworker) != null
) {
return true
}

return false
}

return {
name: 'vite:worker',

Expand All @@ -222,23 +211,23 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
},

load(id) {
if (isBuild && isWorkerQueryId(id)) {
if (isBuild && workerOrSharedWorkerRE.test(id)) {
return ''
}
},

shouldTransformCachedModule({ id }) {
if (isBuild && config.build.watch && isWorkerQueryId(id)) {
if (isBuild && config.build.watch && workerOrSharedWorkerRE.test(id)) {
return true
}
},

async transform(raw, id, options) {
const query = parseRequest(id)
if (query && query[WORKER_FILE_ID] != null) {
async transform(raw, id) {
const workerFileMatch = workerFileRE.exec(id)
if (workerFileMatch) {
// if import worker by worker constructor will have query.type
// other type will be import worker by esm
const workerType = query['type']! as WorkerType
const workerType = workerFileMatch[1] as WorkerType
let injectEnv = ''

const scriptPath = JSON.stringify(
Expand Down Expand Up @@ -270,18 +259,15 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}
return
}
if (
query == null ||
(query && (query.worker ?? query.sharedworker) == null)
) {
return
}

const workerMatch = workerOrSharedWorkerRE.exec(id)
if (!workerMatch) return

// stringified url or `new URL(...)`
let url: string
const { format } = config.worker
const workerConstructor =
query.sharedworker != null ? 'SharedWorker' : 'Worker'
workerMatch[1] === 'sharedworker' ? 'SharedWorker' : 'Worker'
const workerType = isBuild
? format === 'es'
? 'module'
Expand All @@ -293,8 +279,8 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}`

if (isBuild) {
if (query.inline != null) {
const chunk = await bundleWorkerEntry(config, id, query)
if (inlineRE.test(id)) {
const chunk = await bundleWorkerEntry(config, id)
const encodedJs = `const encodedJs = "${Buffer.from(
chunk.code,
).toString('base64')}";`
Expand Down Expand Up @@ -349,15 +335,14 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
map: { mappings: '' },
}
} else {
url = await workerFileToUrl(config, id, query)
url = await workerFileToUrl(config, id)
}
} else {
url = await fileToUrl(cleanUrl(id), config, this)
url = injectQuery(url, WORKER_FILE_ID)
url = injectQuery(url, `type=${workerType}`)
url = injectQuery(url, `${WORKER_FILE_ID}&type=${workerType}`)
}

if (query.url != null) {
if (urlRE.test(id)) {
return {
code: `export default ${JSON.stringify(url)}`,
map: { mappings: '' }, // Empty sourcemap to suppress Rollup warning
Expand Down
10 changes: 5 additions & 5 deletions packages/vite/src/node/plugins/workerImportMetaUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
cleanUrl,
evalValue,
injectQuery,
parseRequest,
slash,
transformStableResult,
} from '../utils'
Expand Down Expand Up @@ -131,7 +130,6 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {

async transform(code, id, options) {
if (!options?.ssr && isIncludeWorkerImportMetaUrl(code)) {
const query = parseRequest(id)
let s: MagicString | undefined
const cleanString = stripLiteral(code)
const workerImportMetaUrlRE =
Expand Down Expand Up @@ -174,11 +172,13 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {

let builtUrl: string
if (isBuild) {
builtUrl = await workerFileToUrl(config, file, query)
builtUrl = await workerFileToUrl(config, file)
} else {
builtUrl = await fileToUrl(cleanUrl(file), config, this)
builtUrl = injectQuery(builtUrl, WORKER_FILE_ID)
builtUrl = injectQuery(builtUrl, `type=${workerType}`)
builtUrl = injectQuery(
builtUrl,
`${WORKER_FILE_ID}&type=${workerType}`,
)
}
s.update(
expStart,
Expand Down
10 changes: 1 addition & 9 deletions packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import os from 'node:os'
import path from 'node:path'
import { exec } from 'node:child_process'
import { createHash } from 'node:crypto'
import { URL, URLSearchParams, fileURLToPath } from 'node:url'
import { URL, fileURLToPath } from 'node:url'
import { builtinModules, createRequire } from 'node:module'
import { promises as dns } from 'node:dns'
import { performance } from 'node:perf_hooks'
Expand Down Expand Up @@ -1041,14 +1041,6 @@ export const singlelineCommentsRE = /\/\/.*/g
export const requestQuerySplitRE = /\?(?!.*[/|}])/
export const requestQueryMaybeEscapedSplitRE = /\\?\?(?!.*[/|}])/

export function parseRequest(id: string): Record<string, string> | null {
const [_, search] = id.split(requestQuerySplitRE, 2)
if (!search) {
return null
}
return Object.fromEntries(new URLSearchParams(search))
}

export const blankReplacer = (match: string): string => ' '.repeat(match.length)

export function getHash(text: Buffer | string, length = 8): string {
Expand Down
2 changes: 1 addition & 1 deletion playground/worker/__tests__/iife/iife-worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ test('import.meta.glob eager in worker', async () => {
})

test.runIf(isServe)('sourcemap boundary', async () => {
const response = page.waitForResponse(/my-worker.ts\?type=module&worker_file/)
const response = page.waitForResponse(/my-worker.ts\?worker_file&type=module/)
await page.goto(viteTestUrl)
const content = await (await response).text()
const { mappings } = decodeSourceMapUrl(content)
Expand Down

0 comments on commit 0cacfad

Please sign in to comment.