【手牵手】搭建前端组件库(一)

手牵手搭建前端组件库

本文梳理怎样搭建和构建前端组件库.

《【手牵手】搭建前端组件库(一)》

相识几个题目

为什么须要组件化?

大部分项目劈头都是源于营业方的林林总总的奇葩需求。跟着公司的营业生长,公司内部最先衍生出许多的B2C体系、背景体系,前端部门也疲于应对越来越多同质化的项目,这些项目在许多基础模块层、源代码存在不小的类似,以至存在类似的营业模块。

笔者曾地点的一个电商团队,前端成员基础每一个人多做过登录注册、购物车、付出、微信登录…… 大批反复的营业代码。因为组内手艺没有强迫范例

本质上雷同的东西,反复的去code就显得糟蹋.

剖析这些题目发明:
日渐增加的营业场景需求

前端资本有限,没法支持一切项目的疾速迭代

公司内部诸多产物营业杂沓、体验不一致

因而开辟底层的东西去效劳差别营业就很有必要:
设想一套公司内部的基础组件库支持各个前端项目,提拔项目和营业的可用性和一致性。

一个前端团队具有大批的营业场景和营业代码,类似的页面和代码屡见不鲜,怎样治理和笼统这些类似的代码和模块,绝大多数团队会碰到如许的题目。 不停的拷代码? 修正代码?照样笼统成组件?明显后者更高效。所以在多项目存在高度的可控、底层依靠的情况下,前端完成组件库是最好的挑选。

组件化,又或许组件抽离的目的是为了功用同享轻易保护,其能够带来的优点是少写代码,一致治理、一致保护。一套基础组件代码精益求精精而又精,从而起到疾速支持营业迭代,提拔开辟效力的目的。

营业型组件库

前端组件库百花齐放,antd、element ui这些基础组件库已很壮大,运用于种种营业场景。然则这些基础组件的粒度是基于单个交互,而在交互产物之间隔着林林总总的模块和营业场景,产物的会聚源于种种基础组件在营业逻辑的沾粘下集成为一个个项目,一个团队或多或少会有项目或模块存在功用、交互流程的反复、本质上的同质化。

所以antd、element ui 这类组件库是基于单个非一连性的交互组件,一个组件代表着一次人机无副作用的操纵与相应,其不思索实体、用户、终端的状况,最小化的暴露和相应组件内部状况。关于一连性的交互一般来讲与特性的营业场景有关,存在诸多的外部依靠,现在都是在各个营业模块由用户(coder)自行编写。

有无一种要领处置惩罚一连性交互流程的共用题目?

处置惩罚的方法是组件封装包含营业场景的一连性交互流程,运用组件化将内部依靠经由过程接口映照到外部。

前端架构部门为营业部门供应营业型组件库能够有用进步开辟效力.

组件库设想思绪

组件是对一些具有雷同营业场景和交互情势、交互流程代码的笼统,组件库起首应当保证各个组件的视觉作风和交互范例坚持一致。组件库的 props 定义须要具有充足的可扩展性,对外供应组件内部的控制权,使组件内部完全受控。支持经由过程 children 自定义内部构造,预定义组件交互状况。坚持组件具有一致的输入和输出,完全的API.

组件库的开辟我们须要斟酌:

  • 组件设想思绪、须要处置惩罚的场景
  • 组件代码范例
  • 组件测试
  • 组件保护,包含迭代、issue、文档、宣布机制

一个完全壮大的组件库须要多方面勤奋,回归正题.

运用到的基础手艺

  1. vue cil 3
  2. npm
  3. webpack
  4. rollup(v1.2.2)

Demo

下面就手把手搭建一个前端偏营业性的组件库。

组件库包含:

  • message 组件: 一个封装用于显现背景经由过程 websocket 推送到前台页面的及时音讯模块;
  • pay 组件: 一个封装用于完成商品付出的模块
  • share 组件: 一个封装用于完成商品、文章、视频在各交际平台分享的模块

只抛出一个栗子,组件内部完成略~

这里注重组件抽取的粒度,组件的抽离以一个完全的一连性交互为目地。

组件依靠数据、交互事宜、控制权的暴露须要斟酌周全,差别的上层营业部门都有本身对组件可设置的差别盼望。须要衡量,不能把设置化给捣鼓的永无止境到很尴尬的局势。笔者曾就介入一个项目的组件化,组件抽离的面目一新,种种依靠、环境、状况的设置,致使末了只要组件编写职员在看文档加回想的情况下才搞清楚其前因后果.

