前言:
问题抛出:在拥有了一系列自己开发的组件后,如何将它们整合到一个包里,像 element-UI 一样方便地使用?又如何将自己的组件开源分享?还是习惯性地用 github 吗?
这里以一个简单的 h1 标签组件为例,让我们看看它是如何经历这个奇妙的旅程,从二次元降落到我们的 “V”头上的(文章末尾附测试源码链接)
- 环境准备
- 组件开发及导入导出处理
- NPM包的发布
- 包的使用
先来看看效果叭!从熟悉的界面开始......
1、环境准备
我们写的是 Vue 组件库,所以使用的是 脚手架 vue-cli 4.5.0 版本(大于2.9.0版本)快速搭建项目,新版脚手架自带的 UI 操作界面非常好用,谁用谁知道。具体怎么用可以查看其他博客,这里我们搭建的是一个 UI 组件库,需要的依赖暂时很少,推荐先作如下配置
2、组件开发及导入导出处理
基础项目搭建完成,进入我们的开发阶段
关于项目目录结构
先看看该项目的初始整体结构吧(慢慢来,咱不犯错!)
再预览一下成果发布后的文件结构
关于组件
组件这一块的结构设计,参考了 element-UI 的源码,我们来看看
在根目录新建一个 plugins 文件夹,再建立它的子文件夹 components 文件夹(所有的组件都放这里),每个组件再分别建立自己的文件夹。
扩展:同时我们可以再 components 文件夹同级下建立我们封装的指令(directives )和过滤器(filters)等工具的文件夹
组件代码文件(testPart.vue):
<template>
<div>
<h1>HUOHUOIT</h1>
</div>
</template>
<script>
export default {
// 这里千万不能漏也不能写错了 name
name: 'testPart'
}
</script>
<style>
</style>
组件内部 JS 文件(index.js):用于实现按需导入功能
import testPart from './testPart.vue'
testPart.install = Vue => Vue.component(testPart.name, testPart)
export default testPart
组件系统下的 JS 文件 (index.js):全局注册并导出组件
import testPart from './components/testPart/index'
// 组件
const components = [testPart]
// 指令
// const directives = [xxxx]
// 过滤器
// const filters = [xxxx]
// 定义install方法,Vue作为参数
const install = Vue => {
// 判断是否安装,安装过就不用继续执行
if (install.installed) return
install.installed = true
// 遍历注册所有组件
components.map(component => Vue.component(component.name, component))
// 遍历注册所有指令
// directives.map(directives => Vue.use(directives))
// 遍历过滤器
// filters.map(filters => Vue.use(filters))
}
// 检测到Vue再执行
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
install,
// 所有组件,必须具有install方法才能使用Vue.use()
testPart
}
3、NPM包的发布
组件这一块这里不做详细讲解,处理完毕,我们开始NPM包的发布准备工作。
先关注一下 webpack 的打包:项目根目录下建立 vue.config.js 文件
const path = require('path')
module.exports = {
// 修改 pages 入口
pages: {
index: {
entry: 'src/main.js', // 入口
template: 'public/index.html', // 模板
filename: 'index.html' // 输出文件
}
},
// 扩展 webpack 配置
chainWebpack: config => {
// @ 默认指向 src 目录
// 新增一个 ~ 指向 plugins
config.resolve.alias
.set('~', path.resolve('plugins'))
// 把 plugins 加入编译,因为新增的文件默认是不被 webpack 处理的
config.module
.rule('js')
.include.add(/plugins/).end()
.use('babel')
.loader('babel-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}
打包发布前我们可以忽略一些不必要的文件(.gitignore文件处理):把包的一些测试文件过滤掉,最终打包只留下直接封装的文件,即 plugins 中封装的暴露组件
src/
plugins/
public/
.editorconfig
.eslintrc.js
vue.config.js
babel.config.js
*.map
*.html
接下来是NPM发布的重点:packages.json配置修改
最终版一览(写了注释的都是新增或者修改项):
{
"name": "test-components", // 发布到 NPM 上的包名(注:包名重复会发布失败)
"version": "0.1.0", // 版本号(注:代码更新发布前需同步更新版本号,不然无法成功发布)
"description": "组件提交测试", // 关于包的描述(便于使用者快速了解包的相关信息)
"private": false, // 是否私有(注:这里要设为 false,才能发布到 NPM)
"author": "huohuo", // 作者名称
"license": "MIT", // 包遵循的开源协议(参考 element 设为 MIT)
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lib": "vue-cli-service build --target lib --name test-components -dest lib plugins/index.js" // --target lib:指定打包目录 --name testhuo-components:打包后文件名字 -dest lib :打包后文件夹名称 plugins/index.js:打包入口文件
},
"keywords": [ // 项目以及npm搜索关键词(注:影响你被搜索到的概率哦)
"huohuo的h1标题"
],
"main": "dist/test-components.umd.min.js", // 主文件入口(最重要,路径名不要填错了!!!)
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
......
}
发布前千万要记得先打包:npm run lib(我做这个例子的时候,后续增加组件进行测试,就是因为发布前没有重新打包,导致~~~~我明明每一步每个代码都正确,本地测试无误,发布后放到新项目里报组件未注册等错误。硬是发布了20多个版本才发现这个错误。emmmmmm.......痛苦)
最后:npm publish
注意可能出现的一个报错:
npm ERR! [no_perms] Private mode enable, only admin can publish this module [no_perms] Private mode enable, only admin can publish this module: wqui
这时候要把我们的淘宝镜像更改为如下,再 npm publish
npm config set registry http://registry.npmjs.org/
大功告成!!!
4、组件包的使用
First:下载安装
npm i test-components
second:引入项目中(项目的 main.js文件内)
import 了什么(这里的 testPart 可以自定义命名,代表引入整个UI库),就看你 export default 了哪些组件
如果你只想引入部分组件(按需导入,如 Button, Select)
import Vue from 'vue';
import { Button, Select } from 'test-components';
import App from './App.vue';
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
* Vue.use(Button)
* Vue.use(Select)
*/
Third:这里方便测试直接放在 App.vue 中啦!
5、其他
关于 npm 包发布的一些操作
废弃一个包:这是用户仍然可以下载安装此包,只是会提示用户~ <message>
npm deprecate <pkg>[@<version>] <message>
// npm deprecate test-components@0.1.0 '这个包包不要啦,我已经换新包包啦!'
删除一个包(彻底删除自己 npm 上发布的包):
npm unpublish 包名 --force
版本控制:
一个办法是改变在 packages.json 文件中的 version (新版本号要高于旧版本号),然后重新发布
也可以命令式改变:
npm version <update_type>
// 补丁:patch 小改:minor 大改:major
// npm version patch v0.1.0