Element3開發內幕 - Vue CLI插件開發

Element3開發內幕 - Vue CLI插件開發

官方開發指南 cli.vuejs.org/zh/dev-guid…javascript

咱們團隊的Element發佈了。爲了讓你們使用起來便捷。須要加入vue-cli和vite生態之中。css

今天先說說vue-cli插件如何開發。html

你們能夠嘗試一下先前端

vue create vue3-demo
vue add element3
複製代碼

image-20201126153311199

1、什麼是Vue CLI插件

Vue CLI工具是Vue生態在Vue生態中負責工具基礎標準化。他使用一套基於插件的架構。vue

好比vue-router、vuex或者安裝組件庫等均可以經過插件的形式安裝。java

vue add 的設計意圖是爲了安裝和調用 Vue CLI 插件。git

# 插件安裝
vue add vuex
複製代碼

一個vue add xxx就搞定了。github

2、功能實現

1. 搭建框架

1.1 初始npm庫

爲了讓一個 CLI 插件在 Vue CLI 項目中被正常使用,它必須遵循 vue-cli-plugin-<name> 或者 @scope/vue-cli-plugin-<name> 這樣的命名慣例。這樣你的插件纔可以:web

  • @vue/cli-service 發現;

也就是說咱們只須要將npm庫的名字命名爲 vue-cli-plugin-element3vue-router

這樣只要最後提交到npm倉庫後 ,咱們經過

vue add element3
複製代碼

就能夠安裝插件了

mkdir vue-cli-plugin-element3
npm init -y
複製代碼

image-20201126112957727

2. 安裝配置命令行交互

在安裝插件前一般會經過命令行交互形式,選擇一下安裝參數:

好比Element中須要詢問

  • 是否全局安裝

    image-20201126112403496

  • 是否使用sass?

    image-20201126112423598

這個功能是使用經過 inquirer 實現。其實你本身寫一個cli工具通常也會用這個功能

在這裏面咱們只須要編輯一下 prompts.js文件就能夠了。具體配置能夠參考 inquirer

module.exports = [
  {
    type: 'list',
    name: 'import',
    message: 'How do you want to import Element3?',
    choices: [
      { name: 'Fully import', value: 'full' },
      { name: 'Import on demand', value: 'partial' }
    ],
    default: 'full',
  },
  {
    when: answers => answers.import === 'full',
    type: 'confirm',
    name: 'customTheme',
    message: 'Do you wish to overwrite Element\'s SCSS variables?',
    default: false,
  },
]
複製代碼

3. 代碼生成器Generator

添加element3組件庫的主要功能集中在生成器上。生成器的做用就是

  • 修改已有代碼
  • 添加代碼
  • 添加依賴
  • 其餘功能(好比babel配置)

若是手工添加Element3庫大概須要如下步驟:

  • npm添加依賴庫
  • 以vue plugin形式添加組件庫
  • main.js引用組件庫
  • App.vue中寫一個代碼例子 好比: 引用一個按鈕 確認安裝效果

image-20201126152542316

3.1 添加依賴

module.exports = (api, opts, rootOptions) => {
 api.extendPackage({
  dependencies: {
    'element3': '^0.0.26'
  }
})
}
複製代碼

這個功能其實就是調用cli提供的api就能夠實現了。

3.2 添加插件

添加插件的過程其實就是須要添加/plugins/element.js文件

生成代碼一般會使用模板引擎渲染方式,過程相似後端代碼渲染,經常使用的庫有ejs模板和hbs模板

cli工具中要求咱們使用ejs模板。

若是想了解模板引擎實現原理 請看這篇【每天造輪子 - 模板引擎】](juejin.cn/post/688413…)

首先定義模板

// 部分節選
<%_ if (options.import === 'full') { _%>
import Element3 from 'element3'
<%_ if (options.customTheme) { _%>
import '../element-variables.scss'
<%_ } else { _%>
import 'element3/lib/theme-chalk/index.css'
<%_ } _%> 
<%_ if (options.lang !== 'en') { _%>
import locale from 'element3/lib/locale/lang/<%= options.lang %>'
<%_ } _%>
<%_ } else { _%>
import { ElButton } from 'element3'
import 'element3/lib/theme-chalk/index.css'
<%_ if (options.lang !== 'en') { _%>
import lang from 'element3/lib/locale/lang/<%= options.lang %>'
import locale from 'element3/lib/locale'
<%_ }} _%>

