From 4c2d3ebbea59f6d3800bdddfa3f58a95657e0fe9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 28 Apr 2025 18:55:13 +0200 Subject: [PATCH 1/4] perf: use hook filter --- src/index.ts | 131 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 48 deletions(-) diff --git a/src/index.ts b/src/index.ts index d51df9472..50d243519 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { routeBlockQueryRE, ROUTE_BLOCK_ID, ROUTES_LAST_LOAD_TIME, + VIRTUAL_PREFIX, } from './core/moduleConstants' import { Options, @@ -50,15 +51,18 @@ export default createUnplugin((opt = {}, _meta) => { mergeAllExtensions(options) ) + const IDS_TO_INCLUDE = options.routesFolder.flatMap((routeOption) => + pageFilePattern.map((pattern) => join(routeOption.src, pattern)) + ) + const DEFINE_PAGE_QUERY_RE = /\?.*\bdefinePage\&vue\b/ + // this is a larger filter that includes a bit too many files // the RouteFolderWatcher will filter it down to the actual files const filterPageComponents = createFilter( [ - ...options.routesFolder.flatMap((routeOption) => - pageFilePattern.map((pattern) => join(routeOption.src, pattern)) - ), + ...IDS_TO_INCLUDE, // importing the definePage block - /\?.*\bdefinePage\&vue\b/, + DEFINE_PAGE_QUERY_RE, ], options.exclude ) @@ -68,25 +72,36 @@ export default createUnplugin((opt = {}, _meta) => { name: 'unplugin-vue-router', enforce: 'pre', - resolveId(id) { - if ( - // vue-router/auto-routes - id === MODULE_ROUTES_PATH || - // NOTE: it wasn't possible to override or add new exports to vue-router - // so we need to override it with a different package name - id === MODULE_VUE_ROUTER_AUTO - ) { - // virtual module - return asVirtualId(id) - } - - // this allows us to skip the route block module as a whole since we already parse it - if (routeBlockQueryRE.test(id)) { - return ROUTE_BLOCK_ID - } - - // nothing to do, just for TS - return + resolveId: { + filter: { + id: { + include: [ + MODULE_ROUTES_PATH, + MODULE_VUE_ROUTER_AUTO, + routeBlockQueryRE, + ], + }, + }, + handler(id) { + if ( + // vue-router/auto-routes + id === MODULE_ROUTES_PATH || + // NOTE: it wasn't possible to override or add new exports to vue-router + // so we need to override it with a different package name + id === MODULE_VUE_ROUTER_AUTO + ) { + // virtual module + return asVirtualId(id) + } + + // this allows us to skip the route block module as a whole since we already parse it + if (routeBlockQueryRE.test(id)) { + return ROUTE_BLOCK_ID + } + + // nothing to do, just for TS + return + }, }, buildStart() { @@ -103,10 +118,17 @@ export default createUnplugin((opt = {}, _meta) => { return filterPageComponents(id) }, - transform(code, id) { - // console.log('👋 Transforming', id) - // remove the `definePage()` from the file or isolate it - return ctx.definePageTransform(code, id) + transform: { + filter: { + id: { + include: [...IDS_TO_INCLUDE, DEFINE_PAGE_QUERY_RE], + }, + }, + handler(code, id) { + // console.log('👋 Transforming', id) + // remove the `definePage()` from the file or isolate it + return ctx.definePageTransform(code, id) + }, }, // loadInclude is necessary for webpack @@ -119,32 +141,45 @@ export default createUnplugin((opt = {}, _meta) => { ) }, - load(id) { - // remove the block as it's parsed by the plugin - // stub it with an empty module - if (id === ROUTE_BLOCK_ID) { - return { - code: `export default {}`, - map: null, + load: { + filter: { + id: { + include: [ + ROUTE_BLOCK_ID, + MODULE_ROUTES_PATH, + MODULE_VUE_ROUTER_AUTO, + VIRTUAL_PREFIX + MODULE_ROUTES_PATH, + VIRTUAL_PREFIX + MODULE_VUE_ROUTER_AUTO, + ], + }, + }, + handler(id) { + // remove the block as it's parsed by the plugin + // stub it with an empty module + if (id === ROUTE_BLOCK_ID) { + return { + code: `export default {}`, + map: null, + } } - } - // we need to use a virtual module so that vite resolves the vue-router/auto-routes - // dependency correctly - const resolvedId = getVirtualId(id) + // we need to use a virtual module so that vite resolves the vue-router/auto-routes + // dependency correctly + const resolvedId = getVirtualId(id) - // vue-router/auto-routes - if (resolvedId === MODULE_ROUTES_PATH) { - ROUTES_LAST_LOAD_TIME.update() - return ctx.generateRoutes() - } + // vue-router/auto-routes + if (resolvedId === MODULE_ROUTES_PATH) { + ROUTES_LAST_LOAD_TIME.update() + return ctx.generateRoutes() + } - // vue-router/auto - if (resolvedId === MODULE_VUE_ROUTER_AUTO) { - return ctx.generateVueRouterProxy() - } + // vue-router/auto + if (resolvedId === MODULE_VUE_ROUTER_AUTO) { + return ctx.generateVueRouterProxy() + } - return // ok TS... + return // ok TS... + }, }, // improves DX From 62d994531b84fbd87d09e88a42946e48f441aacc Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 1 May 2025 09:56:01 +0200 Subject: [PATCH 2/4] fix: use regex in resolveId --- src/core/moduleConstants.ts | 3 +++ src/index.ts | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/moduleConstants.ts b/src/core/moduleConstants.ts index 7c20875ae..48b6e81b4 100644 --- a/src/core/moduleConstants.ts +++ b/src/core/moduleConstants.ts @@ -1,6 +1,9 @@ export const MODULE_VUE_ROUTER_AUTO = 'vue-router/auto' +export const MODULE_VUE_ROUTER_AUTO_RE = /vue-router\/auto/ // vue-router/auto/routes was more natural but didn't work well with TS export const MODULE_ROUTES_PATH = `${MODULE_VUE_ROUTER_AUTO}-routes` +export const MODULE_ROUTES_PATH_RE = new RegExp(MODULE_ROUTES_PATH + '-routes') + // NOTE: not sure if needed. Used for HMR the virtual routes let time = Date.now() diff --git a/src/index.ts b/src/index.ts index 50d243519..ecdc78e0b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,8 @@ import { ROUTE_BLOCK_ID, ROUTES_LAST_LOAD_TIME, VIRTUAL_PREFIX, + MODULE_VUE_ROUTER_AUTO_RE, + MODULE_ROUTES_PATH_RE, } from './core/moduleConstants' import { Options, @@ -76,8 +78,8 @@ export default createUnplugin((opt = {}, _meta) => { filter: { id: { include: [ - MODULE_ROUTES_PATH, - MODULE_VUE_ROUTER_AUTO, + MODULE_ROUTES_PATH_RE, + MODULE_VUE_ROUTER_AUTO_RE, routeBlockQueryRE, ], }, @@ -148,8 +150,8 @@ export default createUnplugin((opt = {}, _meta) => { ROUTE_BLOCK_ID, MODULE_ROUTES_PATH, MODULE_VUE_ROUTER_AUTO, - VIRTUAL_PREFIX + MODULE_ROUTES_PATH, - VIRTUAL_PREFIX + MODULE_VUE_ROUTER_AUTO, + `${VIRTUAL_PREFIX}${MODULE_ROUTES_PATH}`, + `${VIRTUAL_PREFIX}${MODULE_VUE_ROUTER_AUTO}`, ], }, }, From 39d1a81c899cc73c2b4c4ca573e3a63f21bbd1bc Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 1 May 2025 09:56:14 +0200 Subject: [PATCH 3/4] chore: lint --- src/core/moduleConstants.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/moduleConstants.ts b/src/core/moduleConstants.ts index 48b6e81b4..488ad059a 100644 --- a/src/core/moduleConstants.ts +++ b/src/core/moduleConstants.ts @@ -4,7 +4,6 @@ export const MODULE_VUE_ROUTER_AUTO_RE = /vue-router\/auto/ export const MODULE_ROUTES_PATH = `${MODULE_VUE_ROUTER_AUTO}-routes` export const MODULE_ROUTES_PATH_RE = new RegExp(MODULE_ROUTES_PATH + '-routes') - // NOTE: not sure if needed. Used for HMR the virtual routes let time = Date.now() /** From d6c8214f5c5ea82b93f45888c6b81122d5eb5fee Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 1 May 2025 13:27:29 +0200 Subject: [PATCH 4/4] refactor: use exactRegex --- src/core/moduleConstants.ts | 12 ++++++++++-- src/index.ts | 17 ++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/core/moduleConstants.ts b/src/core/moduleConstants.ts index 488ad059a..babdae8ce 100644 --- a/src/core/moduleConstants.ts +++ b/src/core/moduleConstants.ts @@ -1,8 +1,6 @@ export const MODULE_VUE_ROUTER_AUTO = 'vue-router/auto' -export const MODULE_VUE_ROUTER_AUTO_RE = /vue-router\/auto/ // vue-router/auto/routes was more natural but didn't work well with TS export const MODULE_ROUTES_PATH = `${MODULE_VUE_ROUTER_AUTO}-routes` -export const MODULE_ROUTES_PATH_RE = new RegExp(MODULE_ROUTES_PATH + '-routes') // NOTE: not sure if needed. Used for HMR the virtual routes let time = Date.now() @@ -37,3 +35,13 @@ export const routeBlockQueryRE = /\?vue&type=route/ export function asVirtualId(id: string) { return VIRTUAL_PREFIX + id } + +// from https://github.com/vitejs/vite-plugin-vue/pull/582/files#diff-6e789a0a69ac40966dc0c6cf31b4603231ed60412915af87f0b0b8611765efa1R1 +export function exactRegex(input: string): RegExp { + return new RegExp(`^${escapeRegex(input)}$`) +} + +const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g +function escapeRegex(str: string): string { + return str.replace(escapeRegexRE, '\\$&') +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index ecdc78e0b..9a00c4d72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,8 +9,7 @@ import { ROUTE_BLOCK_ID, ROUTES_LAST_LOAD_TIME, VIRTUAL_PREFIX, - MODULE_VUE_ROUTER_AUTO_RE, - MODULE_ROUTES_PATH_RE, + exactRegex, } from './core/moduleConstants' import { Options, @@ -78,8 +77,8 @@ export default createUnplugin((opt = {}, _meta) => { filter: { id: { include: [ - MODULE_ROUTES_PATH_RE, - MODULE_VUE_ROUTER_AUTO_RE, + exactRegex(MODULE_ROUTES_PATH), + exactRegex(MODULE_VUE_ROUTER_AUTO), routeBlockQueryRE, ], }, @@ -147,11 +146,11 @@ export default createUnplugin((opt = {}, _meta) => { filter: { id: { include: [ - ROUTE_BLOCK_ID, - MODULE_ROUTES_PATH, - MODULE_VUE_ROUTER_AUTO, - `${VIRTUAL_PREFIX}${MODULE_ROUTES_PATH}`, - `${VIRTUAL_PREFIX}${MODULE_VUE_ROUTER_AUTO}`, + exactRegex(ROUTE_BLOCK_ID), + exactRegex(MODULE_ROUTES_PATH), + exactRegex(MODULE_VUE_ROUTER_AUTO), + exactRegex(`${VIRTUAL_PREFIX}${MODULE_ROUTES_PATH}`), + exactRegex(`${VIRTUAL_PREFIX}${MODULE_VUE_ROUTER_AUTO}`), ], }, },