Skip to content

Commit 476c669

Browse files
committed
feat(experimental): warn against non absolute aliases
1 parent 6e8f1a1 commit 476c669

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { PrefixTree } from '../core/tree'
2+
3+
/**
4+
* Generates runtime warnings for aliases that are not absolute paths.
5+
*
6+
* @param tree - prefix tree to scan
7+
*
8+
* @internal
9+
*/
10+
export function generateAliasWarnings(tree: PrefixTree): string {
11+
const warnings: string[] = []
12+
13+
for (const node of tree.getChildrenDeepSorted()) {
14+
for (const alias of node.value.alias) {
15+
if (!alias.startsWith('/')) {
16+
warnings.push(
17+
`console.warn('[vue-router] Alias "${alias}" for route "${node.value.fullPath}" must be absolute (start with "/"). Relative aliases are not supported in file-based routing.')`
18+
)
19+
}
20+
}
21+
}
22+
23+
return warnings.join('\n')
24+
}

packages/router/src/unplugin/codegen/generateRouteResolver.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from './generateRouteResolver'
99
import { ImportsMap } from '../core/utils'
1010
import { ParamParsersMap } from './generateParamParsers'
11+
import { generateAliasWarnings } from './generateAliasWarnings'
1112

1213
const DEFAULT_OPTIONS = resolveOptions({})
1314
let DEFAULT_STATE: Parameters<typeof generateRouteRecord>[0]['state'] = {
@@ -1344,5 +1345,42 @@ describe('generateRouteResolver', () => {
13441345
expect(resolver).toMatch(/createFixedResolver\(\[[\s\S]*__route_0/)
13451346
expect(resolver).toMatch(/createFixedResolver\(\[[\s\S]*__route_1/)
13461347
})
1348+
1349+
it('warns on relative aliases', () => {
1350+
const tree = new PrefixTree(DEFAULT_OPTIONS)
1351+
const node = tree.insert('admin/users', 'admin/users.vue')
1352+
node.setCustomRouteBlock('admin/users.vue', { alias: ['users'] })
1353+
1354+
const warnings = generateAliasWarnings(tree)
1355+
1356+
expect(warnings).toContain('console.warn')
1357+
expect(warnings).toContain('Alias "users"')
1358+
expect(warnings).toContain('must be absolute')
1359+
})
1360+
1361+
it('does not warn on absolute aliases', () => {
1362+
const tree = new PrefixTree(DEFAULT_OPTIONS)
1363+
const node = tree.insert('users', 'users.vue')
1364+
node.setCustomRouteBlock('users.vue', { alias: ['/people'] })
1365+
1366+
const warnings = generateAliasWarnings(tree)
1367+
1368+
expect(warnings).toBe('')
1369+
})
1370+
1371+
it('warns on each relative alias individually', () => {
1372+
const tree = new PrefixTree(DEFAULT_OPTIONS)
1373+
const node = tree.insert('users', 'users.vue')
1374+
node.setCustomRouteBlock('users.vue', {
1375+
alias: ['people', '/members', 'folks'],
1376+
})
1377+
1378+
const warnings = generateAliasWarnings(tree)
1379+
1380+
expect(warnings).toContain('"people"')
1381+
expect(warnings).toContain('"folks"')
1382+
expect(warnings).not.toContain('"members"')
1383+
expect(warnings).not.toContain('"/members"')
1384+
})
13471385
})
13481386
})

packages/router/src/unplugin/core/context.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { EditableTreeNode } from './extendRoutes'
2121
import { ts } from '../utils'
2222
import { generateRouteResolver } from '../codegen/generateRouteResolver'
2323
import { generateDuplicatedRoutesWarnings } from '../codegen/generateDuplicateRoutesWarnings'
24+
import { generateAliasWarnings } from '../codegen/generateAliasWarnings'
2425
import { type FSWatcher, watch as fsWatch } from 'chokidar'
2526
import {
2627
generateParamParsersTypesDeclarations,
@@ -297,6 +298,7 @@ export function createRoutesContext(options: ResolvedOptions) {
297298
}
298299

299300
const routeDupsWarns = generateDuplicatedRoutesWarnings(routeTree)
301+
const aliasWarns = generateAliasWarnings(routeTree)
300302

301303
const hmr = ts`
302304
export function handleHotUpdate(_router, _hotUpdateCallback) {
@@ -326,7 +328,7 @@ if (import.meta.hot) {
326328
})
327329
}`
328330

329-
const newAutoResolver = `${imports}${routeDupsWarns}\n${missingParserErrors}${resolverCode}\n${hmr}`
331+
const newAutoResolver = `${imports}${routeDupsWarns}\n${aliasWarns}\n${missingParserErrors}${resolverCode}\n${hmr}`
330332

331333
// prepend it to the code
332334
return newAutoResolver

0 commit comments

Comments
 (0)