Skip to content

Instantly share code, notes, and snippets.

@abiosoft
Last active May 7, 2020 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abiosoft/72356a67e10540bbd8c84a1430119e35 to your computer and use it in GitHub Desktop.
Save abiosoft/72356a67e10540bbd8c84a1430119e35 to your computer and use it in GitHub Desktop.
Generate Routes for vue view files
/* eslint-disable @typescript-eslint/no-var-requires */
/*
Usage: modify package.json
"scripts": {
...
"routes": "vue-cli-service routes"
},
"vuePlugins": {
"service": [
"path/to/this/script.js"
]
},
*/
const fs = require('fs')
const LOCK_FILE = '.routeLock'
const toRoutes = (fileList) => {
const routes = []
fileList.forEach(f => {
if (f === '') {
routes.push({
name: 'root',
path: '/',
component: '@/views/Home.vue',
chunkName: '/* webpackChunkName: "Root" */'
})
return
}
f = f.substring(10, f.length - 4)
const name = f.replace('/', '-')
routes.push({
name,
path: '/' + f.toLowerCase(),
component: '@/views/' + f + '.vue',
chunkName: '/* webpackChunkName: "' + name + '" */'
})
})
return routes
}
function shouldWrite () {
try {
const ff = fs.readFileSync(LOCK_FILE)
return !ff || ff.toString() !== '1'
} catch (e) { return true }
}
function lock () {
fs.writeFileSync(LOCK_FILE, '1')
}
function unlock () {
fs.writeFileSync(LOCK_FILE, '0')
}
const generate = () => {
if (!shouldWrite()) {
unlock()
return
}
lock()
const execFile = require('child_process').execFileSync
const stdout = execFile('find', ['src/views', '-type', 'f', '-name', '*.vue'])
const fileList = stdout.toString().split('\n').sort()
const routes = toRoutes(fileList)
let i = 0
let text = '// auto generated - do not edit'
text += '\n'
text += '\nexport default ['
routes.forEach(f => {
if (i++ !== 0) {
text += ','
}
text += '\n'
text += ' {'
text += '\n'
text += ` name: '${f.name}',`
text += '\n'
text += ` path: '${f.path}',`
text += '\n'
text += ` component: () => import(${f.chunkName} '${f.component}')`
text += '\n'
text += ' }'
})
text += '\n'
text += ']'
text += '\n'
fs.writeFileSync('src/router/routes.ts', text)
}
class RouteGeneratorPlugin {
apply (compiler) {
compiler.hooks.thisCompilation.tap('route-generator', compilation => {
try {
generate()
} catch (error) {
compilation.errors.push(error)
}
})
}
}
module.exports = (api, options) => {
api.registerCommand(
'routes',
{
description: 'Generate Routes',
usage: 'vue-cli-service routes'
},
() => {
generate(api, options)
}
)
api.chainWebpack(webpackConfig => {
webpackConfig
.plugin('route-generator')
.use(RouteGeneratorPlugin)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment