Vue封裝組件并上傳到npm的教程詳解
環(huán)境準備
1.注冊npm賬號:npm | Home (npmjs.com)
2.保證當前環(huán)境安裝了vue、webpack、node,以下工作將在該環(huán)境下進行(沒有的小伙伴自行百度安裝哈~)
3.一下用到的環(huán)境版本
- webpack:v5.1.4
- node:v12.10.0
- vue:v2.6.14
4.創(chuàng)建一個基于webpack的vue項目,這個項目將會是我們的組件項目了。
目錄結(jié)構(gòu)構(gòu)建
在我們?nèi)粘i_發(fā)的項目中,通常的目錄結(jié)構(gòu)可能會像下圖,我們一般會在根目錄下的src/views中進行我們所有頁面的開發(fā),App.vue作為主頁面引入。

但是呢,我們現(xiàn)在是想要進行組件開發(fā),那么在項目的目錄結(jié)構(gòu)上可根據(jù)個人習慣進行一定的調(diào)整和更改如下:

這里我說明一下主要的目錄
- components:存放你所需要開發(fā)的所有組件的目錄
- components/lib:存放組件源碼
- components/css:存放可能需要用到的css樣式(自定義)
- components/lib/xxx/index.js:將組件注冊魏全局組件
- examples:最初項目的src,我們可以一邊開發(fā)一邊調(diào)試
注意:更改上述目錄之后,配置文件也需要進行相應(yīng)的改變,因為在webpack中,默認以sec/main.js作為入口文件,現(xiàn)我們已將scr->example,所以入口文件應(yīng)該進行相應(yīng)的修改


組件開發(fā)
這里以Loading組件為例,
- components/lib/Loading/src/Loading.vue:組件源碼
- components/lib/Loading/src/index.js:單個注冊全局組件
- components/css/loading.scss:存放Loading組件的樣式(這里使用的是scss方式,后面關(guān)于打包會提到)
- components/lib/index.js:所有組件的全局注冊
代碼實例如下:
components/lib/Loading/src/Loading.vue
<template>
<div class="beva-loading">
<img class="loading-icon" :src="imgSrc" alt="">
</div>
</template>
<script>
export default {
name: 'Loading',
props: {
imgSrc: {
type: String,
default: ''
},
},
data() {
return {}
}
}
</script>components/lib/Loading/src/index.js
import Loading from './src/Loading.vue'
Loading.install = function (Vue) {
Vue.component(Loading.name, Loading)
}
export default Loadingcomponents/css/loading.scss
.beva-loading {
background-color: rgba(0, 0, 0, 0.7);
border-radius: 0.4rem;
color: #ffffff;
position: fixed;
z-index: 99;
width: 7.46rem;
height: auto;
padding: 0.8rem;
text-align: center;
top: 20vh;
box-sizing: border-box;
margin-left: -3.73rem;
left: 50%;
}
.loading-icon {
width: 4rem;
height: 4rem;
animation: rotatingright 1s linear infinite;
}
/*自定義動畫類----順時針旋轉(zhuǎn)(使用這個動畫的時候才設(shè)置動畫執(zhí)行時間)*/
@keyframes rotatingright {
transform-origin: 50% 50%;
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}
/*自定義動畫類----逆時針旋轉(zhuǎn)(使用這個動畫的時候才設(shè)置動畫執(zhí)行時間)*/
@-webkit-keyframes rotatingleft {
0% {
-webkit-transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(-180deg);
}
100% {
-webkit-transform: rotate(-360deg);
}
}components/lib/index.js
// 將組件庫中定義的所有組件引進來,然后再導出
import Demo from './demo';
import Card from './card';
import Loading from './Loading';
const components = {
Demo,
Card,
Loading
}
const install = function (Vue) {
// 判斷是否安裝,安裝過就不繼續(xù)往下執(zhí)行
if (install.installed) return
Object.keys(components).forEach(component => {
Vue.component(components[component].name, components[component])
})
}
export default {
install
}新建webpack.components.js文件,其中主要是對組件打包的配置
1.對打包輸出的文件進行處理
2.如果用到了scss、css,圖片,則還需要對這些文件進行額外處理
主要配置如下(其中有相關(guān)的注釋,有興趣可以自行查看)
const { VueLoaderPlugin } = require('vue-loader');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const glob = require('glob')
const path = require('path')
const list = {}// 動態(tài)導入多個組件的入口文件
// 封裝組件的一些配置,因為組件打包是單獨打包的,所以需要單獨配置
async function makeList (dirPath, list) {
// 拿到所有的入口文件的路徑
const files = await glob.sync(`${dirPath}/**/index.js`)//[ 'components/lib/button/index.js', 'components/lib/icon/index.js']
// 取出上一級目錄的文件名
files.forEach(file => {
let name = file.split('/')[2]
// 判斷name是否有后綴名,有的話去除
if (name.includes('.')) {
name = name.split('.')[0]
}
list[name] = `./${file}`
})
// console.log(list)
}
makeList('components/lib', list)
module.exports = {
entry: list,
mode:'development',
output: {
filename: '[name].umd.js',// webpack打包的時候會將name替換成入口的name名字,例如card.umd.js
path: path.resolve(__dirname, 'dist'),
library:'mui',
libraryTarget: 'umd',// 指定輸出格式,umd是一種模塊,兼容了CommonJS、AMD、CMD
},
plugins: [
new VueLoaderPlugin(),
new CleanWebpackPlugin()
],
module: {
// 配置rules,即什么樣的文件,使用什么樣的loader
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
}
]
},
{
test: /\.css$/,
use: ['style-loader','css-loader']
},// 這里只處理了css,而項目中組件中使用了scss文件,對于scss文件的處理這里使用的是gulp,下面會提到
{
test: /\.(png|jpg|gif|svg)$/i, // 匹配圖片文件格式
type: 'asset/resource', // 使用內(nèi)置的asset模塊處理資源文件
generator: {
filename: 'images/[name][ext]', // 輸出的文件名格式
},
},
],
},
}
ps:對于組件中使用的scss文件的處理,這里用到的是gulp,具體設(shè)置如下:
新建gulpfile.js,對css文件單獨打包(下方用到的第三方依賴需要自定下載)
const gulp = require('gulp');
// 需要把樣式代碼導入
const sass = require('gulp-sass')(require('sass'));
// 對css代碼進行壓縮
const minifyCSS = require('gulp-minify-css');
gulp.task('sass', async function () {
return gulp.src('components/css/**/*.scss')
.pipe(sass())// 將scss代碼轉(zhuǎn)換成css代碼
.pipe(minifyCSS())// 壓縮css代碼
.pipe(gulp.dest('dist/css'))// 輸出到打包目錄
})接下來就是新增打包命令:
在package.json文件中