从简朴的最先~

1、初始化组件库目次

建立一个空项目

// 新建一个项目
vue create qw-ui

经由vue cil3初始化后的qw-ui目次:

├─docs
│          
├─public
│
├─src
│  .gitignore
│  babel.config.js
│  package-lock.json
│  package.json
│  README.md
│  vue.config.js
│         

此时为了轻易组件库的代码治理,将目次构造修正为:

├─src        // 用作示例 Demo
│          
├─packages   // 新增 packages 用于编写寄存组件
│
├─lib        // 新增 lib 用于寄存编译后的输出文件
│  .gitignore
│  babel.config.js
│  package-lock.json
│  package.json
│  README.md
│  vue.config.js
│   

目次构造能够更具须要调解.

2、修正 vue.config.js 设置

vue cli3 供应一个可选的 vue.config.js 设置文件。这个文件存在则他会被自动加载,一切的对项目和webpack的设置,都在这个文件中。

修正 vue.config.js 设置的目的主假如:

  1. 使 Demo 可接见,完成对 src目次的编译处置惩罚;
  2. 供应对 package的编译、构建处置惩罚

做以下两处修正:

  • 修正项目的进口

entry 字段为项目进口

进口修正运用 Vue CLI 3 的 page属性来设置:

module.exports = {
  pages: {
    index: {
      // page 的进口
      entry: 'src/main.js',
      // 模板泉源
      template: 'public/index.html',
      // 在 dist/index.html 的输出
      filename: 'index.html'
    }
  }
}
  • 增加对 packages 目次的编译处置惩罚

packages 是我们厥后新增的一个目次,默许是不被 webpack 处置惩罚的,所以须要经由过程增加设置对该目次的编译支持。

新增编译处置惩罚目次,须要经由过程webpack的链式操纵chainWebpack函数完成:

module.exports = {
  pages: {
    index: {
      // page 的进口
      entry: 'examples/main.js',
      // 模板泉源
      template: 'public/index.html',
      // 在 dist/index.html 的输出
      filename: 'index.html'
    }
  },
    chainWebpack: config => {
        // packages和examples目次须要到场编译
        config.module
            .rule('js')
            .include.add(/packages/)
            .end()
            .include.add(/src/)
            .end()
            .use('babel')
            .loader('babel-loader')
            .tap(options => {
                // 修正它的选项...
                return options;
            });
    }
}

实行 npm run vue-cli-service serve , 完成对Demo的接见.

3、编写 packages 组件库