export default (app) => {
  <%_ if (options.import === 'full') { _%>
  <%_ if (options.lang !== 'en') { _%>
  app.use(Element3, { locale })
  <%_ } else { _%>
  app.use(Element3)
  <%_ } _%>
  <%_ } else { _%>
  <%_ if (options.lang !== 'en') { _%>
  locale.use(lang)
  <%_ } _%>
  app.use(ElButton)
  <%_ } _%>
}
複製代碼

調用模板引擎渲染

這裏面仍是使用api提供的render方法 其實就是ejs模板引擎

api.render({
    './src/plugins/element.js': './templates/src/plugins/element.js.ejs',
  })
複製代碼

3.3 添加插件引用

添加插件引用至關於在main.js文件中增長內容

image-20201126114822949

這個程序邏輯比較簡單 ,只須要經過簡單的文件操做+正則就能夠完成。

若是是複雜功能還須要藉助AST抽象語法樹完成。這個後續章節有介紹。

api.afterInvoke(() => {
    const { EOL } = require('os')
    const fs = require('fs')
    const contentMain = fs.readFileSync(api.resolve(api.entryFile), { encoding: 'utf-8' })
    const lines = contentMain.split(/\r?\n/g)

    const renderIndex = lines.findIndex(line => line.match(/createApp\(App\)\.mount\('#app'\)/))
    lines[renderIndex] = `const app = createApp(App)`
    lines[renderIndex + 1] = `installElement3(app)`
    lines[renderIndex + 2] = `app.mount('#app')`

    fs.writeFileSync(api.resolve(api.entryFile), lines.join(EOL), { encoding: 'utf-8' })
  })
複製代碼

3.4 添加代碼示例

這個功能仍是經過代碼模板渲染代碼。

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div>
      <p>
        If Element3 is successfully added to this project, you'll see an
        <code v-text="'<el-button>'"></code>
        below
      </p>
      <el-button type="primary">el-button</el-button>
    </div>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script> import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', components: { HelloWorld } } </script>

<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>

複製代碼
api.render({
    './src/App.vue': './templates/src/App.vue.ejs'
})
複製代碼

4. Service處理

service的會在啓動服務時運行。咱們這裏就小小的秀一下Logo。

image-20201126151912647

咱們使用figlet + chalk完成

const figlet = require('figlet')
const chalk = require('chalk')

module.exports = () => {
    console.log(chalk.yellow(figlet.textSync('Element 3', {
        font: 'big',
        horizontalLayout: 'default',
        verticalLayout: 'default',
        width: 80,
        whitespaceBreak: true
    })));
}

複製代碼

3、本地調試

在沒有上傳npm前須要,本地安裝,方法以下:

# 再次安裝依賴
yarn
npm install --save-dev file:/Users/xiaran/source/hug-sun/vue-cli-plugin-element3
vue invoke vue-cli-plugin-element3
複製代碼

4、上傳npm倉庫

上傳倉庫就是執行npm publish就好了。只不過要注意須要更改鏡像倉庫。上傳完後再改回來。

#!/usr/bin/env bash
npm config get registry # 檢查倉庫鏡像庫
npm config set registry=http://registry.npmjs.org
echo '請進行登陸相關操做:'
npm login # 登錄
echo "-------publishing-------"
npm publish # 發佈
npm config set registry=https://registry.npm.taobao.org # 設置爲淘寶鏡像
echo "發佈完成"
exit
複製代碼

image-20201126153030461

年輕人要講武德!!!點贊關注收藏都要安排起來!!!

截屏2020-11-14 下午10.38.43

🔥公衆號搜索:【前端大班車】 獲取更多 Element3開發內幕教程


img

相關文章
相關標籤/搜索