前言
在前端开发中,除了常用的UI组件库以外,我们还会涉及到基于公司业务,需要定制化开发一些业务组件,还有随着项目的增多,开发人员的增多,为了提高工作效率,我们就需要统一管理好已开发好的业务组件。这时候我们就需要搭建自己的组件库,因为涉及到一些公司的业务,我们只能发布到私服的npm上。下面几点是我们需要做的几个内容:
1、项目搭建以及UI或者业务组件的开发
2、组件的打包
3、搭建私服npm
4、发布组件至私服npm
5、搭建组件库文档
(注:这里用到的 npm版本6.14.15,node版本v14.18.3)
一、项目搭建以及UI或者业务组件的开发
1、搭建vue2项目
vue create demo-ui
2、项目基本结构
在项目的根目录新建 components 文件夹
3、修改vue.config.js
新增pages,修改入口配置,如下:
//vue.config.js const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, pages:{ index:{ entry:'src/main.js', template:'public/index.html', filename:'index.html' } }, })
4、components文件夹设计
- 建立css文件夹和lib文件夹
- css文件夹用于存放样式文件
这里使用到了sass,所以我们需要先安装好sass
cnpm i sass [email protected] [email protected]
新建样式表,如下:
- lib文件夹用于存放各个组件,并建立主index.js导出全部组件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// lib/index.js import Demo from './demo'; import Card from './card'; const components = { Demo, Card } const install = function(Vue){ if(install.installed) return; Object.keys(components).forEach(key =>{ Vue.component(components[key].name,components[key]) }) } const API = { install } export default API; export { Demo, Card }View Code
5、组件开发
一个组件是独立的一个文件夹,在components/lib下建立相应文件夹,以card为例:
建立card/src/main.vue和card/index.js两个文件,
card目录如下:
/components/lib/card/main.vue内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<template> <div class="m-card" :style="width ? {width: width + 'px'} : {}"> <div class="m-card-img" :style="imgHeight? {height:imgHeight+'px'}:{}"> <img :src="imgSrc" alt="img" /> </div> <div class="m-card-summary" v-if="summary"> {{summary}} </div> <div v-else class="m-card-summary"> <slot></slot> </div> <slot name="footer"></slot> </div> </template> <script> export default { name:'m-card', props: { width: { //卡片宽度 type:Number, default:0 }, imgSrc: { //卡片图片资源 type:String, default:'' }, imgHeight: { //图片高度 type:Number, default:0 }, summary: { //卡片概要 type:String, default:'' }, } } </script> <style> </style>View Code
components/lib/card/index.js内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import Card from './src/main.vue' Card.install = function(Vue) { Vue.component(Card.name,Card) } export default CardView Code
main.js中引入
import Vue from 'vue' import App from './App.vue' import '../components/css/card.scss' import Card from '../components/lib/card/index' Vue.use(Card) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')
6、App.vue中使用卡片组件
App.vue内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<template> <div id="app"> <m-card imgSrc="logo.png" summary="这是一个自定义组件" > <template v-slot:footer> <div class="footer"> <div class="left">哈哈哈哈</div> <div class="right">嘿嘿嘿嘿</div> </div> </template> </m-card> </div> </template> <script> export default { name: 'App', components: { } } </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> <template> <div id="app"> <m-card imgSrc="logo.png" summary="这是一个自定义组件" > <template v-slot:footer> <div class="footer"> <div class="left">哈哈哈哈</div> <div class="right">嘿嘿嘿嘿</div> </div> </template> </m-card> </div> </template> <script> export default { name: 'App', components: { } } </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>View Code
执行npm run serve
启动vue项目,查看组件效果,卡片正常显示:
(注:这里只是展示了card的组件,另一个组件demo组件请自行增加,如果没有内容,不需要导出,请删除,否则会报错)。
二、组件库打包
打包有两种方式
方式一:(webpack、gulp)
这里使用到的是 webpack和gulp
1、根目录下创建webpack.components.js,内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const path = require('path') const { VueLoaderPlugin } = require('vue-loader') const glob = require('glob') const list = {} async function makeList(dirPath,list){ const files = glob.sync(`${dirPath}/**/index.js`) for(let file of files) { const component = file.split(/[/.]/)[2] list[component] = `./${file}` } } makeList('components/lib',list) module.exports = { entry:list, mode:'development', output: { filename:'[name].umd.js', path:path.resolve(__dirname,'dist'), library:'rui', libraryTarget:'umd' }, plugins: [ new VueLoaderPlugin() ], module:{ rules: [ { test:/\.vue$/, use: [ { loader: 'vue-loader' } ] }, {test:/\.css$/, use: ['css-loader']}, {test:/\.scss$/, use: ['css-loader','sass-loader',]}, {test:/\.(jpg|png|gif|bmp|jpeg)$/, loader: 'url-loader'}, {test:/\.(ttf|eot|svg|woff|woff2)$/,use: 'url-loader'} ] } }View Code
2、package.json中添加打包命令
"build:js": "webpack --config ./webpack.components.js"
3、执行打包命令,将js打包为umd模块
npm run build:js
执行后如果提示需要安装webpack-cli,yes安装即可。
4、查看js打包结果
index.umd.js提供整个组件库的引入使用;
card.umd.js和demo.umd.js可提供组件库的按需引入。
如果webpack打包js报错如下:
请分别安装 :
npm i [email protected]
npm i [email protected] (这里的版本必要要跟vue的版本一致)
5、gulp打包css文件
- 根目录新建gulpfile.js
安装相关依赖:
npm install gulp gulp-sass gulp-minify-css
//gulpfile.js const gulp = require('gulp'); const sass = require('gulp-sass')( require ( 'sass' ) ) //sass转成css const minifyCSS = require('gulp-minify-css') //压缩 gulp.task('sass',async function(){ return gulp.src('components/css/**/*.scss') .pipe(sass()) .pipe(minifyCSS()) .pipe(gulp.dest('dist/css')) })
- package.json添加打包命令
"build:css": "npx gulp sass"
- 执行打包命令,将css打包
npm run build:css
如果打包报错如下:
请先执行 npm uni sass 删除sass。
然后再执行 npm i sass 重新安装sass。
- 查看css打包结果
/dist/css下已生成css文件
- 整合js和css的打包命令
"build": "npm run build:js && npm run build:css"
执行npm run build
,一键打包js和css文件
打包成功如下:
方式二:
这种方式,只需要在package.json中加上如下内容:
"lib": "vue-cli-service build --target lib --name awsui --dest dist ./components/lib/index.js"
注:方式一和方式二在组件的引用方面没有区别,区别在于css的,第一种方式可以按钮引入组件样式,第二种方式只能全局引用组件的样式。
三、搭建私服npm
我们这里使用verdaccio搭建npm私服,发布组件库。verdaccio官方文档
(以下效果是我在本地电脑上安装的,没有在远程服务器上)
1、安装和配置
安装:
npm install -g verdaccio
启动:
verdaccio
这里要注意第一行打印的信息,这个yaml文件就是verdaccio的配置文件,后面我们需要修改该文件进行相关配置。
2、启动成功后,直接在浏览器输入服务器的ip地址 + 最后一行打印出的端口号,看到这样的页面就说明安装成功了。如果访问不了可能是因为服务器防火墙没关,可以检查下防火墙。
3、修改配置文件 config.yaml
用记事本打开config.yaml,修改两个位置:
- 把listen改成自己的域名地址,
ax_users
设为 -1,禁止注册用户,一般情况下都应该由管理员派发账号,禁用后再添加用户会直接报错
禁用后我们可以通过这个网站 添加账号密码,然后分发给对应的人
把生成的密码复制出来,添加到htpasswd文件中即可
四、发布组件至私服npm
1、package.json文件修改
{ "name": "demo-ui", "version": "0.1.0", "private": false, //这里要设置成false "description": "demo-ui自定义组件", "main": "./dist/index.umd.js", //指定入口文件 "keywords": [ // 关键字,方便搜索 "vue", "typescript", "aws-ui", "awsui", "element-ui" ], "author": "zyf", //作者 "files": [ //指定发布的文件目录 "dist", "components" ], "scripts": { "serve": "vue-cli-service serve", "build": "npm run build:js && npm run build:css", "lint": "vue-cli-service lint", "build:js": "webpack --config ./webpack.components.js", "build:css": "npx gulp sass", "lib": "vue-cli-service build --target lib --name awsui --dest dist ./components/lib/index.js" }, "dependencies": { "core-js": "^3.8.3", "gulp": "^4.0.2", "gulp-minify-css": "^1.2.4", "gulp-sass": "^5.1.0", "sass": "^1.60.0", "vue": "^2.6.14", "vue-loader": "^15.9.8", "webpack-cli": "^5.0.1" }, "devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-service": "~5.0.0", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "node-sass": "^4.14.1", "sass-loader": "^8.0.2", "vue-template-compiler": "^2.7.14" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "eslint:recommended" ], "parserOptions": { "parser": "@babel/eslint-parser" }, "rules": {} }, "browserslist": [ "> 1%", "last 2 versions", "not dead" ] }
2、安装nrm并切换npm源到我们私有的仓库地址
这里我使用到了nrm来管理npm registry
npm install -g nrm
// 添加自定义的源 源就是启动verdaccio时打印出来的地址 nrm add demo-ui http://10.0.0.159:8080/ // 查看所有可用的源 nrm ls // 切换源到我们的私有仓库 nrm use demo-ui
确定已用nrm把源切换到我们的仓库
3、如果没有创建账户的,可以先创建账户
npm adduser --registry http://10.0.0.159:8888/
4、然后发布包
npm publish --registry http://10.0.0.159:8888/
发布成功后,再访问私有仓库地址,就会发现自己的包已经发上去了。
5、具体使用方式
在项目中需要先安装好依赖(记得先用rem切换到私有npm源):
npm i demo-ui
在main.js中,示例如下:
//全局引用 import AwsUI from 'demo-ui'; import 'demo-ui/dist/css/index.css'; Vue.use(AwsUI) //按需引用 import {Card,Demo} from 'demo-ui'; import 'demo-ui/dist/css/card.css'; Vue.use(Card).use(Demo)
标签:npm,vue,sass,js,从零开始,vue2,组件,完整版,css From: https://www.cnblogs.com/zyfenblog/p/17292547.html