最后的打包文件如下:

上傳npm
修改package.json文件
在上傳npm之前呢,我們有必要對這個組件庫信息進行相應(yīng)的配置,因為npm上發(fā)布的包是根據(jù)package.json的文件進行匹配的,所以,進行如下信息修改,一般指定如下信息
- 刪除私有屬性private
- description:描述
- main:入口文件
- keywords:關(guān)鍵字(方便用戶搜索)
- author:作者信息
- files:望發(fā)布的文件目錄(不需要將所有文件都上傳到npm中)
距離如下:

添加md文件

打包&&發(fā)布
由于這里封裝組件的方式是打包發(fā)布的方式,所以切記在發(fā)布之前進行打包,生成dist文件!
維護版本
手動修改package.json中的version或者執(zhí)行npm version patch生成迭代一個版本
執(zhí)行打包命令
npm run build
登陸npm
注意這一需要登陸官方倉庫,如果之前連接的是淘寶鏡像需要線切換回來。下面是查看倉庫源和切換倉庫的命令。
npm config get registry // 查看倉庫源
npm config set registry https://registry.npm.taobao.org
npm config set registry http://registry.npmjs.org
登陸npm,輸入賬號、密碼、郵箱
npm login
發(fā)布
npm publish


測試組件
安裝
npm i vue-library-ui
引入&&使用

頁面

擴展
我在這個的基礎(chǔ)上封裝了另外一個組件vue2-edit-cron,主要是可以快速構(gòu)建cron表達式,有興趣也可以看看~:vue2-edit-cron - npm (npmjs.com)

總結(jié)
該文組件封裝的方式其實是打包發(fā)布的方式,這種方式是將裝好的組件最終打包成一個或者多個js文件發(fā)布。這種方式使得開發(fā)和調(diào)試時更接近于一個前端項目。但是一旦引入圖片等靜態(tài)資源需要同個BASE64的方式打包到j(luò)s,而對于字體一類較大的靜態(tài)資源則根本無法引用
適用范圍:沒有或極少的依賴第三方插件、圖片的組件的封裝或JS方法的封裝
后面經(jīng)過了解知道,其實還有另外一種方式即,非打包方式,具體的對比如下:
| 打包發(fā)布 | 非打包發(fā)布 | |
|---|---|---|
| webpack | 需要配置 | 無需配置 |
| 發(fā)布 | 發(fā)布前需要打包 | 發(fā)布前無需打包 |
| 引用靜態(tài)文件 | 較小的圖片可以通過BASE64方式打包僅js文件 | 隨意使用 |
| 引用第三方依賴 | 可以引用,但如果第三方依賴包含較多的靜態(tài)文件時可能會出現(xiàn)引用不到的情況 | 隨意引用 |
| 被應(yīng)用的文件 | 一個打包好的js | 組件的入口文件 |
| 調(diào)試方法 | 在組件項目中即可調(diào)試 | 需要在引用組件的項目中的node_module中對用模塊中調(diào)試 |
以上就是Vue封裝組件并上傳到npm的教程詳解的詳細內(nèi)容,更多關(guān)于Vue封裝組件上傳到npm的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決Idea、WebStorm下使用Vue cli腳手架項目無法使用Webpack別名的問題
這篇文章主要介紹了解決Idea、WebStorm下使用Vue cli腳手架項目無法使用Webpack別名的問題,需要的朋友可以參考下2019-10-10
Vue.js每天必學之內(nèi)部響應(yīng)式原理探究
Vue.js每天必學之內(nèi)部響應(yīng)式原理探究,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
vue如何從后臺獲取數(shù)據(jù)生成動態(tài)菜單列表
這篇文章主要介紹了vue如何從后臺獲取數(shù)據(jù)生成動態(tài)菜單列表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04

