Skip to content

Commit 6399fd4

Browse files
committed
feat(vue): add filter
1 parent 2600cc3 commit 6399fd4

File tree

3 files changed

+148
-100
lines changed

3 files changed

+148
-100
lines changed

packages/plugin-vue/src/index.ts

Lines changed: 104 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { handleHotUpdate, handleTypeDepChange } from './handleHotUpdate'
2424
import { transformTemplateAsModule } from './template'
2525
import { transformStyle } from './style'
2626
import { EXPORT_HELPER_ID, helperCode } from './helper'
27+
import { exactRegex } from './utils/filter'
2728

2829
export { parseVueRequest } from './utils/query'
2930
export type { VueQuery } from './utils/query'
@@ -338,110 +339,129 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin<Api> {
338339
}
339340
},
340341

341-
async resolveId(id) {
342-
// component export helper
343-
if (id === EXPORT_HELPER_ID) {
344-
return id
345-
}
346-
// serve sub-part requests (*?vue) as virtual modules
347-
if (parseVueRequest(id).query.vue) {
348-
return id
349-
}
342+
resolveId: {
343+
filter: {
344+
id: [exactRegex(EXPORT_HELPER_ID), /[?&]vue\b/],
345+
},
346+
handler(id) {
347+
// component export helper
348+
if (id === EXPORT_HELPER_ID) {
349+
return id
350+
}
351+
// serve sub-part requests (*?vue) as virtual modules
352+
if (parseVueRequest(id).query.vue) {
353+
return id
354+
}
355+
},
350356
},
351357

352-
load(id, opt) {
353-
if (id === EXPORT_HELPER_ID) {
354-
return helperCode
355-
}
358+
load: {
359+
filter: {
360+
id: [exactRegex(EXPORT_HELPER_ID), /[?&]vue\b/],
361+
},
362+
handler(id, opt) {
363+
if (id === EXPORT_HELPER_ID) {
364+
return helperCode
365+
}
356366

357-
const ssr = opt?.ssr === true
367+
const ssr = opt?.ssr === true
358368

359-
const { filename, query } = parseVueRequest(id)
369+
const { filename, query } = parseVueRequest(id)
360370

361-
// select corresponding block for sub-part virtual modules
362-
if (query.vue) {
363-
if (query.src) {
364-
return fs.readFileSync(filename, 'utf-8')
365-
}
366-
const descriptor = getDescriptor(filename, options.value)!
367-
let block: SFCBlock | null | undefined
368-
if (query.type === 'script') {
369-
// handle <script> + <script setup> merge via compileScript()
370-
block = resolveScript(
371-
descriptor,
372-
options.value,
373-
ssr,
374-
customElementFilter.value(filename),
375-
)
376-
} else if (query.type === 'template') {
377-
block = descriptor.template!
378-
} else if (query.type === 'style') {
379-
block = descriptor.styles[query.index!]
380-
} else if (query.index != null) {
381-
block = descriptor.customBlocks[query.index]
382-
}
383-
if (block) {
384-
return {
385-
code: block.content,
386-
map: block.map as any,
371+
// select corresponding block for sub-part virtual modules
372+
if (query.vue) {
373+
if (query.src) {
374+
return fs.readFileSync(filename, 'utf-8')
375+
}
376+
const descriptor = getDescriptor(filename, options.value)!
377+
let block: SFCBlock | null | undefined
378+
if (query.type === 'script') {
379+
// handle <script> + <script setup> merge via compileScript()
380+
block = resolveScript(
381+
descriptor,
382+
options.value,
383+
ssr,
384+
customElementFilter.value(filename),
385+
)
386+
} else if (query.type === 'template') {
387+
block = descriptor.template!
388+
} else if (query.type === 'style') {
389+
block = descriptor.styles[query.index!]
390+
} else if (query.index != null) {
391+
block = descriptor.customBlocks[query.index]
392+
}
393+
if (block) {
394+
return {
395+
code: block.content,
396+
map: block.map as any,
397+
}
387398
}
388399
}
389-
}
400+
},
390401
},
391402

392-
transform(code, id, opt) {
393-
const ssr = opt?.ssr === true
394-
const { filename, query } = parseVueRequest(id)
395-
396-
if (query.raw || query.url) {
397-
return
398-
}
403+
transform: {
404+
filter: {
405+
// FIXME: should include other files if filter is updated
406+
id: {
407+
include: /[?&]vue\b|\.vue$/,
408+
exclude: /[?&](?:raw|url)\b/,
409+
},
410+
},
411+
handler(code, id, opt) {
412+
const ssr = opt?.ssr === true
413+
const { filename, query } = parseVueRequest(id)
399414

400-
if (!filter.value(filename) && !query.vue) {
401-
return
402-
}
415+
if (query.raw || query.url) {
416+
return
417+
}
403418

404-
if (!query.vue) {
405-
// main request
406-
return transformMain(
407-
code,
408-
filename,
409-
options.value,
410-
this,
411-
ssr,
412-
customElementFilter.value(filename),
413-
)
414-
} else {
415-
// sub block request
416-
const descriptor: ExtendedSFCDescriptor = query.src
417-
? getSrcDescriptor(filename, query) ||
418-
getTempSrcDescriptor(filename, query)
419-
: getDescriptor(filename, options.value)!
420-
421-
if (query.src) {
422-
this.addWatchFile(filename)
419+
if (!filter.value(filename) && !query.vue) {
420+
return
423421
}
424422

425-
if (query.type === 'template') {
426-
return transformTemplateAsModule(
423+
if (!query.vue) {
424+
// main request
425+
return transformMain(
427426
code,
428-
descriptor,
427+
filename,
429428
options.value,
430429
this,
431430
ssr,
432431
customElementFilter.value(filename),
433432
)
434-
} else if (query.type === 'style') {
435-
return transformStyle(
436-
code,
437-
descriptor,
438-
Number(query.index || 0),
439-
options.value,
440-
this,
441-
filename,
442-
)
433+
} else {
434+
// sub block request
435+
const descriptor: ExtendedSFCDescriptor = query.src
436+
? getSrcDescriptor(filename, query) ||
437+
getTempSrcDescriptor(filename, query)
438+
: getDescriptor(filename, options.value)!
439+
440+
if (query.src) {
441+
this.addWatchFile(filename)
442+
}
443+
444+
if (query.type === 'template') {
445+
return transformTemplateAsModule(
446+
code,
447+
descriptor,
448+
options.value,
449+
this,
450+
ssr,
451+
customElementFilter.value(filename),
452+
)
453+
} else if (query.type === 'style') {
454+
return transformStyle(
455+
code,
456+
descriptor,
457+
Number(query.index || 0),
458+
options.value,
459+
this,
460+
filename,
461+
)
462+
}
443463
}
444-
}
464+
},
445465
},
446466
}
447467
}

packages/plugin-vue/src/main.ts

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TraceMap, eachMapping } from '@jridgewell/trace-mapping'
88
import type { EncodedSourceMap as GenEncodedSourceMap } from '@jridgewell/gen-mapping'
99
import { addMapping, fromMap, toEncodedMap } from '@jridgewell/gen-mapping'
1010
import { normalizePath, transformWithEsbuild } from 'vite'
11+
import * as vite from 'vite'
1112
import {
1213
createDescriptor,
1314
getDescriptor,
@@ -256,22 +257,41 @@ export async function transformMain(
256257
/tsx?$/.test(lang) &&
257258
!descriptor.script?.src // only normal script can have src
258259
) {
259-
const { code, map } = await transformWithEsbuild(
260-
resolvedCode,
261-
filename,
262-
{
263-
target: 'esnext',
264-
charset: 'utf8',
265-
// #430 support decorators in .vue file
266-
// target can be overridden by esbuild config target
267-
...options.devServer?.config.esbuild,
268-
loader: 'ts',
269-
sourcemap: options.sourceMap,
270-
},
271-
resolvedMap,
272-
)
273-
resolvedCode = code
274-
resolvedMap = resolvedMap ? (map as any) : resolvedMap
260+
if ('transformWithOxc' in vite) {
261+
// @ts-ignore rolldown-vite
262+
const { code, map } = await vite.transformWithOxc(
263+
resolvedCode,
264+
filename,
265+
{
266+
// #430 support decorators in .vue file
267+
// target can be overridden by esbuild config target
268+
// @ts-ignore
269+
...options.devServer?.config.oxc,
270+
lang: 'ts',
271+
sourcemap: options.sourceMap,
272+
},
273+
resolvedMap,
274+
)
275+
resolvedCode = code
276+
resolvedMap = resolvedMap ? (map as any) : resolvedMap
277+
} else {
278+
const { code, map } = await transformWithEsbuild(
279+
resolvedCode,
280+
filename,
281+
{
282+
target: 'esnext',
283+
charset: 'utf8',
284+
// #430 support decorators in .vue file
285+
// target can be overridden by esbuild config target
286+
...options.devServer?.config.esbuild,
287+
loader: 'ts',
288+
sourcemap: options.sourceMap,
289+
},
290+
resolvedMap,
291+
)
292+
resolvedCode = code
293+
resolvedMap = resolvedMap ? (map as any) : resolvedMap
294+
}
275295
}
276296

277297
return {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function exactRegex(input: string): RegExp {
2+
return new RegExp(`^${escapeRegex(input)}$`)
3+
}
4+
5+
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g
6+
function escapeRegex(str: string): string {
7+
return str.replace(escapeRegexRE, '\\$&')
8+
}

0 commit comments

Comments
 (0)