前端工程化之plop的使用

工程化、模塊化讓編碼更加絲滑、讓我們"懶"起來

這裏記錄plop.js的使用。plop.js可以通過命令行去生成、處理文件模板代碼等,從而解放雙手。

後更加複雜的yeomannode cli自己去編寫一套針對模板腳手架的工具等。這些後面慢慢探索。

安裝plop

安裝到項目

  npm install --save-dev plop

全局安裝plop(可選,建議安裝方便使用)

npm install -g plop

如果沒有全局安裝plop,那麼要在package.json中的script中增加腳本命令:

"scripts": {
    "p": "plop"
 },

plop使用

在項目的根目錄下創建plopfile.js文件

module.exports = function (plop) {};

創建路由Generator

1、 根目錄創建一個template文件夾,並創建一個router目錄作爲路由的generator

在這裏插入圖片描述
2、 並創建generatorjs文件和hbs模板(Handlebars模板語法

在這裏插入圖片描述

三、 generatorplop.js編寫
在此之前,有幾個概念:
description:(String)描述(這個generator是幹什麼的)
prompts:(Array)給出一些詢問,讓用戶給出回答或選擇
actions:(種類較多,後面給出描述),最後一步對上述的回答詢問等做出決策,比如生成文件、替換文本、替換文件、或者自定義操作等等

const {
  isEmpty
} = require('../utils')

module.exports = {
  description: '創建根文件路由',
  prompts: [{
    type: 'input',
    name: 'moduleName',
    message: '模塊名',
    validate: isEmpty('模塊名')
  }, {
    type: 'input',
    name: 'path',
    message: '地址',
    validate: isEmpty('路由地址')
  }, {
    type: 'input',
    name: 'title',
    message: '左側菜單顯示名稱',
    validate: isEmpty('路由地址')
  }],
  actions: function (data) {
    //其中這裏的值可以使用data獲取,比如獲取和moduleName輸入的值,可以是 const moduleName = data.moduleName  ,data就是一個包含name的對象,其中的屬性key就是name的值
    const moduleName = '{{moduleName}}'
    const path = '{{path}}'
    const title = '{{title}}'
    const actions = [{
      type: 'add',
      path: `src/router/modules/${moduleName}.js`,
      templateFile: 'template/router/index.hbs',
      data: {
        moduleName: moduleName,
        path: path,
        title: title
      }
    }]
    return actions
  }
}

3、 hbs模板

import Layout from '@/layout'

const {{moduleName}} = {
  path:'/{{path}}',
  component: Layout,
  sort: 1,
  name: '{{path}}',
  meta: {
    title: '{{title}}',
    icon: 'example'
  }
}
export default {{moduleName}};

4、 設置到plopfile.js

const router = require('./template/router/plop.js')
module.exports = function(plop) {
   plop.setGenerator('router', router);
}

5、使用總結:
prompts:衆多的參數不一一解釋,都是集自inquirer,示例很多-傳送門

action: 對詢問做出反應

  • type:類型,內置4中,
    • add:根據模板生成文件
    • AddMany 可以看成add的多個版本
    • Modify :根據模板修改根據正則替換存在的文件或地方
    • Append:將模板或者字符串根據正則添加到符合正則的地方

其他的如設置自定義的action type,可以參考傳送門

上訴的action是其中一種動態的action,還有其他的直接返回actions 數組等等具體傳送門

自動化創建view視圖以及對應路由

上面初試創建一個action typeaddgenerator,接下來將更深入的結合其他的prompts以及node相關api製作更復雜的generator

想法: 創建一個模板,並增加其功能,比如查詢、新增、編輯、詳情的開關等,而且生成該模板的對應路由。

1、 創建viewgenerator以及對應的視圖模板和路由模板()
在這裏插入圖片描述
router.hbs:

  {
    path: '{{name}}',
    component: () => import('@/views/{{filepath}}/{{name}}'),
    name:'{{name}}',
    meta: {
      title: '{{menu}}'
    }
},

view index.hbs

<div>
    <header-search {{#if create}}:create="true" @create="handleCreate"{{/if}}>
      <template #search>
        <el-row>
          <el-col :span="6">
            <we-input v-model="query.name" label="名稱" placeholder="輸入名稱" />
          </el-col>
          <el-col :span="6">
            <we-select v-model="query.model" :options="list" label="型號" placeholder="輸入型號" />
          </el-col>
          <el-col :span="6">
            <we-date-picker v-model="query.begindate" label="開始時間" placeholder="選擇時間" />
          </el-col>
        </el-row>
      </template>
    </header-search>
    ...省略

2 獲取真實模塊列表用於選擇新建的模塊掛載在哪裏

const fs = require('fs');
const blackFileList = ['login', 'dashboard', 'error-page']// 不會被讀取的文件模塊
const fileList = [];
async function foundFiles() {
  const files = await fs.promises.readdir('src/views/');
  for (const file of files) {
    if (!blackFileList.includes(file)) {
      fileList.push(file)
    }
  }
}

3、 創建promoto以及action

module.exports = {
    description: '創建視圖',
    prompts: [{
        type: 'input',
        name: 'name',
        message: '輸入視圖文件名',
        validate: isEmpty('文件名')
    }, {
      type: 'list',
      name: 'filepath',
      message: '選擇加入的模塊',
      choices: fileList
    }, {
      type: 'confirm',
      name: 'hasBtn',
      message: '列表是否有操作按鈕',
      default: true
    }, {
      type: 'checkbox',
      name: 'functions',
      message: '選擇需要加入的功能',
      choices: [{
        name: '新增',
        value: 'create',
        checked: false
      }, {
        name: '詳情',
        value: 'detail',
        checked: true
      }]
    }, {
      type: 'input',
      name: 'menu',
      message: '輸入左側菜單顯示名稱',
      validate: isEmpty('菜單顯示名稱')
  }],
    actions: function (data) {
      const { functions, hasBtn } = data
      const actions = [{
        type: 'add',
        path: `src/views/{{filepath}}/{{name}}/index.vue`,
        templateFile: 'template/view/index.hbs',
        data: {
          name: '{{name}}',
          hasBtn: hasBtn, // 是否有操作按鈕
          create: functions.includes('create'), // 是否開啓新增(默認有新增就有編輯)
          detail: functions.includes('detail')// 是否開啓詳情
        }
      }, {
        type: 'append',
        path: `src/router/modules/{{filepath}}.js`,

        pattern: /\[/,
        templateFile: 'template/view/router.hbs',
        data: {
          name: '{{name}}',
          filepath: '{{filepath}}',
          menu: '{{menu}}'
        }
      }]
      return actions
    }
}

4、 設置到plopfile.js

const view = require('./template/view/plop.js')
const router = require('./template/router/plop.js')
module.exports = function(plop) {
   plop.setGenerator('router', router);
   plop.setGenerator('view', view);
}

5、運行plop(或者直接選擇view 的generator 運行plop view
在這裏插入圖片描述
6、 輸入視圖名以及選擇加入的模塊
在這裏插入圖片描述
7、 爲視圖添加列表頁是否有操作按鈕

在這裏插入圖片描述
8、爲視圖添加功能
在這裏插入圖片描述
9、爲視圖路由新增左側名稱
在這裏插入圖片描述

結果

路由生成
在這裏插入圖片描述
視圖生成:
在這裏插入圖片描述

同一時間利用webpack require.context自動化生成左側菜單
在這裏插入圖片描述

千里之行
始於足下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章