从零搭建自己的UI组件库,部署到github,纯干货流程介绍,内含丰富表情包【手动狗头】

515 阅读7分钟

放弃幻想,轻装前进 微信搜索:OrzR3  关注一个有趣的灵魂

基本概念

Vue:一套用于构建用户界面的渐进式框架

a2655c2a0a514a92b8de1a75fc568c9a.jpeg

Vue组件:组件是可复用的Vue实例

682766c63c6b0c12ca3d9d46efbc18c7.jpeg

Vue组件库:基于Vue实现的,独立于业务的第三方UI库

elementUIant design

c48822c92065fdfeed82c1a945485657.jpeg

6894f6763baadc3b6b571600681f612e.jpeg

Vue组件库优点

提升开发效率,节省了时间成本和人力成本。

几乎所有大厂都会使用组件库,有的甚至会自己开发组件库。

譬如:

阿里巴巴 Ant Design 

饿了么    Element

fd649e9e4f5261e86ee5c387df720e81.jpeg

话休絮烦,言归正传。不要搞那么前端,直接开搞。

1,418文件.png

干货笔记,没那么多弯弯绕绕,直接开整。

3ea48733a3a73eee30908a13f90b2854.jpeg

开打!开打!

034242da23d872148e0aff69727d4e68.jpeg

干货笔记

流程介绍

1.通过Vue脚手架搭建vue项目

2.实现自定义组件

3.通过Webpack和Gulp打包

4.发布至npm

5.通过VuePress生成文档站点,部署到github

用脚手架生成vue项目

Vue CLI 官网介绍,传送门:

cli.vuejs.org/zh/guide/

安装

npm install -g @vue/cli
npm install -g @vue/cli

检测版本

vue --version

1.新建项目

创建项目

vue create hello-world

选择创建默认的vue2版本项目

2.修正项目结构

src文件夹下的 components 文件放到最外层

src文件夹,更名为 examples 

删除掉HelloWorld组件及其引用

main.js默认作为vue项目的入口文件,现在要改变项目的入口文件

新建vue.config.js文件,重新配置入口文件

vue.config.js 文件,代码如下:

module.exports = {
  pages: {
    index: {
      entry: 'examples/main.js',
      template: 'public/index.html',
      filename: 'index.html'
    }
  }
}

3.实现并跑通一个demo组件

clipboard.png

新增vue组件和css文件,结构如上图所示,并且在 main.js 中引入

import Vue from 'vue'
import App from './App.vue'

import '../components/css/demo.scss'
import Demo from  '../components/lib/demo/src/main.vue'
Vue.use(Demo);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

安装sass样式预加载处理器

npm i sass-loader -D

报错信息:

this.getOptions is not a function

文件822.png

解决方案:

sass版本太高,不兼容这个函数

卸载sass-loader

npm uninstall sass-loader -D

安装低版本的sas-loader

npm i sass-loader@5 -D

安装node-sass

npm i node-sass -D

在components/lib文件夹下,新建 index.js 文件

import Demo from './src/main.vue'

Demo.install = function (Vue) {
  Vue.component(Demo.name, Demo);
}

export default Demo;

App.vue中添加demo组件

<template>
  <div id="app">
    <Demo/>
  </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>

main.js 文件改为

import Vue from 'vue'
import App from './App.vue'

import '../components/css/demo.scss'
import Demo from '../components/lib/demo/index'
Vue.use(Demo);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

设计组件,编写html结构和样式代码

这个就不在此赘述了,看自己需要封装什么样的组件。 2,005文件.gif

通过Webpack和Gulp打包

打包使用webpack,打包js为umd模块

webpack官网,传送门

webpack.docschina.org/

概念

webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。

核心概念

入口(entry)

输出(output)

loader

插件(plugin)

模式(mode)

浏览器兼容性(browser compatibility)

环境(environment)

1,986文件.gif

详情请见官方文档,在此也不再一一赘述。

了解了webpack和配置文件所需的字段,接下来编写配置文件。

安装 vue-loader 到开发依赖中。

npm i vue-loader -D

vue-loader用来识别vue文件,并将它们转换为有效 模块。

因为,webpack 只能理解 JavaScriptJSON 文件,

这是 webpack 开箱可用的自带能力。

loaderwebpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。

新建一个 webpack.component.js 文件

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 output = file.split(/[/.]/)[2];
    list[output] = `./${file}`;
  }
}

makeList('components/lib',list);

module.exports = {
  entry: list,
  mode: 'development',
  output: {
    filename: '[name].umd.js',
    path: path.resolve(__dirname, 'dist'),
    library: 'mui',
    libraryTarget: 'umd'
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader',
          }
        ]
      }
    ]
  },
};

在 package.json 文件中,新增打包命令

"build:js": "webpack --config ./webpack.component.js"

报错信息:

如果webpack打包的时候,

遇到: webpack Cannot find module 'vue/compiler-sfc'

