uniapp使用原生小程序组件实现tree-shaking

1,084 阅读3分钟

背景

在使用 uniapp 开发小程序的过程中,总有某些场景不需要兼容多平台,且生态与宿主平台强耦合的情况下,我们有可能会需要使用 原生小程序组件库 来快速开发UI页面

那么这个时候有可能你会需要使用到像如下的组件库来进行开发

但是鉴于 uniapp小程序 使用原生小程序组件的方式是

那么就会有可能存在该情况:

  • 在使用的时候会把一个完整包放在对应的原生小程序组件文件夹底下,在使用的时候是在pages.json中去定义的对应组件
  • 打包的时候会把整个原生小程序组件库源码包塞进你的整个项目里去

这样的话你的代码包体积就会相对较大 (即使通过打包压缩的方式可以省去一些体积,但其实这部分内容有可能是不需要的)

解决方案

  1. 在每次打包完成后,手动去整理没有使用的相关组件并删掉多余内容
  2. 编写一份脚本,在你项目build结束后去执行删去多余的内容
  3. 写一个插件,可以抽离出来与项目解耦,并且能够在多项目中开箱即用,提供相关配置项即可

在以上几个方案中,我最终选择了 方案3 于是诞生了以下插件

vite-plugin-miniprogram-tree-shaking

graph TD
      A[开始] --> B[初始化插件]
      B --> C[设置过滤器]
      C --> D[定义日志功能]
      D --> E[生成打包]
      E --> F{遍历包}
      F -->|符合条件| G[解析组件]
      F -->|不符合条件| H[跳过]
      G --> I[更新JSON]
      E --> J[处理app.json]
      J --> K[删除未使用组件]
      K --> L[安装npm依赖]
      L --> M[结束]

大概就是如上一个工作流程,利用 vite 相关钩子做了 组件使用的收集和删除

使用方式

参考 vite-plugin-miniprogram-tree-shaking

源码仓库中有 example 使用示例 README

npm run -D vite-plugin-miniprogram-tree-shaking

这里举了一个使用支付宝小程序组件库能力的例子

// vite.config.ts
import { defineConfig } from 'vite'
import uni from "@dcloudio/vite-plugin-uni";
import miniprogramTreeShaking from "vite-plugin-miniprogram-tree-shaking";

export default defineConfig(({ mode }) => {
  return {
    plugins: mode === "production" ? [uni(), miniprogramTreeShaking({
      include: ["pages/**/*", "subpages/**/*", "components/**/*"], // 表示从以下路径中去寻找所使用过的组件
      componentsPlatform: "alipay", // 原生小程序组件库平台
      componentsPrefix: "ant", // pages.json中 要处理的小程序组件库前缀 例如 <ant-button> 中的 ant 默认使用 '-' 拼接
      excludeComponents: [
        "style",
        "_util",
        "mixins",
        "tsxml",
      ], // 支付宝小程序组件库所需要的base内容
      componentsPath:
        "dist/build/mp-alipay/mycomponents/node_modules/antd-mini/es", // 原生小程序组件库编译后的目录路径
      miniprogramComponentsPath: "dist/build/mp-alipay/mycomponents", // 如果是以node_modules的方式引入的话可以填写,用于CI上安装依赖(内部执行npm i)
    })] : [uni()];
  };
});

特别提示

插件钩子需要放置在 uni() 也就是 uni-vite-plugin 后执行

使用场景

如果你有在 uniapp 开发小程序的过程中需要使用到 原生小程序组件库 能力的时候,或许可以考虑一下使用该插件

本来定位的是一个 vite 插件,但是好像在 跨端框架 写小程序并使用 原生小程序组件 方式在不同框架上不太一致 (前期确实没有做过多的调研)

另外看了一下 taro4.x 开始支持 vite,踩了一下坑发现使用方式确实不太一样,并且框架内置了 tree-shaking,也就是没有该插件的用武之地了,至于别的框架应该市面上流通率并不会特别高吧,一些企业内部使用率高的框架可能也已经自研实现了相关功能

展望

目前只做了构建工具是 vite 的版本,如果后续有需求的话看下考虑支持 webpack,不过新项目的话一般都不会用了吧 (我猜的

欢迎交流

有任何问题或者关于插件的想法都可以随时交流~