From 4dab4d0e46315d2a5a2763ec2559dfafd843063f Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Thu, 12 May 2022 11:36:31 +0200 Subject: [PATCH] feat: warn against named parent routes (#1396) Co-authored-by: Eating-Eating <47847099+Eating-Eating@users.noreply.github.com> --- __tests__/matcher/addingRemoving.spec.ts | 100 +++++++++++++++++++++++ src/matcher/index.ts | 27 ++++++ 2 files changed, 127 insertions(+) diff --git a/__tests__/matcher/addingRemoving.spec.ts b/__tests__/matcher/addingRemoving.spec.ts index 4819ff2e..33626210 100644 --- a/__tests__/matcher/addingRemoving.spec.ts +++ b/__tests__/matcher/addingRemoving.spec.ts @@ -441,5 +441,105 @@ describe('Matcher: adding and removing records', () => { ) expect('same param named').not.toHaveBeenWarned() }) + + it('warns if a named route has an empty non-named child route', () => { + createRouterMatcher( + [ + { + name: 'UserRoute', + path: '/user/:id', + component, + children: [{ path: '', component }], + }, + ], + {} + ) + expect('has a child without a name').toHaveBeenWarned() + }) + + it('no warn if both or just the child are named', () => { + createRouterMatcher( + [ + { + name: 'UserRoute', + path: '/user/:id', + component, + children: [{ path: '', name: 'UserHome', component }], + }, + { + path: '/', + component, + children: [{ path: '', name: 'child', component }], + }, + ], + {} + ) + expect('has a child without a name').not.toHaveBeenWarned() + }) + + it('warns if nested child is missing a name', () => { + createRouterMatcher( + [ + { + name: 'parent', + path: '/a', + component, + children: [ + { + path: 'b', + name: 'b', + component, + children: [{ path: '', component }], + }, + ], + }, + ], + {} + ) + expect('has a child without a name').toHaveBeenWarned() + }) + + it('warns if middle nested child is missing a name', () => { + createRouterMatcher( + [ + { + path: '/a', + component, + children: [ + { + path: '', + name: 'parent', + component, + children: [{ path: '', component }], + }, + ], + }, + ], + {} + ) + expect('has a child without a name').toHaveBeenWarned() + }) + + it('no warn if nested child is named', () => { + createRouterMatcher( + [ + { + name: 'parent', + path: '/a', + component, + children: [ + { + path: 'b', + name: 'b', + component, + children: [{ path: '', name: 'child', component }], + }, + ], + }, + ], + {} + ) + expect('has a child without a name').not.toHaveBeenWarned() + }) }) }) diff --git a/src/matcher/index.ts b/src/matcher/index.ts index 1756020e..d8b2dfb8 100644 --- a/src/matcher/index.ts +++ b/src/matcher/index.ts @@ -79,6 +79,9 @@ export function createRouterMatcher( // used later on to remove by name const isRootAdd = !originalRecord const mainNormalizedRecord = normalizeRouteRecord(record) + if (__DEV__) { + checkChildMissingNameWithEmptyPath(mainNormalizedRecord, parent) + } // we might be the child of an alias mainNormalizedRecord.aliasOf = originalRecord && originalRecord.record const options: PathParserOptions = mergeOptions(globalOptions, record) @@ -452,6 +455,30 @@ function checkSameParams(a: RouteRecordMatcher, b: RouteRecordMatcher) { } } +/** + * A route with a name and a child with an empty path without a name should warn when adding the route + * + * @param mainNormalizedRecord - RouteRecordNormalized + * @param parent - RouteRecordMatcher + */ +function checkChildMissingNameWithEmptyPath( + mainNormalizedRecord: RouteRecordNormalized, + parent?: RouteRecordMatcher +) { + if ( + parent && + parent.record.name && + !mainNormalizedRecord.name && + !mainNormalizedRecord.path + ) { + warn( + `The route named "${String( + parent.record.name + )}" has a child without a name and an empty path. Using that name won't render the empty path child so you probably want to move the name to the child instead. If this is intentional, add a name to the child route to remove the warning.` + ) + } +} + function checkMissingParamsInAbsolutePath( record: RouteRecordMatcher, parent: RouteRecordMatcher -- 2.47.3