通過npm或yarn自動生成vue元件
不知道大家每次新建元件的時候,是不是都要建立一個目錄,然後新增一個.vue檔案,然後寫template、script、style這些東西,如果是公共元件,是不是還要新建一個index.js用來匯出vue元件、雖然有vscode有程式碼片段能實現自動補全,但還是很麻煩,今天靈活運用scripts工作流,自動生成vue檔案和目錄。
實踐步驟
- 安裝一下chalk,這個外掛能讓我們的控制檯輸出語句有各種顏色區分
npm install chalk --save-dev
yarn add chalk --save-dev - 在根目錄中建立一個 scripts 資料夾
- 新增一個generateComponent.js檔案,放置生成元件的程式碼
- 新增一個template.js檔案,放置元件模板的程式碼
template.js檔案,裡面的內容可以自己自定義,符合當前專案的模板即可
// template.js module.exports = { vueTemplate: compoenntName => { return `<template> <div class="${compoenntName}"> ${compoenntName}元件 </div> </template> <script> export default { name: '${compoenntName}' } </script> <style scoped lang="stylus" rel="stylesheet/stylus"> .${compoenntName} { } </style> ` }, entryTemplate: `import Main from './main.vue' export default Main` }
generateComponent.js生成vue目錄和檔案的程式碼
// generateComponent.js` const chalk = require('chalk') // 控制檯列印彩色 const path = require('path') const fs = require('fs') const resolve = (...file) => path.resolve(__dirname, ...file) const log = message => console.log(chalk.green(`${message}`)) const successLog = message => console.log(chalk.blue(`${message}`)) const errorLog = error => console.log(chalk.red(`${error}`)) const { vueTemplate, entryTemplate } = require('./template') const _ = process.argv.splice(2)[0] === '-com' const generateFile = (path, data) => { if (fs.existsSync(path)) { errorLog(`${path}檔案已存在`) return } return new Promise((resolve, reject) => { fs.writeFile(path, data, 'utf8', err => { if (err) { errorLog(err.message) reject(err) } else { resolve(true) } }) }) } // 公共元件目錄src/base,全域性註冊元件目錄src/base/global,頁面元件目錄src/components _ ? log('請輸入要生成的元件名稱、如需生成全域性元件,請加 global/ 字首') : log('請輸入要生成的頁面元件名稱、會生成在 components/目錄下') let componentName = '' process.stdin.on('data', async chunk => { const inputName = String(chunk).trim().toString() // 根據不同型別元件分別處理 if (_) { // 元件目錄路徑 const componentDirectory = resolve('../src/base', inputName) // vue元件路徑 const componentVueName = resolve(componentDirectory, 'main.vue') // 入口檔案路徑 const entryComponentName = resolve(componentDirectory, 'index.js') const hasComponentDirectory = fs.existsSync(componentDirectory) if (hasComponentDirectory) { errorLog(`${inputName}元件目錄已存在,請重新輸入`) return } else { log(`正在生成 component 目錄 ${componentDirectory}`) await dotExistDirectoryCreate(componentDirectory) } try { if (inputName.includes('/')) { const inputArr = inputName.split('/') componentName = inputArr[inputArr.length - 1] } else { componentName = inputName } log(`正在生成 vue 檔案 ${componentVueName}`) await generateFile(componentVueName, vueTemplate(componentName)) log(`正在生成 entry 檔案 ${entryComponentName}`) await generateFile(entryComponentName, entryTemplate) successLog('生成成功') } catch (e) { errorLog(e.message) } } else { const inputArr = inputName.split('/') const directory = inputArr[0] let componentName = inputArr[inputArr.length - 1] // 頁面元件目錄 const componentDirectory = resolve('../src/components', directory) // vue元件 const componentVueName = resolve(componentDirectory, `${componentName}.vue`) const hasComponentDirectory = fs.existsSync(componentDirectory) if (hasComponentDirectory) { log(`${componentDirectory}元件目錄已存在,直接生成vue檔案`) } else { log(`正在生成 component 目錄 ${componentDirectory}`) await dotExistDirectoryCreate(componentDirectory) } try { log(`正在生成 vue 檔案 ${componentName}`) await generateFile(componentVueName, vueTemplate(componentName)) successLog('生成成功') } catch (e) { errorLog(e.message) } } process.stdin.emit('end') }) process.stdin.on('end', () => { log('exit') process.exit() }) function dotExistDirectoryCreate (directory) { return new Promise((resolve) => { mkdirs(directory, function () { resolve(true) }) }) } // 遞迴建立目錄 function mkdirs (directory, callback) { var exists = fs.existsSync(directory) if (exists) { callback() } else { mkdirs(path.dirname(directory), function () { fs.mkdirSync(directory) callback() }) } }
- 配置package.json,scripts新增兩行命令,其中-com是為了區別是建立頁面元件還是公共元件
"scripts": { "new:view":"node scripts/generateComponent", "new:com": "node scripts/generateComponent -com" },
- 執行
npm run new:view // 生成頁元件 npm run new:com // 生成基礎元件 或者 yarn run new:view // 生成頁元件 yarn run new:com // 生成基礎元件