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項目,這個項目將會是我們的組件項目了。
目錄結構構建
在我們日常開發(fā)的項目中,通常的目錄結構可能會像下圖,我們一般會在根目錄下的src/views中進行我們所有頁面的開發(fā),App.vue作為主頁面引入。
但是呢,我們現在是想要進行組件開發(fā),那么在項目的目錄結構上可根據個人習慣進行一定的調整和更改如下:
這里我說明一下主要的目錄
- components:存放你所需要開發(fā)的所有組件的目錄
- components/lib:存放組件源碼
- components/css:存放可能需要用到的css樣式(自定義)
- components/lib/xxx/index.js:將組件注冊魏全局組件
- examples:最初項目的src,我們可以一邊開發(fā)一邊調試
注意:更改上述目錄之后,配置文件也需要進行相應的改變,因為在webpack中,默認以sec/main.js作為入口文件,現我們已將scr->example,所以入口文件應該進行相應的修改
組件開發(fā)
這里以Loading組件為例,
- components/lib/Loading/src/Loading.vue:組件源碼
- components/lib/Loading/src/index.js:單個注冊全局組件
- components/css/loading.scss:存放Loading組件的樣式(這里使用的是scss方式,后面關于打包會提到)
- 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 Loading
components/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; } /*自定義動畫類----順時針旋轉(使用這個動畫的時候才設置動畫執(zhí)行時間)*/ @keyframes rotatingright { transform-origin: 50% 50%; 0% { transform: rotate(0deg); } 50% { transform: rotate(180deg); } 100% { transform: rotate(360deg); } } /*自定義動畫類----逆時針旋轉(使用這個動畫的時候才設置動畫執(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,圖片,則還需要對這些文件進行額外處理
主要配置如下(其中有相關的注釋,有興趣可以自行查看)
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', // 使用內置的asset模塊處理資源文件 generator: { filename: 'images/[name][ext]', // 輸出的文件名格式 }, }, ], }, }
ps:對于組件中使用的scss文件的處理,這里用到的是gulp,具體設置如下:
新建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代碼轉換成css代碼 .pipe(minifyCSS())// 壓縮css代碼 .pipe(gulp.dest('dist/css'))// 輸出到打包目錄 })
接下來就是新增打包命令:
在package.json文件中
最后的打包文件如下:
上傳npm
修改package.json文件
在上傳npm之前呢,我們有必要對這個組件庫信息進行相應的配置,因為npm上發(fā)布的包是根據package.json的文件進行匹配的,所以,進行如下信息修改,一般指定如下信息
- 刪除私有屬性private
- description:描述
- main:入口文件
- keywords:關鍵字(方便用戶搜索)
- 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
引入&&使用
頁面
擴展
我在這個的基礎上封裝了另外一個組件vue2-edit-cron,主要是可以快速構建cron表達式,有興趣也可以看看~:vue2-edit-cron - npm (npmjs.com)
總結
該文組件封裝的方式其實是打包發(fā)布的方式,這種方式是將裝好的組件最終打包成一個或者多個js文件發(fā)布。這種方式使得開發(fā)和調試時更接近于一個前端項目。但是一旦引入圖片等靜態(tài)資源需要同個BASE64的方式打包到js,而對于字體一類較大的靜態(tài)資源則根本無法引用
適用范圍:沒有或極少的依賴第三方插件、圖片的組件的封裝或JS方法的封裝
后面經過了解知道,其實還有另外一種方式即,非打包方式,具體的對比如下:
打包發(fā)布 | 非打包發(fā)布 | |
---|---|---|
webpack | 需要配置 | 無需配置 |
發(fā)布 | 發(fā)布前需要打包 | 發(fā)布前無需打包 |
引用靜態(tài)文件 | 較小的圖片可以通過BASE64方式打包僅js文件 | 隨意使用 |
引用第三方依賴 | 可以引用,但如果第三方依賴包含較多的靜態(tài)文件時可能會出現引用不到的情況 | 隨意引用 |
被應用的文件 | 一個打包好的js | 組件的入口文件 |
調試方法 | 在組件項目中即可調試 | 需要在引用組件的項目中的node_module中對用模塊中調試 |
以上就是Vue封裝組件并上傳到npm的教程詳解的詳細內容,更多關于Vue封裝組件上傳到npm的資料請關注腳本之家其它相關文章!
相關文章
解決Idea、WebStorm下使用Vue cli腳手架項目無法使用Webpack別名的問題
這篇文章主要介紹了解決Idea、WebStorm下使用Vue cli腳手架項目無法使用Webpack別名的問題,需要的朋友可以參考下2019-10-10