Bootstrap

浅尝 | 从 0 到 1 Vue 组件库封装

写在前面

对于目前框架为王的时代,前端可能很大一部分时间,都是在开发相关的页面组件,而有句话说得好,没有哪个前端不想拥有一个属于自己的,为自己量身定制的组件库,那么本文就为大家整理一下:

如何从 0 到 1 搭建一个属于自己的组件库

开发环境

本文将基于 vue-cli4.5 脚手架搭建项目基础框架

// 全局安装vue脚手架
npm install -g @vue/cli
// 创建项目
vue create 项目名称

修改项目结构

由于使用脚手架创建的项目结构,主要是面向业务开发,因此我们需要根据我们自己的需求,进行一下适当的调整

抽离 components 目录,用于放置我们之后开发的组件库的源码
将 src 改为 example ,用于存放测试组件的代码

3.png

创建组件目录

在 components 中创建 css 文件夹用于存放组件相关的 css 样式
在 components 中创建 lib 文件夹用于存放组件相关的源码(vue、js等)

4.png

添加组件相关文件

5.png

在每个组件中新建一个 src 文件夹用于存放组件源码,src 中写入测试源码 main.vue
<template>
  <div class="demo">Demo</div>
</template>

<script>
export default {
  name: 'Demo'
}
</script>
在每个组件的根目录创建一个 index.js 文件,用于导出该组件,代码如下:
// 引入组件
import Demo from './src/main.vue'
// 为组件添加 install 方法,在vue中调用 Vue.use(组件)
// 将自动调用组件的 install 方法注册组件
Demo.install = function(Vue){
  Vue.component(Demo.name, Demo)
}
export default Demo
最后在 lib 根目录创建 index.js 用于批量导出所有组件,代码如下:
// 引入组件
import Demo from './demo'
import Demo2 from './demo2'
const components = {
  Demo,
  Demo2
}

// 添加 install 方法,在vue中调用 Vue.use(组件)
// 将自动调用 install 方法注册所有组件
const install = function(Vue){
  if(install.installed) return;
  Object.keys(components).forEach(key =>{
    Vue.component(components[key].name,components[key])
  })
}

// 导出所有组件
const API = {
  install
}
export default API;

添加组件样式

7.png

在 /components/css 中分别为每个组件创建 .scss 文件并写入样式
.demo {
  background: cadetblue;
}
在 /components/css 中创建 index.scss 文件,用于导出所有样式
// 引入所有组件的样式
@import './demo.scss';
@import './demo2.scss';

打包组件库

打包 vue、js

安装 webpack-cli
npm install webpack-cli
在项目根目录创建用于打包组件库的配置文件并写入配置
Tips: 当打包失败时,可通过直接运行webpack.js 文件检测插件引入是否正常
// 引入 glob 用于匹配路径
const glob = require('glob')
// 引入 path 用于生成绝对路径
const path = require('path')
// 引入 VueLoaderPlugin 用于解析vue文件
const { VueLoaderPlugin } = require('vue-loader')

// 生成所有组件对应目录组成的数组
const list = {}
async function makeList(dirPath, list){
  // path/*/name 表示匹配在path子文件夹中所有name文件
  // path/**/name 表示匹配在path/中以及
  // 子目录的所有name文件(递归匹配所有目录)
  const files = glob.sync(`${dirPath}/**/index.js`)
  for(let file of files){
    const component = file.split(/[/.]/)[2]
    list[component] = `./${file}`
  }
}
makeList('components/lib',list)

module.exports = {
  // webpack 打包类型
  mode: 'development',
  // 入口文件为所有组件目录组成的数组
  entry: list,
  // libraryTarget 为 umd 则表示打包的组件库为通用组件库
  output: {
    filename: '[name].umd.js',
    path: path.resolve(__dirname, 'dist'),
    library: 'yimwu',
    libraryTarget: 'umd'
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  module: {
    rules: [
      {
        // 匹配所有vue文件并使用vue-loader进行解析
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  }
}
打包踩坑

9.png

这里出现的问题是 vue-loader 版本太高,无法和 Vue2 匹配,更换低版本的vue-loader 即可解决

npm uninstall vue-loader
npm install vue-loader@15
在package.json 中添加 script 打包脚本命令
"build:js": "webpack --config ./webpack.component.config.js"

10.png

最后一步,运行命令完成 js 打包
npm run build:js

11.png

打包样式

打包样式需要用到另外一个构建工具 gulp,首先安装gulp以及相关插件
npm install gulp gulp-sass gulp-minify-css
在根目录创建 gulp 配置文件 gulpfile.js 并写入配置
const gulp = require('gulp');
// sass -> css
const sass = require('gulp-sass')(require('node-sass')) 
// 压缩 css 
const minifyCSS = require('gulp-minify-css') 
gulp.task('sass', async function(){
  return gulp.src('components/css/**/*.scss')
    .pipe(sass())
    .pipe(minifyCSS())
    .pipe(gulp.dest('dist/css'))
})
在package.json 中添加 script 打包脚本命令
"build:css": "npx gulp sass"
最后一步,运行打包命令,完成 css 打包
npm run build:css

12.png

优化打包命令

由于 js 和 css 是分开打包的,所以可以通过 package.json 中sciprt的配置,将 js 与 css 打包整合
"build": "npm run build:js && npm run build:css"
至此,所有组件打包相关的工作就结束了,组件库已经可以正常使用了

NPM 包发布

完成了打包工作后,最后一步就是将组件发布到 npm 上

编写 README.md 文件

在 README.md 中写入组件的安装、引用以及使用的相关说明

配置 package.json 文件

  • 在 package 中添加以下 npm 相关的配置
  • main 表示组件库的入口
  • files 表示需要发布到 npm 上的目录
  • 由于 npm 包为公开组件库,因此需要删除原来存在的 private 属性
"name": "test",
  "version": "0.1.1",
  "description": "测试组件库",
  "main": "dist/index.umd.js",
  "keywords": [
    "yimwu-ui",
    "vue",
    "ui"
  ],
  "author": "yimwu",
  "files": [
    "dist",
    "components"
  ],

注册 npm 账号并通过命令行登录账号

npm login

13.png

最后最后,见证奇迹的时候到了~~
运行 npm pubilsh 完成 npm 包发布

在这里插入图片描述

总结

搭建组件库本身并没有什么技术难点,最主要是打包流程以及对于组件库目录结构的把握,对于相对复杂的组件库来说,一个清晰、层级分明的目录非常重要,这不仅能够使之后组件开发过程更加标准、可控,也能够使组件对组件使用者更加灵活、友好!

写在最后

该专栏将持续更新前端相关技术的整理与总结,欢迎订阅!
如果喜欢博主的文章,那就狠狠给博主点个赞呗,让我们一起成长吧!
欢迎关注博主文章首发号 掘金社区,转发记得私信博主哟哟!

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;