feat(router): custom route name splitter (#4598)

This commit is contained in:
Ricardo Gobbo de Souza 2018-12-20 10:42:42 -02:00 committed by Sébastien Chopin
parent 9877c72f5d
commit add80004ba
14 changed files with 57 additions and 11 deletions

View File

@ -325,7 +325,9 @@ export default class Builder {
if (this._defaultPage) { if (this._defaultPage) {
templateVars.router.routes = createRoutes( templateVars.router.routes = createRoutes(
['index.vue'], ['index.vue'],
this.template.templatesDir + '/pages' this.template.templatesDir + '/pages',
'',
this.options.router.routeNameSplitter
) )
} else if (this._nuxtPages) { } else if (this._nuxtPages) {
// Use nuxt.js createRoutes bases on pages/ // Use nuxt.js createRoutes bases on pages/
@ -342,7 +344,8 @@ export default class Builder {
templateVars.router.routes = createRoutes( templateVars.router.routes = createRoutes(
Object.values(files), Object.values(files),
this.options.srcDir, this.options.srcDir,
this.options.dir.pages this.options.dir.pages,
this.options.router.routeNameSplitter
) )
} else { // If user defined a custom method to create routes } else { // If user defined a custom method to create routes
templateVars.router.routes = this.options.build.createRoutes( templateVars.router.routes = this.options.build.createRoutes(

View File

@ -211,13 +211,14 @@ export const flatRoutes = function flatRoutes(router, _path = '', routes = []) {
return routes return routes
} }
function cleanChildrenRoutes(routes, isChild = false) { function cleanChildrenRoutes(routes, isChild = false, routeNameSplitter = '-') {
let start = -1 let start = -1
const regExpIndex = new RegExp(`${routeNameSplitter}index$`)
const routesIndex = [] const routesIndex = []
routes.forEach((route) => { routes.forEach((route) => {
if (/-index$/.test(route.name) || route.name === 'index') { if (regExpIndex.test(route.name) || route.name === 'index') {
// Save indexOf 'index' key in name // Save indexOf 'index' key in name
const res = route.name.split('-') const res = route.name.split(routeNameSplitter)
const s = res.indexOf('index') const s = res.indexOf('index')
start = start === -1 || s < start ? s : start start = start === -1 || s < start ? s : start
routesIndex.push(res) routesIndex.push(res)
@ -226,7 +227,7 @@ function cleanChildrenRoutes(routes, isChild = false) {
routes.forEach((route) => { routes.forEach((route) => {
route.path = isChild ? route.path.replace('/', '') : route.path route.path = isChild ? route.path.replace('/', '') : route.path
if (route.path.includes('?')) { if (route.path.includes('?')) {
const names = route.name.split('-') const names = route.name.split(routeNameSplitter)
const paths = route.path.split('/') const paths = route.path.split('/')
if (!isChild) { if (!isChild) {
paths.shift() paths.shift()
@ -246,12 +247,12 @@ function cleanChildrenRoutes(routes, isChild = false) {
}) })
route.path = (isChild ? '' : '/') + paths.join('/') route.path = (isChild ? '' : '/') + paths.join('/')
} }
route.name = route.name.replace(/-index$/, '') route.name = route.name.replace(regExpIndex, '')
if (route.children) { if (route.children) {
if (route.children.find(child => child.path === '')) { if (route.children.find(child => child.path === '')) {
delete route.name delete route.name
} }
route.children = cleanChildrenRoutes(route.children, true) route.children = cleanChildrenRoutes(route.children, true, routeNameSplitter)
} }
}) })
return routes return routes
@ -316,7 +317,7 @@ const sortRoutes = function sortRoutes(routes) {
return routes return routes
} }
export const createRoutes = function createRoutes(files, srcDir, pagesDir) { export const createRoutes = function createRoutes(files, srcDir, pagesDir = '', routeNameSplitter = '-') {
const supportedExtensions = ['vue', 'js', 'ts'] const supportedExtensions = ['vue', 'js', 'ts']
const routes = [] const routes = []
files.forEach((file) => { files.forEach((file) => {
@ -333,7 +334,7 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
const sanitizedKey = key.startsWith('_') ? key.substr(1) : key const sanitizedKey = key.startsWith('_') ? key.substr(1) : key
route.name = route.name route.name = route.name
? route.name + '-' + sanitizedKey ? route.name + routeNameSplitter + sanitizedKey
: sanitizedKey : sanitizedKey
route.name += key === '_' ? 'all' : '' route.name += key === '_' ? 'all' : ''
route.chunkName = file.replace(new RegExp(`\\.(${supportedExtensions.join('|')})$`), '') route.chunkName = file.replace(new RegExp(`\\.(${supportedExtensions.join('|')})$`), '')
@ -357,7 +358,7 @@ export const createRoutes = function createRoutes(files, srcDir, pagesDir) {
}) })
sortRoutes(routes) sortRoutes(routes)
return cleanChildrenRoutes(routes) return cleanChildrenRoutes(routes, false, routeNameSplitter)
} }
// Guard dir1 from dir2 which can be indiscriminately removed // Guard dir1 from dir2 which can be indiscriminately removed

View File

@ -2,6 +2,7 @@ export default () => ({
mode: 'history', mode: 'history',
base: '/', base: '/',
routes: [], routes: [],
routeNameSplitter: '-',
middleware: [], middleware: [],
linkActiveClass: 'nuxt-link-active', linkActiveClass: 'nuxt-link-active',
linkExactActiveClass: 'nuxt-link-exact-active', linkExactActiveClass: 'nuxt-link-exact-active',

View File

@ -0,0 +1,5 @@
export default {
router: {
routeNameSplitter: '/'
}
}

View File

View File

View File

View File

View File

View File

View File

@ -0,0 +1,3 @@
import { buildFixture } from '../../utils/build'
buildFixture('route-name-splitter')

View File

@ -0,0 +1,33 @@
import { resolve } from 'path'
import fs from 'fs'
import { promisify } from 'util'
const readFile = promisify(fs.readFile)
describe('route-name-splitter', () => {
test('Check routes names', () => {
return readFile(
resolve(__dirname, '..', 'fixtures/route-name-splitter/.nuxt/router.js'),
'utf-8'
).then((routerFile) => {
routerFile = routerFile
.slice(routerFile.indexOf('routes: ['))
.replace('routes: [', '[')
.replace(/ _[0-9A-z]+,/g, ' "",')
routerFile = routerFile.substr(
routerFile.indexOf('['),
routerFile.lastIndexOf(']') + 1
)
const routes = eval('( ' + routerFile + ')') // eslint-disable-line no-eval
expect(routes[0].name).toBe('parent')
expect(routes[1].name).toBe('posts')
expect(routes[1].children[0].name).toBe('posts/id')
expect(routes[2].name).toBe('parent/child')
expect(routes[3].name).toBe('index')
expect(routes[4].name).toBe('all/p/all')
expect(routes[5].name).toBe('all/all')
expect(routes[6].name).toBe('all')
})
})
})