為何要進(jìn)行組件庫開發(fā)
如果你所在的公司對(duì)于頁面的樣式?jīng)]有什么要求围详,那么你只要隨便拿一個(gè)組件庫來用就行了外驱,比如element屠凶、iView等等馋记,不用再重復(fù)造輪子了号坡;
如果你目前只有個(gè)人用一個(gè)組件,或者是只對(duì)個(gè)別組件有要求梯醒,那么只要在你的工程里面開發(fā)一個(gè).vue單文件組件就可以了宽堆;如果你的團(tuán)隊(duì)想要一個(gè)更加快速的開發(fā)方式,希望有一套一類應(yīng)用的標(biāo)準(zhǔn)茸习,并且對(duì)組件的樣式有較高的要求畜隶,那么你就需要開發(fā)一個(gè)組件庫了。
正確的學(xué)習(xí)方式
我覺得我寫完這篇文章以后号胚,大家看完可能只是能按部就班地開發(fā)一個(gè)組件庫而已籽慢,而且具體的記憶和理解不是很深,所以我覺得正確的方式應(yīng)該是站在巨人的肩膀上猫胁,比如去查看element組件庫的源碼箱亿,去了解他的文件組織方式,文檔是如何管理的弃秆,主題文件是如何管理的届惋,以及一些復(fù)雜組件是如何實(shí)現(xiàn)的。接下來菠赚,我們就進(jìn)入正題盼樟。
步驟
我們來理一下整個(gè)步驟:
- 創(chuàng)建項(xiàng)目
- 調(diào)整項(xiàng)目結(jié)構(gòu)
- 編寫組件
- 使用vue-cli-service庫模式打包編譯
- 發(fā)布到npm
創(chuàng)建項(xiàng)目
# 創(chuàng)建目錄
mkdir frog-ui
# 切換目錄
cd frog-ui
# 初始化項(xiàng)目
vue create .
調(diào)整目錄
將項(xiàng)目的目錄調(diào)整到以下形式,該目錄方式像是成了業(yè)界不成名的規(guī)定锈至,element和iview都是以這樣的方式組織的晨缴。我覺得挺好的,所以不做修改了峡捡。
其中:
|-- examples // 為原來的src目錄改名而來击碗,用于測(cè)試編寫的組件
|-- packages // 用于組織我們的組件庫
目錄調(diào)整以后,我們需要修改相應(yīng)的webpack配置们拙,使原來的src目錄指向修改后的examples目錄稍途,修改vue.config.js文件:
const path = require('path')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
// 將entry指向examples
pages: {
index: {
entry: 'examples/main.js',
template: 'public/index.html',
filename: 'index.html'
}
},
// 為packages目錄添加babel-loader處理
chainWebpack: config => {
config.module
.rule('js')
.include
.add(resolve('packages'))
.end()
.use('babel')
.loader('babel-loader')
.tap(options => {
return options
})
}
}
編寫組件
packages目錄下面的文件組織情況如下:
其中:
|-- datePicker // 新編寫的組件,以datepicker為例
|-- theme-default // 主題文件
主題文件較為特殊砚婆,他作為單獨(dú)的一個(gè)包進(jìn)行發(fā)布引入械拍,方便進(jìn)行主題發(fā)布突勇,后面再進(jìn)行介紹。下面對(duì)datePicker進(jìn)行介紹:
datePicker.vue
<template>
<div>這是一個(gè)datePicker組件</div>
</template>
<script>
export default {
name: 'datePicker'
}
</script>
datePicker/src/index.js
// 導(dǎo)入組件坷虑,組件必須聲明 name
import datePicker from './src/datePicker.vue'
// 為組件提供 install 安裝方法甲馋,供按需引入
datePicker.install = function (Vue) {
Vue.component(datePicker.name, datePicker)
}
// 默認(rèn)導(dǎo)出組件
export default datePicker
</script>
批量注冊(cè)組件
// 導(dǎo)入日期選擇器組件
import datePicker from './datePicker'
// 存儲(chǔ)組件列表
const components = [
datePicker
]
// 定義 install 方法,接收 Vue 作為參數(shù)迄损。如果使用 use 注冊(cè)插件定躏,則所有的組件都將被注冊(cè)
const install = function (Vue) {
// 判斷是否安裝
if (install.installed) return
// 遍歷注冊(cè)全局組件
components.map(component => Vue.component(component.name, component))
}
// 判斷是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 導(dǎo)出的對(duì)象必須具有 install,才能被 Vue.use() 方法安裝
install,
// 以下是具體的組件列表
...components
}
本地測(cè)試組件
我們的組件以及編寫完成芹敌,第一步先在本地進(jìn)行測(cè)試:
examples/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 導(dǎo)入組件庫
import datePicker from './../packages/index'
import './../packages/theme-default/src/test.scss'
// 注冊(cè)組件庫
Vue.use(datePicker)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
examples/views/home.vue
<template>
<div class="home">
<datePicker></datePicker>
</div>
</template>
<script>
export default {
name: 'home'
}
</script>
如何在瀏覽器中就可以看到我們的組件運(yùn)行成功了痊远,下一步就是要將我們的代碼打包成npm庫了,那么需要通過vue-cli3中vue-cli-service的庫模式進(jìn)行打包氏捞。
庫模式打包
# package.json
"script": {
"build-lib": "vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js && npm run build-theme",
}
庫模式的介紹:點(diǎn)擊這里
執(zhí)行:
npm run build-lib
項(xiàng)目的根目錄新增了lib文件夾碧聪,內(nèi)容如下
其中:
- lib/frog-ui.common.js:一個(gè)給打包器用的 CommonJS 包
- lib/frog-ui.umd.js:一個(gè)直接給瀏覽器或 AMD loader 使用的 UMD 包
- lib/frog-ui.umd.min.js:壓縮后的 UMD 構(gòu)建版本
修改package.json
修改packages.json,目前我的項(xiàng)目的完整package.json如下:
{
"name": "frog-ui",
"version": "0.1.0",
"private": false,
"lisence": "MIT",
"main": "lib/frog-ui.umd.min.js",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-lib": "vue-cli-service build --target lib --name frog-ui --dest lib packages/index.js && npm run build-theme",
"build-theme": "gulp build --gulpfile packages/theme-default/gulpfile.js && cp-cli packages/theme-default/lib lib/theme-default",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^2.6.5",
"vue": "^2.6.10",
"vue-router": "^3.0.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.7.0",
"@vue/cli-service": "^3.7.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"cp-cli": "^2.0.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^6.1.0",
"gulp-cssmin": "^0.2.0",
"gulp-sass": "^4.0.2",
"markdown-it-anchor": "^5.0.2",
"markdown-it-container": "^2.0.0",
"markdown-it-decorate": "^1.2.2",
"markdown-it-task-checkbox": "^1.0.6",
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
"vue-markdown-loader": "^2.4.1",
"vue-template-compiler": "^2.5.21"
}
}
主要要修改的是:
{
"private": false, // 是否私有,必須指定為false才能發(fā)布到npm
"main": "lib/frog-ui.umd.min.js", // 編譯后包的入口文件
}
根目錄添加.npmignore文件
發(fā)布到npm下液茎,只需要lib目錄矾削、package.json 和readme.md文件,所以需要忽略掉其他的目錄
.npmignore
examples/
packages/
public/
vue.config.js
postcss.config.js
babel.config.js
*.map
發(fā)布npm
# 設(shè)置要發(fā)布的源,我發(fā)布的是通過verdaccio搭建的私庫
npm config set registry http://registry.npmjs.org
# 登錄
npm login
# 發(fā)布
npm publish
下圖可以看到豁护,我們的包發(fā)布成功了哼凯,關(guān)于私庫的搭建可以查看我另外的文章。
總結(jié)
整個(gè)過程有一點(diǎn)點(diǎn)繁瑣楚里,但是能學(xué)到一些意外的知識(shí)断部,希望大家能夠動(dòng)手嘗試。能力有限班缎,文章中有寫得不對(duì)的地方請(qǐng)大家見諒蝴光。如果對(duì)你有幫助的話,可以幫忙點(diǎn)個(gè)贊哦 ~