Skip to content

背景

近期我在做什么?

远程组件如何引入在项目中这个话题也就是我最近在研究的东西;

为什么?

最近有一个想法,就是在工作中有那么一个功能就是商品属性, 类似于淘宝京东的选择商品规格的功能, 有尺寸大小,有眼色,有材质等等;

该功能涉及到多个平台,每个属性有对应的规则,但是有一个比较麻烦的点就是功能是一致的,规则是一样的,就是完全的功能要在不同的项目中复制粘贴修改;导致现在就是不同的项目中都有一样的组件一样的代码

这样就暴露出了弊端:

  1. 维护多个平台,比如修改了规则,那么就要修改多个项目;pc 端, h5, 小程序等等;
  2. 代码的重复性比较高,对于高复杂的组件没有对应的文档以及说明;
  3. 底层的变动以及参数不统一,A 同学加个一个参数 a, B 加了一个 b,最后都不知道该字段的具体作用

在这样的业务场景下,于是我消费一些时间去研究一下远程组件如何做?

当然远程组件的好处就是:后期维护这个组件即可;

于是,就考虑到了俩种不同的处理方式

  1. 包依赖模式,有一个缺点就是如果远程组件更新了,那么本地以及生产的package.json也要对应进行升级;不过稳定性比较高
  2. cdn 模式,那就是项目使用 cdn 的模式引入import {RTx} from 'https://xxx.com/xx.js', 不过这样在vite上是可以正常运行的,在webpack上就无法使用了

思路

首先,选用构建工具:

  • vite
  • webpack
  • rollup

在三者的比较下,我选择了vite

  1. vite 与 webpack 相比,不论是启动,打包还是热更新,vite 还是比较优秀的,再者,vite 还支持对 rollup 的配置
  2. rollup 与 webpack 相比,rollup 更加轻量,配置简单,但是不支持热更新

为什么要用到热更新,因为你在开发组件或者测试一些 api 的时候总不能每次都重启修改吧,那么热更新是不错的选择;

于是我还是采用vite的打包方式,原因就是很简单,速度,配置等都算的是比较不错的,当然是还可以配置 rollup 配置; 完全是自定义的;

其次,组件的编写方式:

组件使用 vueComponent 的方式,之前也想过用函数组件,但是有些场景不太合适;就拿vant来讲,其远嘛就是tsx/jsx编写,你直接看不到vue文件,但是对于其维护的便利性来讲我还是看中component的形式;

接着,就要对其目录进行分级,

  • packages
    • ele-components => element-plus 组件的目录
    • van-components => van-ui 组件的目录
    • utils => 工具函数的目录
    • hooks => 封装的 hooks
    • types => 类型定义
    • style => 样式的目录
    • index.ts => 入口文件
    • package.json => 组件的配置文件
  • package.json
  • vite.config.ts
  • ...其他文件

当然对应的打包文件的格式也和packages一样,这样就可以了

编写远程组件

其实这里的远程组件和日常编写的组件是一样的,不过是对公司的一些公共的业务组件进行拆分,从而再二次封装,后期只需要引入对应的依赖即可,这样就可以做到仅仅修改一次从而再多个平台进行更新;

具体的编写方式就不细说了;

当你写完之后,那么最后一步就是进行打包了, 这里我采取vite-lib插件的形式进行打包:

JS
{
  build: {
    lib: {
      entry: '', // 插件的入口文件
      name: '', // 名字
      formats: ['es'] // 打包的格式
    },
    // rollup配置
    rollupOptions: {
      external: {},
      output: {
      }
    },
    cssCodeSplit: true
  }
}

以依赖包的形式将进行打包,这里我用到了几个插件:

  1. vite-plugin-dts: 将组件的代码进行类型声明,方便使用
  2. autoprefixer: 添加浏览器前缀
  3. rollup-plugin-obfuscator: 代码混淆

打包完成之后,你会发现对应的文件会很大,那么接着对其进行优化, 首先我们下载的一些依赖不需要进行打包,如:vue, vant, element-plus

那么vite-rollupOptions有这样一个配置:

ts
{
	rollupOptions: {
		external: ["vue", "vant", "element-plus"];
	}
}

那么重新打包,观察其文件大小,你会发现比之前的文件小了很多;

到了这一步基本上差不多了,不过要注意的是打包完成之后必须要有package.json文件,不然后期使用install的方式会失败的;

这是一个使用案例:

ts
// 类似于这样的格式,具体路径自己进行配置;
// 这样做到了按需加载,用到那个组件加载对应的组件以及样式,避免组件和样式打包一起导致文件加载时间过长的情况
import "remote-components/ele/index.css";
import { ElButton } from "remote-components";

<template>
	<ElButton />
</template>;

目前项目在:源码,暂时不开源

wangxiaoze | MIT License.