文件872.gif

那要注意vue-loader的版本

npm install vue-loader@15.9.6 -D

运行打包命令

npm run build:js

打包成功后,在dist文件夹里生成了组件的umd.js文件。

这时,有一个问题,dist文件夹中只有各个组件的对应的js,并没有整个组件库的入口文件。

用户只能按需引入,没有办法整体引入。

1,923文件.jpeg

因此,需要在components/lib文件夹下面新建一个 index.js 文件,作为组件库的入口。

import Demo from './demo';
import Card from './card';

import { version } from '../../package.json';

const components = {
  Demo,
  Card,
};

const install = function (Vue) {
  if (install.installed) return;
  Object.keys(components).forEach(key => {
    Vue.component(components[key].name, components[key]);
  })
};

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

const API = {
  version,
  install,
  ...components
};

export default API;

如果今后所有的组件,都要一个个引入太麻烦了。

所以,我将组件拿出来,放在components/lib文件夹下。

clipboard2.png

修改一下 components/lib文件夹下的 index.js 文件,通过require.context引入所有的vue组件。

1,736文件.gif

require.context()的用法详解

require.context(directory,useSubdirectories,regExp)

directory:表示检索的目录

useSubdirectories:表示是否检索子文件夹

regExp:匹配文件的正则表达式,一般是文件名

例如:

require.context("@/views/components",false,/.vue$/)

components/lib文件夹下的index.js文件,

修改为如下内容:

// import Demo from './demo';
// import Card from './card';

import { version } from '../../package.json';

// 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 requireComponent = require.context('./', false, /[a-zA-Z]*\.vue/)

const install = function (Vue) {
  if (install.installed) return;
  requireComponent.keys().forEach(fileName => {
    const componentConfig = requireComponent(fileName)
    const componentName = fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')
    Vue.component(componentName, componentConfig.default || componentConfig)
  })
};

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

const API = {
  version,
  install,
  ...requireComponent
};

export default API;

tips:小知识

UMD

universal module definition 前后端跨平台的模块化解决方案

实现原理:

1.先判断是否支持node.js模块格式(exports是否存在),存在则使用node.js模块格式

2.再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块

3.前两个都不存在,则将模块公开到全局(window或global)

gulp打包css

webpack没有办法单独处理css文件,所以用gulp打包css

gulp官网地址,传送门:

www.gulpjs.com.cn/

新建gulpfile.js配置文件

const gulp = require("gulp")
const sass = require('gulp-sass')
const minifyCSS = require('gulp-minify-css')
const del = require('del');

gulp.task("sass", async function() {
  await del(['dist/css']);    
  return gulp.src("components/css/**/*.scss")    
    .pipe(sass())
    .pipe(minifyCSS())    
    .pipe(gulp.dest("dist/css"))
})

安装gulp相关插件

npm i gulp gulp-sass gulp-minify-css -D

package.json文件中新建命令行

"build:css": "npx gulp sass"

打包css,报错

gulp-sass no longer has a default Sass compiler; please set one yourself.

Both the "sass" and "node-sass" packages are permitted.

For example, in your gulpfile:

解决方案:

npm install sass gulp-sass --save-dev

修改 gulpfile.js 文件

const sass = require('gulp-sass') 改为这样:

 const sass = require('gulp-sass')(require('sass'));

再次运行打包命令!

ok!打包成功!

修改package.json文件中的命令行

"build": "npm run build:js && npm run build:css",

npm run build 直接打包生成 js 和 css 文件

发布到npm

npm官网地址:

www.npmjs.com/

首先,要注册一个npm账号

npm login 登录,然后输入账户,密码,邮箱

npm publish 发布

npm publish --access=public

文件946.jpeg

因为,我有另一篇文章,详细讲了封装组件发布到npm。所以,在这里也不再啰嗦了。

基于elementUI封装了基础表单组件,传送门

juejin.cn/post/704109…

通过VuePress生成文档站点,部署到github

1.关于vuepress

VuePress官网,传送门

vuepress.vuejs.org/zh/

快速上手:

将 VuePress 安装为本地依赖

npm install -D vuepress

2.初始化组件库文档结构

创建你的第一篇文档

mkdir docs && echo '# Hello VuePress' > docs/README.md

或者

 mkdir docs ; echo '# Hello VuePress' > docs/README.md

在 package.json 中添加一些 scripts

{  "scripts": {    "docs:dev": "vuepress dev docs",    "docs:build": "vuepress build docs"  }}

在本地启动服务器

npm run docs:dev

运行起来,如下图所示

clipboard3.png

3.编写组件文档

查看vuepress官网,关于基础配置的说明

vuepress.vuejs.org/zh/guide/ba…

docs文件夹下,新建.vuepress文件夹

.vuepress文件夹下,新建 config.js 文件

module.exports = {
  title: 'Hello VuePress',
  description: 'Just playing around'
}

