Skip to content

Commit c98ddbf

Browse files
committed
refactor: wip hmr
1 parent 63788f6 commit c98ddbf

File tree

8 files changed

+83
-20
lines changed

8 files changed

+83
-20
lines changed

playground/src/App.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
RouteLocation,
88
} from 'vue-router/auto'
99
import { ref } from 'vue'
10+
import { routes } from 'vue-router/auto-routes'
1011
1112
function test(
1213
a: RouteLocationResolved<'/[name]'>,
@@ -19,6 +20,8 @@ if (route.name === '/deep/nesting/works/[[files]]+') {
1920
route.params.files
2021
}
2122
23+
console.log(`We have ${routes.length} routes.`)
24+
2225
const router = useRouter()
2326
2427
router.resolve('/:name')

playground/src/main.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import { createApp } from 'vue'
22
import App from './App.vue'
3-
import {
4-
createRouter,
5-
createWebHistory,
6-
DataLoaderPlugin,
7-
} from 'vue-router/auto'
8-
import { routes } from 'vue-router/auto-routes'
3+
import { DataLoaderPlugin } from 'vue-router/auto'
94
import { MutationCache, QueryCache, VueQueryPlugin } from '@tanstack/vue-query'
105
import { createPinia } from 'pinia'
116
import { QueryPlugin } from '@pinia/colada'
12-
13-
const router = createRouter({
14-
history: createWebHistory(),
15-
routes,
16-
})
7+
import { router } from './router'
178

189
const app = createApp(App)
1910

playground/src/router.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { createRouter, createWebHistory } from 'vue-router/auto'
2+
import { routes } from 'vue-router/auto-routes'
3+
4+
export const router = createRouter({
5+
history: createWebHistory(),
6+
routes,
7+
})
8+
9+
if (import.meta.hot) {
10+
// How to trigger this? tried virtual: /@id/
11+
import.meta.hot.accept('vue-router/auto-routes', (mod) => {
12+
console.log('✨ got new routes', mod)
13+
})
14+
import.meta.hot.accept((mod) => {
15+
console.log('🔁 reloading routes from router...', mod)
16+
console.log(mod!.router.getRoutes())
17+
})
18+
}

src/core/context.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ export function createRoutesContext(options: ResolvedOptions) {
178178
options,
179179
importsMap
180180
)}`
181+
// TODO: should we put some HMR code for routes here or should it be at the router creation level (that would be easier to replace the routes)
181182

182183
// generate the list of imports
183184
let imports = `${importsMap}`
@@ -225,9 +226,10 @@ export function createRoutesContext(options: ResolvedOptions) {
225226
lastDTS = content
226227

227228
// update the files
228-
server?.invalidate(MODULE_ROUTES_PATH)
229-
server?.invalidate(MODULE_VUE_ROUTER)
230-
server?.reload()
229+
server && logger.log(`⚙️ Invalidating server "${MODULE_ROUTES_PATH}"`)
230+
// server?.invalidate(MODULE_ROUTES_PATH)
231+
server?.updateRoutes()
232+
// server?.reload()
231233
}
232234
}
233235
logger.timeEnd('writeConfigFiles')

src/core/moduleConstants.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@ export const MODULE_VUE_ROUTER = 'vue-router/auto'
22
// vue-router/auto/routes was more natural but didn't work well with TS
33
export const MODULE_ROUTES_PATH = `${MODULE_VUE_ROUTER}-routes`
44

5+
// NOTE: not sure if needed. Used for HMR the virtual routes
6+
let time = Date.now()
7+
/**
8+
* Last time the routes were loaded from MODULE_ROUTES_PATH
9+
*/
10+
export const ROUTES_LAST_LOAD_TIME = {
11+
get value() {
12+
return time
13+
},
14+
update(when = Date.now()) {
15+
time = when
16+
},
17+
}
18+
519
export const VIRTUAL_PREFIX = 'virtual:'
620

721
// allows removing the route block from the code

src/core/vite/index.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type ViteDevServer } from 'vite'
22
import { ServerContext } from '../../options'
3-
import { asVirtualId } from '../moduleConstants'
3+
import { MODULE_ROUTES_PATH, asVirtualId } from '../moduleConstants'
44

55
export function createViteContext(server: ViteDevServer): ServerContext {
66
function invalidate(path: string) {
@@ -13,16 +13,48 @@ export function createViteContext(server: ViteDevServer): ServerContext {
1313
}
1414

1515
function reload() {
16-
if (server.ws) {
17-
server.ws.send({
18-
type: 'full-reload',
19-
path: '*',
20-
})
16+
server.hot.send({
17+
type: 'full-reload',
18+
path: '*',
19+
})
20+
}
21+
22+
// NOTE: still not working
23+
// based on https://github.com/vuejs/vitepress/blob/1188951785fd2a72f9242d46dc55abb1effd212a/src/node/plugins/localSearchPlugin.ts#L90
24+
// https://github.com/unocss/unocss/blob/f375524d9bca3f2f8b445b322ec0fc3eb124ec3c/packages/vite/src/modes/global/dev.ts#L47-L66
25+
26+
async function updateRoutes() {
27+
const modId = asVirtualId(MODULE_ROUTES_PATH)
28+
server.moduleGraph.onFileChange(modId)
29+
const mod = server.moduleGraph.getModuleById(modId)
30+
if (!mod) {
31+
return
2132
}
33+
// server.moduleGraph.invalidateModule(mod)
34+
// await new Promise((r) => setTimeout(r, 10))
35+
// console.log(
36+
// `${mod.url}\n${modId}\n`,
37+
// mod.lastInvalidationTimestamp,
38+
// ROUTES_LAST_LOAD_TIME.value
39+
// )
40+
server.hot.send({
41+
type: 'update',
42+
updates: [
43+
{
44+
acceptedPath: mod.url,
45+
path: mod.url,
46+
// NOTE: this was in the
47+
// timestamp: ROUTES_LAST_LOAD_TIME.value,
48+
timestamp: Date.now(),
49+
type: 'js-update',
50+
},
51+
],
52+
})
2253
}
2354

2455
return {
2556
invalidate,
57+
updateRoutes,
2658
reload,
2759
}
2860
}

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
asVirtualId as _asVirtualId,
88
routeBlockQueryRE,
99
ROUTE_BLOCK_ID,
10+
ROUTES_LAST_LOAD_TIME,
1011
} from './core/moduleConstants'
1112
// TODO: export standalone createRoutesContext that resolves partial options
1213
import {
@@ -123,6 +124,7 @@ export default createUnplugin<Options | undefined>((opt = {}, _meta) => {
123124

124125
// vue-router/auto-routes
125126
if (resolvedId === MODULE_ROUTES_PATH) {
127+
ROUTES_LAST_LOAD_TIME.update()
126128
return ctx.generateRoutes()
127129
}
128130

src/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ export const DEFAULT_OPTIONS = {
231231

232232
export interface ServerContext {
233233
invalidate: (module: string) => void
234+
updateRoutes: () => void
234235
reload: () => void
235236
}
236237

0 commit comments

Comments
 (0)