能够根据不一样的环境生成指定的路由文件,而不是一次性打包全部文件,默承认以遍历page目录下的全部.vue文件。html
--test
InitRouterPlugin.js
,使用yargs
模块获取命令行参数const argv = require('yargs').argv
console.log(argv.test)
复制代码
生成路由文件应在全部事情开始以前执行,webpack提供的生命周期钩子实在太多,这里就挑了一个最靠前的afterPlugins
,有兴趣的能够看下这张完整的生命周期图。vue
webpack plugin对外暴露的apply
函数,经过apply函数获取主引擎compiler
webpack
module.exports = class InitRouterPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
compiler.hooks.afterPlugins.tap('InitRouterPlugin', async (context, entry) => {
await writeRouter()
})
}
}
复制代码
这里奇怪的换行是为了生成后的文件保持格式规范web
let route = `import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const array = [
`
复制代码
这里使用的是路由懒加载模式vue-router
const fs = require('fs').promises
const path = require('path')
async function getPage(filePath) {
let files = await fs.readdir(filePath)
for (const filename of files) {
const filedir = path.join(filePath, filename)
const filehandle = await fs.open(filedir)
const stat = await filehandle.stat()
await filehandle.close()
const isFile = stat.isFile()
const isDir = stat.isDirectory()
if (isFile) {
route += ` { path: 'filename.split(".")[0]}', component: () => import('@/page${filedir.split("page")[1].replace(/\\/g, "/")}') },
`
}
if (isDir) {
await getPage(filedir) //递归,若是是文件夹,就继续遍历该文件夹下面的文件
}
}
}
复制代码
fs模块的promise语法写起来舒服多了。json
async function writeRouter() {
if (argv.test) {
// 自定义逻辑
} else {
await getPage(path.resolve('path/to/page'))
route = route.slice(0, -2) // 去掉最后一个换行和逗号
}
route += `
]
export default new Router({
routes: array
})
`
const routeFile = await fs.open(path.resolve('path/to/router.js'), 'w')
await routeFile.writeFile(route)
await routeFile.close()
}
复制代码
webpack内容实在太多,文档写的也不是很清楚,有些钩子的说明甚至只有一个名字,是让咱们本身去摸索吗(╯°Д°)╯︵ ┻━┻,实在是太南了。目前新增vue文件的话须要从新编译才会生成新的路由文件。原本还想试试监听文件的改动实时更新router.js文件,可是没有找到合适的方法。若是只是文件内容的改动,而不是新增vue就触发的话,就过于频繁了,我认为没有必要。欢迎在评论区提出意见~promise