建立一个 message组件

  • 建立组件

    • packages 目次下,一切的单个组件都以文件夹的情势存储,这里建立一个目次 message 文件夹;
    • message/ 目次下建立 src/ 目次存储组件源码,一切 message 依靠的除第三方资本都寄存与该目次下;
    • /message目次下建立 index.js` 文件对外供应对组件的援用

示例代码:

message/index.js 对外供应运用

// message/index.js

import message  from './src/message '

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

export default message 
// message/src/message .js
<template>
  <div class="message">
    <el-row class="message-test">
      <el-col :span="12" class="message-row"><p class="text">hello {{ message }}</p></el-col>
      <el-col :span="6">
        <img src="./st.png"/>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import './index.scss'
export default {
  name: 'v-message',    // 说明组件的 name属性
  props: {
    message: String
  }
}
</script>

须要注重的是,组件 mesage 必需声明 name 属性,这个 name 就是组件的标签,如:

<v-message><v-message/>

packages/message目次构造以下:

packages/message
            ├─index.js
            │          
            ├─src
                │      message.vue
                │      st.png         // 组件依靠的图片
                │      index.scss    // 组件依靠的款式文件

导出 packages 组件库

修正 /packages/index.js 文件,整合一切组件,并对全部组件库举行导出:

// 导入组件
import hello from './hello'

// 存储组件列表
const components = [
  hello
]

// 定义 install 要领,吸收 Vue 作为参数。假如运用 use 注册插件,则一切的组件都将被注册
const install = function (Vue) {
  // 推断是不是装置
  if (install.installed) return
  // 遍历注册全局组件
  components.map(component => Vue.component(component.name, component))
}

// 推断是不是是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue)
}

export default {
  // 导出的对象必需具有 install,才被 Vue.use() 要领装置
  install,
  // 以下是详细的组件列表
  hello
}

到此,构建组件库的环境准好好了

### 4、宣布组件库到 npm

  1. packages 目次的编译打包

    package.jsonscripts 字段中新增一下敕令:

    "lib": "vue-cli-service build --target lib --name kui --dest lib packages/index.js"
    vue cil3 供应了 [库情势](https://cli.vuejs.org/zh/guide/build-targets.html#%E5%BA%93) 来打包第三方库的开辟,packages 的编译打包须要运用库情势
    

    --target: 构建目的,默许为运用情势。这里修正为 lib 启用库情势。

    --dest : 输出目次,默许 dist。这里我们改成 lib

    [entry]: 末了一个参数为进口文件,默许为 src/App.vue。这里我们指定编译 packages/ 组件库目次。

    在 vue cil3 库情势中,Vue 是
    外置的。这意味着包中不会有 Vue,即使你在代码中导入了 Vue。假如这个库会经由过程一个打包器运用,它将尝试经由过程打包器以依靠的体式格局加载 Vue;不然就会回退到一个全局的
    Vue 变量。

    设置好了后,实行编译敕令:

    npm run lib

    稍后控制台输出,即编译完成:

     DONE  Compiled successfully in 5988ms16:05:35
    
      File                  Size                       Gzipped
    
      lib\kui.umd.min.js    8.08 KiB                   4.55 KiB
      lib\kui.umd.js        17.78 KiB                  7.31 KiB
      lib\kui.common.js     17.41 KiB                  7.19 KiB
      lib\kui.css           0.10 KiB                   0.10 KiB
    
      Images and other types of assets omitted.
 Total task duration: 8.71s
 ```
  1. package.json 设置

    • name: 包名,该名字是唯一的。可在 npm 官网搜刮名字。
    • version: 版本号,每次宣布至 npm 须要修正版本号,不能和汗青版本号雷同。
    • description: 形貌。
    • main: 进口文件,该字段需指向我们终究编译后的包文件。
    • keyword:关键字,以空格星散愿望用户终究搜刮的词。
    • author:作者
    • private:是不是私有,须要修正为 false 才宣布到 npm
    • license: 开源协定

      参考设置:

      {
        "name": "qw-ui",
        "version": "0.1.0",
        "private": false,
        "main": "lib/kui.umd.min.js",
        "description": "qw-ui",
        "keyword": "qw-ui",
        "author":"luojh",
        "scripts": {
          "serve": "vue-cli-service serve",
          "build": "vue-cli-service build",
          "lint": "vue-cli-service lint",
          "lib": "vue-cli-service build --target lib --name kui --dest lib packages/index.js"
        }
      }
  2. 增加 .npmignore 文件

    宣布时,只要编译后的 lib 目次、package.json、README.md才须要被宣布。所以经由过程设置.npmignore文件疏忽不须要提交的目次和文件。

    # 疏忽目次
    examples/
    packages/
    public/
    
    # 疏忽指定文件
    vue.config.js
    babel.config.js
    *.map
    
    # 当地文件
    .env.local
    .env.*.local
    
    # 日记文件
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
    
    # 编辑器缓存文件
    .idea
    .vscode
    *.suo
    *.ntvs*
    *.njsproj
    *.sln
    *.sw*
  3. 宣布到 npm

    起首须要在 npm 官网上注册一个账号,经由过程 npm adduser 敕令建立一个账户,或许在 npm 官网注册

    注册完成后在当地敕令行中登录:

    npm login

    实行宣布敕令,宣布到 npm

    npm publish
    1. npm 淘宝镜像不支持 publish 敕令,假如设置了淘宝镜像,publish 前需将镜像设置会 npm :

    npm config set registry http://registry.npmjs.org

    1. npm publish时,当地cmd终端需经由过程治理员运转

### 5.运用组件库

装置宣布的组件库:

npm i qw-ui

运用组件:

# 在 main.js 引入并注册
import qwui from 'qw-ui'
Vue.use(qwui)

# 在组件中运用
<template>
  <v-message message=" hello 333 :: 运用kui组件库"></v-message>
</template>
<script>
  export default {
    data () {
      return {
      }
    }
  }
</script>

完!

    原文作者:kooky
    原文地址: https://segmentfault.com/a/1190000018310478
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