Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions src/directory-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,163 @@ function parsePagesDirectory(
let routes = []

//TODO
let filesList = []
const dirList = readFileList(path.join(dir, '/'), filesList)
console.log("============xxxxxx=============filesList=", filesList);

let name, rPath, component,hasChildren
const rIndex = new RegExp('index')
const rDash = new RegExp('/', 'g')
const rUnderLine = new RegExp('_')
const rColons = new RegExp(':')
const routeMap = filesList
.filter(elm => elm.filename.indexOf('ignored') == -1)
.map((elm) => {
name = getFileName(elm.filename)
rPath = getFileName(path.relative(dir, elm.fullPath))
component = elm.fullPath
hasChildren = existSameNameDir(name, elm, dirList)
// index文件的特殊处理
if (name == 'index') rPath = rPath.replace(rIndex, '')
//参数的特殊处理
if (name.startsWith('_')) name = name.substring(1)
if (rPath.indexOf('_') != -1) rPath = rPath.replace(rUnderLine, ':')
//子目录的特殊处理
if (rPath.indexOf('/') != -1) {
name = rPath.replace(rDash, '-')
if (name.indexOf(':') != -1) name = name.replace(rColons,'')
}
if (name.endsWith('-')) name = name.substring(0, name.length - 1)

console.log(`old name == ${getFileName(elm.filename)}, new name = ${name}}`)

if (hasChildren)
return {
name: name,
rPath: rPath,
component: component,
hasChildren: true,
fullPath: elm.fullPath,
path: path.join(getFileName(elm.fullPath), '/'),
}
else
return {
name: name,
rPath: rPath,
component: component,
hasChildren: false,
path: elm.path,
fullPath: elm.fullPath,
parentDir: elm.dirName,
}

})
.map((elm) => {
if (elm.hasChildren == false && dirList.find((elmDir) => elmDir.hasChildren && elmDir.dirName == elm.parentDir )){
elm.isChildComponent = true
elm.rPath = elm.rPath.substring(elm.rPath.lastIndexOf('/')+1)
if (path.basename(elm.fullPath) == 'index.vue') elm.rPath = ''
}
else {
elm.isChildComponent = false
if (elm.hasChildren == false) //没有子组件的文件,也不是子组件的文件
elm.path = elm.fullPath
}
return elm
})
.reduce((result, elm, index, arr) => {
if (result.has(elm.path) == false) {
if (elm.hasChildren)
result.set(elm.path, {
name: elm.name,
rPath: elm.rPath,
component: elm.component,
hasChildren: elm.hasChildren,
children: [],
})
else if (elm.isChildComponent) result.set(elm.path, { children: [elm] })
else
result.set(elm.path, {
name: elm.name,
rPath: elm.rPath,
component: elm.component,
hasChildren: false,
})
} else {
value = result.get(elm.path)
if (elm.hasChildren){
value = {
name: elm.name,
rPath: elm.rPath,
component: elm.component,
hasChildren: elm.hasChildren,
...value,
}
result.set(elm.path, value)
}
else value.children.push(elm)
}
return result
}, new Map())


console.log("=========================routeMap=", routeMap, routes);
// return { routeMap }
// routes = routeList.filter(elm => elm.isDirectory == false)

for (const [_, elm] of routeMap) {
if (elm.hasChildren)
routes.push(`{ path: '/${elm.rPath}', component: () => import('/${elm.component}'), children: [ ${printChildren(elm.children)} ] }`)
else
routes.push(`{ name: '${elm.name}', path: '/${elm.rPath}', component: () => import('/${elm.component}') }`)
}
console.log("=========================routes=", routes);

return { routes }
}

function printChildren(children){
let str = ''
for (elm of children)
str = str.concat(`{ name: '${elm.name}', path: '${elm.rPath}', component: () => import('/${elm.component}') }, `)
return str.substring(0, str.length-2) //截取尾部逗号
}

// 判断某个文件是否有子目录,有子目录则表示有children组件
function existSameNameDir(fileBaseName, fileInfo, dirList){
result = dirList.find(elm => (elm.dirName == fileBaseName && elm.path == (path.join(fileInfo.path, fileBaseName, '/')) ))
if (result)
result.hasChildren = true
return result? true : false
}

function getFileName(data) {
return data.substring(0, data.indexOf('.'))
}

function readFileList(path, filesList) {
var dirList = []
var files = fs.readdirSync(path)
files.forEach(function (itm, index) {
var stat = fs.statSync(path + itm)
var obj = {}
if (stat.isDirectory()) {
obj.dirName = itm
obj.path = path + itm + '/'
dirList.push(obj)
readFileList(obj.path, filesList)
} else {
obj.dirName= path.substring(path.lastIndexOf('/', path.length-2)+1, path.length-1) //所在目录
obj.path = path //路径
obj.filename = itm //名字
obj.fullPath = path + itm //全路径
filesList.push(obj)
}
}
)
return dirList
}

module.exports = {
parsePagesDirectory,
}
5 changes: 2 additions & 3 deletions tests/directory-parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ test('directory with a little nesting', () => {
`{ name: 'contact', path: '/contact', component: () => import('/${dir}/contact.vue') }`,
`{ name: 'index', path: '/', component: () => import('/${dir}/index.vue') }`,
`{ name: 'level1-about', path: '/level1/about', component: () => import('/${dir}/level1/about.vue') }`,
`{ name: 'level1-team', path: '/level1/team', component: () => import('/${dir}/level1/team.vue') }`,
`{ name: 'level1-level2-deep', path: '/level1/level2/deep', component: () => import('/${dir}/level1/level2/deep.vue') }`,
`{ name: 'level1-level2', path: '/level1/level2/', component: () => import('/${dir}/level1/level2/index.vue') }`,
`{ name: 'level1-team', path: '/level1/team', component: () => import('/${dir}/level1/team.vue') }`,
])
})

Expand All @@ -68,9 +68,9 @@ test('directory with some params', () => {
const { routes } = parsePagesDirectory(dir)

expect(routes).toEqual([
`{ name: 'about', path: '/about', component: () => import('/${dir}/about.vue') }`,
`{ name: 'product-buy', path: '/:product/buy', component: () => import('/${dir}/_product/buy.vue') }`,
`{ name: 'product-sell', path: '/:product/sell', component: () => import('/${dir}/_product/sell.vue') }`,
`{ name: 'about', path: '/about', component: () => import('/${dir}/about.vue') }`,
`{ name: 'team-name', path: '/team/:name', component: () => import('/${dir}/team/_name.vue') }`,
`{ name: 'team-join', path: '/team/join', component: () => import('/${dir}/team/join.vue') }`,
])
Expand All @@ -92,7 +92,6 @@ test('directory with everything', () => {
}`,
`{ name: 'about', path: '/about', component: () => import('/${dir}/about.vue') }`,
oneLine`{
name: 'contact',
path: '/contact',
component: () => import('/${dir}/contact.vue'),
children: [
Expand Down