前言
在使用 Vue 进行日常开发时, 我们经常会用到一些开源的 UI 库, 如: Element-UI, Vuetify 等.
只需一行命令, 即可方便的将这些库引入我们当前的项目:
npm install vuetify
// or
yarn add vuetify
但是当我们自己开发了一个 UI Component, 需要在多个项目中使用的时候呢? 我们首先想到的可能是直接复制一份过去对吗?
这样做是很方便, 但是有两个问题:
- 当该 component 需要更新时, 我们需要手动维护所有用到该 component 的更新
- 当有多个 component 需要共享时, 手动复制过于繁琐 那么, 我们为什么不发布一个 UI 组件库给自己用呢?
本文将介绍如何一步步, 创建并发布自己的 Vue UI 组件库。组件库的内容比较简单主要是熟悉流程。
安装 @vue/cli
npm install -g @vue/cli-service-global
创建一个 vue 新项目
运行下面的命令,引导选择安装模板,自动生成了项目目录及文件,也可以通过vue ui 去界面形式去创建项目。
vue create component-test
创建组件文件
src/componnets/input/index.vue
<template>
<div class="about">
<input :type="typeInput" @change="inputChange" />
</div>
</template>
<script>
export default {
props: {
typeInput: String
},
methods: {
inputChange(val) {
this.$emit("change", val);
}
}
};
</script>
首先我们编辑入口文件 src/components/index.js, 使其被作为 UI 库导入时能自动在Vue中注册我们的 Component:
import Vue from "vue";
import Input from "./input/index.vue";
const Components = {
Input
};
Object.keys(Components).forEach(name => {
Vue.component(name, Components[name]);
});
export default Components;
package.json 构建
主要的就是修改字段
- name
- main // 指定该属性后, 当我们引用该组件库时, 会默认加载 main 中指定的文件
- files
- scripts:{ "build-bundle": "vue-cli-service build --target lib --name component-test ./src/components/index.js" }
--target lib 把组件打包成lib 包,生成commonjs 的包,umd.js文件的包
--name component-test 打出包的名称 ./src/components/index.js 打包的入口文件
{
"name": "@username/component-test", // username 为用户在npm 官网注册的账号用户名
"version": "0.1.0",
"private": false, // 是否私有包
"main": "./dist/main.common.js", // 入口文件
"files": [ // 对外可见的文件夹
"dist/*",
"src/*",
"public/*",
"*.json",
"*.js"
],
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
// 打包构建的文件 --target lib --name component-test ./src/components/index.js
"build-bundle": "vue-cli-service build --target lib --name component-test ./src/components/index.js"
},
"dependencies": {
"core-js": "^3.6.5",
"user": "0.0.0",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
运行 npm run build-bundle 打包
可以看到 build 生成了各种版本可以用于发布的js文件
注册npm
1.官网注册
https://www.npmjs.com/signup
2.命令行注册
npm add user //按照提示输入用户名,邮箱等即可
3.注册后登陆
npm login //按照提示输入用户名,密码,邮箱等即可
4.登陆后查看登陆状态(可忽略)
npm whoami
发布代码到npm上
npm publish --access public
登陆npm官网查看发布代码(UI组件库创建完成)
个人头像->profile settings->package
测试组件(新建/已有项目中安装)
1.安装
npm install --save @username/component-name //@npm官网注册username/组件项目名 == @username/component-name
2.引用在项目总入口中(找到src/main.js)文件
import '@username/component-name'
3.引用在页面中
<template>
<input :typeInput="type" @change="changeInput"/>
</template>
<script>
export default {
data() {
return {
typeInput: 'text'
}
},
methods: {
changeInput(val) {
console.log(val)
},
}
}
</script>
遇到的问题
1、npm add user 安装完成后,运行npm login 登录不成功,是因为我的nrm 源没有切回来
重新设置源为官方npm 源地址
npm config set registry https://registry.npmjs.org/
后续优化 组件包自动引入
优化组件包自动引入
如果有很多的组件新建,则每个组件都需要重新导入到 src/components/index.js 中,例如下面:
import Vue from "vue";
import xieInput from "./input/index.vue";
// 新增
import xieButton from "./button/index.vue";
const Components = {
xieInput,
// 新增
xieButton
};
Object.keys(Components).forEach(name => {
Vue.component(name, Components[name]);
});
export default Components;
为了解决这个频繁修改的问题,我们用 webpack 的 require.context() 创建执行上下文环境。
修改 src/components/index.js
// webpack require.context 创建上下文环境
const req = require.context('./', true, /^.*\.vue/)
const componentsName = req.keys()
const components = componentsName.reduce((components, module) => {
const mod = req(module)
// 自定义获取项目规则
const moduleNameReg = /\.\/(\w*)\/index\.vue/ig
// 处理对应的模块关系
// {
// 'xieInput': mod.default
// }
module.replace(moduleNameReg, function ($0, $1) {
var nameList = $1.split('')
nameList[0] = nameList[0].toUpperCase()
const newName = nameList.join("")
components['xie' + newName] = mod.default
})
return components
}, {})
export { components }
执行 yarn build-bundle, 生成最新的 components-test.common.js 文件
执行 npm link 把@username/components-test 包映射到 本地node_modules 中
C:\Program Files\nodejs\node_modules\@username\component-test -> D:\component-test
在需要引入 @xiejunmei/component-test 项目中 执行 npm link @username/component-test
修改项目src/main.js 引入组件
import Vue from 'vue'
import App from './App.vue'
// 导入文件
import { components } from '@username/component-test'
Vue.config.productionTip = false
// 注入组件
Object.keys(components).forEach(name => {
Vue.component(name, components[name]);
});
new Vue({
render: h => h(App),
}).$mount('#app')
完成项目改造,测试项目 执行 yarn serve 开启本地开发
项目完成后可以执行取消软链接
npm unlink @xiejunmei/component-test
查看是否已删除,执行如下命令
npm ls --global @xiejunmei/component-test
显示了对应的地址,说明没删除成功,再去目录下删除一下即可
C:\Program Files\nodejs
`-- @xiejunmei/component-test@0.1.1 -> D:\component-test
因为我是nvm 下载的node 版本,删除 node 下的node_modules包中的@xiejunmei 文件夹即可。如下:
C:\Users\xjm\AppData\Roaming\nvm\v14.17.0\node_modules
参考文章: 原文链接:blog.csdn.net/baidu_25464…