主题配置,参考官网的配置,可以自行配置。

vuepress.vuejs.org/zh/theme/de…

譬如增加侧边栏

clipboard4.png

// .vuepress/config.js
module.exports = {
  themeConfig: {
    sidebar: [
      '/',
      '/componentDocs/card'
    ]
  }
}

配置成功,如下图所示

clipboard7.png

如何在 Markdown 中使用 Vue

vuepress.vuejs.org/zh/guide/us…

所有在 .vuepress/components 中找到的 *.vue 文件将会自动地被注册为全局的异步组。

clipboard6.png

在.vuepress文件夹下新建 components 文件夹,把card组件和样式文件复制过来。

修改card.md 文件为

# 卡片组件
<m-card imgSrc="static/vue.jpg" summary="这是一个vue卡片组件" />

实现热更新

vuepress启动后,修改.vuepress文件下的配置文件,不会马上更新,需要重新启动。

这个挺麻烦的,vuepress不能热更新怎么解决。

2,071文件.jpeg

修改 package.json文件的 docs:dev 字段,酱:

"docs:dev": "vuepress dev docs --temp .temp",

clipboard7.png

遇到一个小问题,图片没有正常显示。

2,121文件.jpeg

问题不大,查看vuepress官网关于静态资源的说明:

vuepress.vuejs.org/zh/guide/as…

有时,你可能需要提供一个静态资源,但是它们并不直接被你的任何一个 markdown 文件或者主题组件引用 —— 举例来说,favicons 和 PWA 的图标,在这种情形下,你可以将它们放在 .vuepress/public 中, 它们最终会被复制到生成的静态文件夹中

ok!在.vuepress下新建public文件夹,把静态资源放进去即可。

修改card.md文件

# 卡片组件
<m-card imgSrc="/vue.jpg" summary="这是一个vue卡片组件" />

页面成功显示图片

clipboard8.png

修改card.md文件,添加示例和属性说明


# Card

卡片组件

### 示例

<m-card imgSrc="/vue.jpg" summary="这是一个vue卡片组件" />

### 代码

```html
<m-card imgSrc="/vue.jpg" summary="这是一个vue卡片组件" />
```

### Attributes

|   参数    |     说明     |    类型     | 是否必要  |  默认值   |
| :-------: | :----------: | :---------: | :-------: | :-------: |
|   width   |   卡片宽度   |   Number    |   false   |     -     |
|  imgSrc   | 图片资源地址 |   String    |   true    |     -     |
| imgHeight |   图片高度   |   Number    |   false   |     -     |
|  summary  |   卡片概述   | String/Slot |   false   |     -     |
|  footer   |   卡片底部   |    Slot     |   false   |     -     |

clipboard9.png

修改docs文件夹下的README.md文件

# 快速开始

#### 1.安装组件库

```bash
npm i mengyun-ui
```

#### 2.引用组件库
>在main.js中引用组件库
```javascript
// 全部引入
import 'mengyun-ui/dist/css/index.css';
import MUI from 'mengyun-ui';
Vue.use(MUI)
// 按需引入
import 'mengyun-ui/dist/css/demo.css';
import { Demo } from 'mengyun-ui';
Vue.use(Demo)
```

clipboard10.png

4.在github上创建个人站点

GitHub Pages 文档官网说明,传送门

docs.github.com/cn/pages

创建 GitHub Pages 站点

docs.github.com/cn/pages/ge…

文件597.gif

5.将文档站点部署到github.io

VuePress官网,部署到 GitHub Pages 的说明

vuepress.vuejs.org/zh/guide/de…

docs/.vuepress/config.js 中设置正确的 base

如果你打算发布到

https://.github.io/,

则可以省略这一步,因为 base 默认即是 "/"。

如果你打算发布到 

https://.github.io//

也就是说你的仓库在:

github.com//

则将 base 设置为 "//"。

文件950.jpeg

docs/.vuepress/config.js 文件修改

module.exports = {
  base: '/mengyun-ui/',
  themeConfig: {
    sidebar: [
      '/',
      '/componentDocs/card'
    ]
  }
}

在你的项目中,创建一个如下的 deploy.sh 文件

#!/usr/bin/env sh
# 确保脚本抛出遇到的错误set -e
# 生成静态文件npm run docs:build
# 进入生成的文件夹cd docs/.vuepress/dist
# 如果是发布到自定义域名# echo 'www.example.com' > CNAME
git initgit add -Agit commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
# 如果发布到 https://<USERNAME>.github.io/<REPO># git push -f git@github.com:<USERNAME>/<REPO>.git master:maser
cd -

运行 deploy.sh 文件,部署到github

文件980.jpeg

欢迎访问我的组件库

orzr3.github.io/mengyun-ui/

既然你都看到这里了,点个赞再走呗~~!

文件759.gif

青山不改,绿水长流,咱们后会有期。

2,088文件.jpeg