1.什麼是 vue-cli 插件?
Vue CLI 使用了一套基於插件的架構。如果你查閱一個新創建項目的 package.json
,就會發現依賴都是以 @vue/cli-plugin-
開頭的。插件可以修改 webpack 的內部配置,也可以向 vue-cli-service
注入命令。在項目創建的過程中,絕大部分列出的特性都是通過插件來實現的。
基於插件的架構使得 Vue CLI 靈活且可擴展。如果你對開發一個插件感興趣,請翻閱插件開發指南。
提示
你可以通過 vue ui
命令使用 GUI 安裝和管理插件。
下面plugins
裏面就是常用的vue-cli
插件:
{
"useConfigFiles": true,
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "standard",
"lintOn": [
"save"
]
},
"@vue/cli-plugin-unit-mocha": {}
},
....
....
....
}
@vue/cli-plugin-babel : 給項目添加babel的配置、 依賴 和 對應的代碼
@vue/cli-plugin-router: 給項目添加router的配置、依賴 和 集成到項目的案例代碼
編寫一個獨立的vue-cli插件:
https://cli.vuejs.org/zh/dev-guide/plugin-dev.html#cli-%E6%8F%92%E4%BB%B6
CLI 插件是一個可以爲 @vue/cli
項目添加額外特性的 npm 包。它應該始終包含一個 Service 插件作爲其主要導出,且可選的包含一個 Generator 和一個 Prompt 文件。
一個典型的 CLI 插件的目錄結構看起來是這樣的:
├── README.md
├── generator.js # generator (可選)
├── prompts.js # prompt 文件 (可選)
├── index.js # service 插件
└── package.json
2. 什麼是vue-cli 的Preset?
vue create新建項目時保存的Preset :
一個 Vue CLI preset 是一個包含創建新項目所需預定義選項和插件的 JSON 對象
,讓用戶無需在命令提示中選擇它們( 一個preset選項可以自定義 vue create 新建項目的目錄結構,項目的依賴,項目的配置等等 )
。
在 vue create
過程中保存的 preset 會被放在你的 home 目錄下的一個配置文件中 (~/.vuerc
)。你可以通過直接編輯這個文件來調整、添加、刪除保存好的 preset。
window 系統電腦的 .vuerc文件 在 C:\Users\電腦名稱\ .vuerc
這裏有一個本地 preset 的示例:
{
"useConfigFiles": true,
"cssPreprocessor": "sass",
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "airbnb",
"lintOn": ["save", "commit"]
},
"@vue/cli-plugin-router": {},
"@vue/cli-plugin-vuex": {}
}
}
Preset
的數據會被插件生成器(generator)
用來生成相應的項目文件
。除了上述這些字段,你也可以爲集成工具添加配置:
{
"useConfigFiles": true,
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}
這些額外的配置將會根據 useConfigFiles
的值被合併到 package.json
或相應的配置文件中。例如,當 "useConfigFiles": true
的時候,configs
的值將會被合併到 vue.config.js
中。
遠程的Preset :
你可以通過發佈 git repo 將一個 preset 分享給其他開發者。這個 repo 應該包含以下文件:
preset.json
: 包含 preset 數據的主要文件(必需)。generator.js
: 一個可以注入或是修改項目中文件的 Generator。prompts.js
一個可以通過命令行對話爲 generator 收集選項的 prompts 文件。
發佈 repo 後,你就可以在創建項目的時候通過 --preset
選項使用這個遠程的 preset 了:
# 從 GitHub repo 使用 preset
vue create --preset username/repo my-project
GitLab 和 BitBucket 也是支持的。如果要從私有 repo 獲取,請確保使用 --clone
選項:
vue create --preset gitlab:username/repo --clone my-project
vue create --preset bitbucket:username/repo --clone my-project
加載文件系統(本地)的 Preset :
當開發一個遠程 preset 的時候,你必須不厭其煩的向遠程 repo 發出 push 進行反覆測試。爲了簡化這個流程,你也可以直接在本地測試 preset。如果 --preset
選項的值是一個相對或絕對文件路徑,或是以 .json
結尾,則 Vue CLI 會加載本地的 preset:
# ./my-preset 應當是一個包含 preset.json 的文件夾
vue create --preset ./my-preset my-project
# 或者,直接使用當前工作目錄下的 json 文件:
vue create --preset my-preset.json my-project
4.如何編寫遠程/本地的Preset?
1.新建 vue-cli-plugin-vbpm
項目:
vue-cli-plugin-vbpm
.
|-- generator.js
|-- preset.json
|-- prompts.js
`-- template
|-- base-web2
|-- mob-web4
|-- pc-web3
`-- vue-web1
|-- preset.json
Vue CLI preset
是一個包含創建新項目所需預定義選項和插件的 JSON 對象, 默認自動安裝裏面的插件,依賴,配置等。
|-- prompts.js 內建插件對話,進行安裝時提示用戶的操作流程
|-- generator.js 允許一個向package.json
注入額外的依賴或字段,並向項目中添加 template 中的文件。
`-- template 模板文件,裏面的文件會直接被拷貝到項目中(其中有使用 ejs 模板引擎)
2.編寫 Preset,prompts 和 generator
1.preset.json 文件
一個 Vue CLI preset 是一個包含創建新項目所需預定義選項和插件的 JSON 對象,讓用戶無需在命令提示中選擇它們。當執行vue create
默認會自動安裝裏面的插件,依賴,配置 和 vue項目的基本目錄等。
preset 的示例:
{
"useConfigFiles": true,
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-eslint": {
"config": "standard",
"lintOn": [
"save"
]
},
"@vue/cli-plugin-unit-mocha": {}
},
"router": true,
"routerHistoryMode": true,
"vuex": true,
"cssPreprocessor": "node-sass"
}
plugins 是指在執行vue create新建項目的時候默認執行的vue-cli的哪些插件。
router 是指在執行vue create新建項目的時候默認是否集成router
…
Preset
的數據會被插件生成器(generator)
用來生成相應的項目文件
。例如:router:true
最終會被cli-plugin-router插件的生成器生成相應的Home.vue,About.vue,router/index.js等文件。
Preset 除了上述這些字段,你也可以爲集成工具添加配置:
例如:configs 配置
{
"useConfigFiles": true,
"plugins": {...},
"configs": {
"vue": {...},
"postcss": {...},
"eslintConfig": {...},
"jest": {...}
}
}
這些額外的配置將會根據 useConfigFiles
的值被合併到 package.json
或相應的配置文件中。例如,當 "useConfigFiles": true
的時候,configs
的值將會被合併到 vue.config.js
中。
2.prompts.js 文件
是一個內建對話配置文件,進行安裝時提示用戶的操作流程。
type 的類型有: list checkbox input confirm
// let chalk = require('chalk')
/**
* 本質上是一個對話配置文件
*/
module.exports = [
{
type: 'list', // 即類型爲 選擇項
name: 'project', // 名稱,作爲下面 generator.js導出 函數 options 的鍵
message: '請選擇你要生成的項目類型', // 提示語
choices: [
{ name: 'vue-web', value: 'vue-web' },
{ name: 'base-web', value: 'base-web' },
{ name: 'pc-web', value: 'pc-web' },
{ name: 'mo-web', value: 'mo-web' }
],
default: 'vue-web',
},
{
type: 'input', // 類型爲 輸入項
name: 'projectName', // 名稱,作爲下面 generator.js導出 函數 options 的鍵
message: '請輸入項目的名稱', // 提示語
default: 'vue-web'
},
// {
// type: 'confirm',
// name: 'testConfirm',
// // 該項目唯一安裝的依賴 chalk; 目的是使用控制檯輸出 chalk.yellow('xxx') xxx 文字有顏色
// // ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
// message: `Use history mode for router? ${chalk.yellow(`(Requires proper server setup for index fallback in production)`)}`,
// description: `Using History API, the URLs don't need '#' character.`
// }
]
可通過安裝
npm install chalk
,使用chalk.yellow( xxx )
修改控制檯輸出字體的顏色
3.generator.js 文件
允許一個向 package.json
注入額外的依賴或字段,並向項目中添加 template中的文件。template下的文件默認拷貝到vue項目中,拷貝時如果文件的路徑和文件名相同則覆蓋
,否則是疊加
。template下的模板文件可以定義變量,底層使用ejs
模板引擎進行渲染。
/**
* api : 一個 GeneratorAPI 實例
* options: 可以先簡單理解爲 prompts 問題數組的用戶輸入 組合成的選項對象
* rootOptions: 整個 preset.json 對象
*/
module.exports = (api, options, rootOptions) => {
// options.project 可以訪問上面問題數組的第一個對象的值,默認爲: 'vue-web'
console.log(`Your choice is ${options.project}`)
console.log(`Your input is ${options.projectName}`)
// 1.判斷控制檯用戶的輸入
if (options.project === 'vue-web') {
// render函數把該路徑下的 ./template/vue-web1 文件拷貝到默認的vue項目中。
// 如果文件的路徑和文件名稱相同的則覆蓋,否則是疊加
api.render('./template/vue-web1', { InputOptions:{ ...options} })
}
if (options.project === 'base-web') {
// 2.拷貝文件並傳遞變量。例如:InputOptions對象中的屬性/變量會覆蓋掉該./template/base-web2路勁下html,js,json等文件對應的屬性/變量
api.render('./template/base-web2', { InputOptions:{ ...options} })
}
if (options.project === 'pc-web') {
// 3.如果該./template/pc-web3 路徑下的內容爲空,會使用vue-cli中提供的默認的模板
api.render('./template/pc-web3', { InputOptions:{ ...options} })
}
if (options.project === 'mob-web') {
// 4.如果該 render 沒有執行,會使用 vue-cli 中提供的默認的模板
// api.render('./template/mob-web4', { InputOptions:{ ...options} })
}
// 3.修改 `package.json` 裏的字段
api.extendPackage({
// 4.添加第三庫的依賴
dependencies: {
// 'normalize.css': '^8.0.1'
},
// 4.添加第三庫的依賴
devDependencies: {
// 'normalize.css': '^8.0.1'
},
// 5.添加自定義的腳本
scripts: {
// 'dev': 'vue-cli-service serve'
},
config: {
}
})
}
參考模板引擎的寫法
https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-plugin-router/generator/template/src/App.vue
// 1.語法1: if else
<%_ if (InputOptions.project) { _%>
<script>
// 2.語法2: 插值
console.log('<%= InputOptions.projectName %>')
// 3.語法3: 插值
console.log('<%%= InputOptions.projectName %%>')
export default {
name: 'App',
components: {
}
}
</script>
<%_ } else { _%>
<script>
console.log('false')
</script>
<%_ } _%>
3.使用該 preset 新建vue項目
當開發一個遠程 preset 的時候,你必須不厭其煩的向遠程 repo 發出 push 進行反覆測試。爲了簡化這個流程,你也可以直接在本地測試 preset。如果 --preset
選項的值是一個相對或絕對文件路徑,或是以 .json
結尾,則 Vue CLI 會加載本地的 preset:
# ./vue-cli-plugin-vbpm 應當是一個包含 preset.json 的文件夾, my-vue-project是vue項目名稱
vue create --preset ./vue-cli-plugin-vbpm my-vue-project