前言(*❦ω❦)

思维导图可能有点高糊,有点太大了,项目和导图文件放到githubgiteee上,这个思维导图也是我文章的架构,思维导图是用FeHelper插件生成的,这个是一款开源chrome插件,访问地址按照插件项目说明安装即可,然后导入我的思维导图的JSON文件即可,JSON文件会放在项目中。
思维导图


构建vue npm 组件库需要准备的事(会的同学可跳过)( ゚▽゚)/

  这里主要讲一下搭建一个vue组件库需要事先准备的条件,其实也是一个合格的初级前端开发人员的必备条件。

  • 编辑器工具: VsCode下载地址
      首先是使用工具,个人推荐VsCode,因为感觉前端用这款软件太合适不过了,各种插件用得好完全可以起飞。

  • git环境: git安装可以网上查查资料,安装好边学边用就可以了,协同开发工具能用就可,需要深入再学不迟,只要了解分支开发等等基础内容就行了。然后配合github这个著名的交友网站(手动滑稽)就可以了,主要是用来保存自己的组件库代码,搭建组件库暂时还用不到,本地保存主要怕丢失了,所以云备份一份万无一失。

  • Node.js环境: 不会吧!不会吧!不会有人学前端还不知道Node.js吧, 好吧!其实我刚开始学也是不知道的,后面也是慢慢接触到,菜到自闭⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄,安装node环境主要是用npm包管理工具,npm真是前端人的灵魂。Node.js下载地址,安装相关可以参考这篇博客。安装完成后推荐安装nrm这个包,主要是用它换源贼方便,这里建议看看这篇博客(理直气壮夹带私货(。-`ω´-))。下图是我的node版本和npm版本:
      node版本

  • vue&vue-cli: Vue是前端一个渐进式框架,vue-cli是一个项目构建工具,这里主要是用cli来构建一个基础的组件库项目,具体的细节就不做过多解释了。

  • 注册npm一个账号: npm官网,注册账号就不用多说了吧,准备好一个邮箱,然后注册的时候记着注册名和密码,后面发布npm包会使用到。

  • 小小建议: 公司让我尝试搭建一个公用的组件库,主要是前端一些代码复用率高,能抽成组件可以减少冗余,刚开始也是一脸迷茫,翻阅不少博客后才完成基本的搭建流程,期间也有看过element源码,当然不可能是完全啃源码,主要是饿了么这么优秀的vue开源ui组件库不看看源码,怎么对得起天天使用它٩(๑❛ᴗ❛๑)۶。主要是借鉴一下,整个项目的文件构建结构,然后组件构建的流程,大致能顺一下流程。最后再搭建组件库的过程中也确实对我有一定的帮助,所以建议大家也看看源码。(o°ω°o)

开始搭建组件库ヾ(≧∇≦*)ヾ

创建项目&调整文件名

查看vue-cli版本

  搭建项目我使用的是 vue-cli的4+ 版本,node版本之前也有截图,cli最好是用 3+版本 。完成这些后,找一个保存项目的文件夹,然后使用cmd输入vue create xd-test-ui就可以创建名为xd-test-ui的项目了

vue-cli版本&创建

创建项目

  cmd输入vue create xd-test-ui后会来到这个页面,一路回车默认就可了,这里我选择vue2版本,剩下的是默认配置,是一些编译和拼写检测的配置,直接默认即可,如果想要深入了解,可以学习学习webpack,这些配置完成后就进入安装页面,等待项目创建完成。

  • 配置选项
       vue项目构建

  • 安装过程
       cli安装过程

  • 项目创建完成
      可以看到构建完成后,最后提示使用npm run serve运行,这是基础的vue-cli项目,当然这只是刚开始,完成组件库还需要进行进一步的"脱胎换骨"┐( ̄ヮ ̄)┌。项目初始样子完成后,使用VsCode从项目根目录打开该项目。
      

调整文件夹命名

  看了很多的博客,大家基本都是这个样子来修改的,包括element源码里面的项目,也是有examples文件夹(项目示例文件夹)和packages文件夹(组件文件夹),所以这里随大流,将创建好的项目修改成如下的格式。

·
··
...
|-- examples      // 原 src 目录,改成 examples 用作示例展示
|-- packages      // 新增 packages 用于编写存放组件
...
··
·
  • 修改文件名前后(src->examples,新增 packages)
    修改前
    修改后

项目配置调整

完成上述修改后,项目无法运行,需要调整配置,在 根目录 添加vue.config.js文件,配置代码如下,vue.config.jsvue-cli3新增提供的一个可选配置文件,相关的配置链式操作可以查看官网的这篇配置介绍 webpack-chain,完成这些配置后项目就可以重新运行了。

//vue.config.js文件
const path = require('path')
module.exports = {
    // 修改 pages 入口
    pages: {
        index: {
            entry: 'examples/main.js', // 入口
            template: 'public/index.html', // 模板
            filename: 'index.html' // 输出文件
        }
    },
    // 扩展 webpack 配置
    chainWebpack: config => {
        // @ 默认指向 src 目录,这里要改成 examples
        // 另外也可以新增一个 ~ 指向 packages
        config.resolve.alias
            .set('@', path.resolve('examples'))
            .set('~', path.resolve('packages'))
        // 把 packages 和 examples 加入编译,因为新增的文件默认是不被 webpack 处理的
        config.module
            .rule('js')
            .include.add(/packages/)
            .end()
            .include.add(/examples/)
            .end()
            .use('babel')
            .loader('babel-loader')
            .tap(options => {
                // 修改它的选项...
                return options
            })
    }
}

编写组件 φ(>ω<*)

组件目录构建

构建如下的文件目录格式,然后构建完成后就可以开始写代码了

|——
|——packages
|   |——index.js
|   |——button
|      |——index.js
|      |——src
|         |——button.vue
|——

项目整体样子
目前为止的目录截图。

组件代码编写

  • button.vue文件内容

  这里就是单个的组件文件,每个packages下的文件夹就是一个组件,这里是基础组件样式的编写。

<template>
  <div>
    <a :class="type">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <slot></slot>
    </a>
  </div>
</template>

<script>
export default {
  name: "XdButton",
  props: {
    type: {
      type: String,
      default: "primary",
    },
  },
};
</script>

<style scoped>
@import url("https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

a {
  position: relative;
  display: inline-block;
  padding: 25px 30px;
  margin: 40px 0;
  color: #03e9f4;
  text-decoration: none;
  text-transform: uppercase;
  transition: 0.5s;
  letter-spacing: 4px;
  overflow: hidden;
  margin-right: 50px;
}
a:hover {
  background: #03e9f4;
  color: #050801;
  box-shadow: 0 0 5px #03e9f4, 0 0 25px #03e9f4, 0 0 50px #03e9f4,
    0 0 200px #03e9f4;
  -webkit-box-reflect: below 1px linear-gradient(transparent, #0005);
}

.warning {
  filter: hue-rotate(300deg);
}

.success {
  filter: hue-rotate(240deg);
}

a span {
  position: absolute;
  display: block;
}
a span:nth-child(1) {
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #03e9f4);
  animation: animate1 1s linear infinite;
}
@keyframes animate1 {
  0% {
    left: -100%;
  }
  50%,
  100% {
    left: 100%;
  }
}
a span:nth-child(2) {
  top: -100%;
  right: 0;
  width: 2px;
  height: 100%;
  background: linear-gradient(180deg, transparent, #03e9f4);
  animation: animate2 1s linear infinite;
  animation-delay: 0.25s;
}
@keyframes animate2 {
  0% {
    top: -100%;
  }
  50%,
  100% {
    top: 100%;
  }
}
a span:nth-child(3) {
  bottom: 0;
  right: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(270deg, transparent, #03e9f4);
  animation: animate3 1s linear infinite;
  animation-delay: 0.5s;
}

@keyframes animate3 {
  0% {
    right: -100%;
  }
  50%,
  100% {
    right: 100%;
  }
}

a span:nth-child(4) {
  bottom: -100%;
  left: 0;
  width: 2px;
  height: 100%;
  background: linear-gradient(360deg, transparent, #03e9f4);
  animation: animate4 1s linear infinite;
  animation-delay: 0.75s;
}
@keyframes animate4 {
  0% {
    bottom: -100%;
  }
  50%,
  100% {
    bottom: 100%;
  }
}
</style>
  • button/index.js内容编写

  如果要暴露组件,还需在组件文件夹内编写向外暴露组件的js文件

// 导入组件,组件必须声明 name
import Button from './src/button'

// 为组件提供 install 安装方法,供按需引入
Button.install = (Vue) => {
    Vue.component(Button.name, Button)
}

// 默认导出组件
export default Button
  • packages/index.js文件编写

  在这里提供两种组件注册方式,一种是使用use全部引入,另一种是按需引入组件,使用方法和elemnet组件引用方法一样。目前只写了一种组件,所以两种引入的都一样。

import button from './button'
// 存储组件列表
const components = [
    button
]
/* 
  定义install 方法,接收Vue作为参数,如果使用use注册插件,则所有的组件都将被注册
*/
const install = (Vue) => {
    // 判断是否安装
    if (install.installed) { return }
    // 遍历所有组件
    components.map(item => {
        Vue.component(item.name, item)
    })
}

//判断Vue初始化
if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
}

export default {
    install,
    button
}

在组件库项目内引用组件(测试组件所用,可以跳过)

  在examples/main.js中全局注册组件,然后在examples/components/HelloWorld.vue文件中编写使用按钮组件。

  • main.js文件内容如下
import Vue from 'vue'
import App from './App.vue'

import XdUi from '../packages/index' //组件库项目内引入组件
Vue.use(XdUi); //全局注册组件

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
  • 在HelloWorld.vue中的代码如下
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <XdButton>default</XdButton>
    <xd-button type="primary">primary</xd-button>
    <xd-button type="warning">warning</xd-button>
    <xd-button type="success">success</xd-button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
};
</script>

这里我只是删除了一些组件库项目的默认内容,然后在这个页面中测试我编写的组件,在项目内测试,以防上传组件库后发现错误再折腾回来修改。

  • 组件引用效果截图

组件效果截图

组件打包

package.json文件编写

  • name: 包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。
  • version: 版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。
  • description: 描述。
  • main: 入口文件,该字段需指向我们最终编译后的包文件。
  • keyword:关键字,以空格分离希望用户最终搜索的词。
  • author:作者
  • private:是否私有,需要修改为 false 才能发布到 npm
  • license: 开源协议
    以下为参考设置
···
  "description": "基于Vue搭建的一个基础组件库。",
  "main": "lib/xd-ui.umd.min.js",
  "private": false,
  "license": "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 xd-test-ui --dest lib packages/index.js"
  },
···
  1. 编译为库的命令 lib 内容解析

    • vue-cli-service build 构建包的命令
    • –target: 构建目标,默认为应用模式。这里修改为 lib 启用库模式。
    • –name:指定编译后的组件文件名字。
    • –dest : 输出目录,修改为lib。
    • 最后一个参数为入口文件,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录。
  2. 打包后图示说明
    打包图示

打包命令:npm run lib

上传到npm官网 罒ω罒

  终于到了“鸡冻”人心的一步了,发布正式的npm包,然而到这里还需要在发布前做一些准备工作。

  1. 添加.npmignore文件

  上传到npm当然只需要一个构建好的lib和相关的几个文件就足够了,这样别人引入的时候体积小,也不用获取多余的文件,就像上传到github不需要node_modules文件夹一样,因为这些东西太大,而且没有必要上传,所以这里在根目录添加.npmignore文件,在里面写入忽略上传的文件夹和文件即可。

以下是参考配置:

# 这是复制 .gitignore 里面的
.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

# 以下是新增的
# 要忽略目录和指定文件
examples/
packages/
public/
vue.config.js
babel.config.js
*.map
*.html
  1. 登录到npm

    • 首先需要到 npm 上注册一个账号,注意验证邮箱,不然之后会发布不了。
    • 如果配置了淘宝镜像,先设置回npm镜像。
      • 在控台输入 npm config set registry http://registry.npmjs.org 切换源
      • 或者使用 nrm use npm 当然需要安装NRM,前面说过了。
    • 然后使用 npm login 登录,输入之前注册的信息。
      登录npm
    • 最后使用 npm publish 发布包,好耶!ヽ(゚∀゚)メ(゚∀゚)ノ 终于发布了第一个自己的包了。可以看到包的版本是0.1.0,后续再发布包需要修改成和历史不同的版本号。如果发布成功,npm会使用邮件通知你,可以在邮箱中查看到自己的发布包成功的消息。
      发布npm包
    • 登录到npm官网查看自己发布的包
      npm官网查看发布的包

到这一步我们就完成了整个基于vue的npm包发布的流程,完成了第一个组件库的搭建,如果你成功了,哦耶!恭喜你!!!如果没有成功可能是版本或者某些配置遗漏了,可以回过头去看看,或者 重新来一次ヽ(・ω・´メ)(不要打我)。到这里基本就完成了组件库的搭建,好累啊啊啊!!!

新建项目引入安装自己的npm包测试 ❥(ゝω・✿ฺ)

当然如果要完成整个流程,那肯定得新建项目测试一下自己的包是否能用。

  1. 构建新的项目 vue create 项目名

  2. 使用 npm i xd-test-ui 安装上传的npm包。
    上传的包安装

  3. 确认检查包是否安装了。

    确认包引入

  4. 在新项目中挂载下载好的组件。

import XdUi from "xd-test-ui" //引入组件
import "xd-test-ui/lib/xd-test-ui.css" //之前在组件库项目中没有引入,因为是一个项目,而新项目需要引入css文件才会有样式。
Vue.use(XdUi); //全局注册组件
  1. 在页面内编写引入的组件
<XdButton>默认</XdButton>
<xd-button type="primary">指定默认样式</xd-button>
<xd-button type="warning">警告样式</xd-button>
<xd-button type="success">成功样式</xd-button>
  1. 效果展示
    成功
    警告
    默认

好了,这里就万无一失的确认组件ok,引入没有问题,npm组件库完全的完成了,可喜可贺,可喜可贺!\\\٩(‘ω’)و////

项目地址✧⁺⸜(●˙▾˙●)⸝⁺✧

npm包地址

项目地址

在项目中使用 npm i xd-test-ui 引入,然后和上述的方法一样引入即可。

github仓库地址

项目地址

使用git clone https://github.com/ZERO-DG/xd-test-ui.git下载项目。求个Star

gitee仓库地址

项目地址

使用git clone https://gitee.com/zero-dg/xd-test-ui.git下载项目。

参考大佬的博客

大佬0001

大佬0002

大佬0003

大佬0004

以上大佬部分先后顺序,本博客有部分借鉴的地方,全部来自于以上博客,感谢各位大佬!

版权声明:本文为zero-dg原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zero-dg/p/14341676.html