创建, 发布自己的 Vue UI 组件库

1,227 阅读2分钟

前言

在使用 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文件

2.png

注册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.jpg

测试组件(新建/已有项目中安装)

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 开启本地开发

3.jpg

项目完成后可以执行取消软链接

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…