一個自動生成vue路由文件的webpack插件

能夠根據不一樣的環境生成指定的路由文件,而不是一次性打包全部文件,默承認以遍歷page目錄下的全部.vue文件。html

獲取命令行參數

  • 在package.json中新建一個scripts指令,帶上參數,如 --test
  • 新建InitRouterPlugin.js,使用yargs模塊獲取命令行參數
const argv = require('yargs').argv
console.log(argv.test)
複製代碼

webpack鉤子

生成路由文件應在全部事情開始以前執行,webpack提供的生命週期鉤子實在太多,這裏就挑了一個最靠前的afterPlugins,有興趣的能夠看下這張完整的生命週期圖vue

webpack plugin的基本模板

webpack plugin對外暴露的apply函數,經過apply函數獲取主引擎compilerwebpack

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 = [
`
複製代碼

二、遍歷page目錄

這裏使用的是路由懶加載模式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

相關文章
相關標籤/搜索