Skip to content

uni-ku/bundle-optimizer

@uni-ku/bundle-optimizer npm package

NPM downloads LICENSE pkg.pr.new

Tip

uni-app 分包优化插件化实现

前往 dcloudio/uni-app#5025 查看本项目立项背景。

前往 https://github.com/Vanisper/uniapp-bundle-optimizer 查看本插件详细发展过程与提交记录。

Caution

v2.0.0版本开始,有重大更新,如果您是从旧版本升级,请务必阅读 迁移指南 (MIGRATION.MD)

🎏 功能与支持

暂时没有对App平台做兼容性实现

适用于 Uniapp - CLI 或 HBuilderX 创建的 Vue3 项目

  • 分包优化
  • 模块异步跨包调用

    允许使用 import() 语法,异步引用模块。

    注意,这不是指静态导入,详见此处

  • 组件异步跨包引用

    在vue 组件的 defineOptions 宏指令或者默认导出下配置 componentPlaceholder,eg:

    <!-- setup 模式(组合式) -->
    <script setup>
    import SubComponent from '@/pages-sub-async/component.vue'
    import SubDemo from '@/pages-sub-demo/index.vue'
    
    defineOptions({
      componentPlaceholder: {
        SubComponent: 'view',
        SubDemo: 'view',
      },
    })
    </script>
    <!-- 默认导出模式(选项式) -->
    <script>
    import SubComponent from '@/pages-sub-async/component.vue'
    import SubDemo from '@/pages-sub-demo/index.vue'
    // 同样支持支持 defineComponent
    export default {
      components: {
        SubComponent,
        SubDemo,
      },
      componentPlaceholder: {
        SubComponent: 'view',
        SubDemo: 'view',
      },
    }
    </script>

异步组件、异步模块引用基本原理:详见 https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/async.html

📦 安装

pnpm add -D @uni-ku/bundle-optimizer

🚀 使用

0. 插件可配置参数

以下各参数均为可选参数,默认开启所有插件功能,并在项目根目录下生成async-component.d.ts文件

参数-[enable] 类型 默认值 描述
enable boolean|object true 插件功能总开关,object时可详细配置各插件启闭状态,详见下列
enable.optimization boolean true 分包优化启闭状态
enable['async-import'] boolean true 模块异步跨包调用启闭状态
enable['async-component'] boolean true 组件异步跨包引用启闭状态
参数-[logger] 类型 默认值 描述
logger boolean|string[] false 插件日志输出总配置,true时启用所有子插件的日志功能;string[]时可具体启用部分插件的日志,可以是optimizationasync-componentasync-import

1. 引入 @uni-ku/bundle-optimizer

  • CLI: 直接编写 根目录下的 vite.config.*
  • HBuilderX: 需要根据你所使用语言, 在根目录下 创建 vite.config.*
简单配置:
// vite.config.*
import Uni from '@dcloudio/vite-plugin-uni'
import Optimization from '@uni-ku/bundle-optimizer'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    Uni(),
    Optimization({
      enable: true,
      dts: true,
      logger: false,
    }),
    // 以上配置都是默认配置,可以直接不传任何配置
    // Optimization(),
  ],
})
详细配置说明
// vite.config.*
import Uni from '@dcloudio/vite-plugin-uni'
import Optimization from '@uni-ku/bundle-optimizer'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    Uni(),
    // 可以无需传递任何参数,默认开启所有插件功能,并在项目根目录生成类型定义文件
    Optimization({
      // 插件功能开关,默认为true,即开启所有功能
      enable: {
        'optimization': true,
        'async-import': true,
        'async-component': true,
      },
      // 也可以传递具体的子插件的字符串列表,如 ['optimization', 'async-import', 'async-component'],开启部分插件的log功能
      logger: true, // 默认 false
    }),
  ],
})

2. 修改 manifest.json

需要修改 manifest.json 中的 mp-weixin.optimization.subPackages 配置项为 true,开启方法与vue2版本的uniapp一致。

{
  "mp-weixin": {
    "optimization": {
      "subPackages": true
    }
  }
}

使用了 @uni-helper/vite-plugin-uni-manifest 的项目,修改 manifest.config.ts 的对应配置项即可。

3. (可选) 异步组件配置,获得 ts 类型标注

本项目为异步组件配置 componentPlaceholder 时,提供了 ts 类型标注,类型文件为 @uni-ku/bundle-optimizer/client

可按需引用,下面分别提供 三斜线指令tsconfig 两种配置方法。

三斜线指令

在项目的入口文件(如 main.ts)顶部添加:

/// <reference types="@uni-ku/bundle-optimizer/client" />

但是一般不会在入口文件写这个类型引用,而是有专门的 *.d.ts 文件,内容同上。

tsconfig 配置

在业务项目的 tsconfig 配置文件的 compilerOptions.types 数组中添加:

{
  "compilerOptions": {
    "types": [
      "@uni-ku/bundle-optimizer/client"
    ]
  }
}

✨ 例子

以下例子均以CLI创建项目为例, HBuilderX 项目与以上设置同理。

现在已经支持 hbx 创建的 vue3 + vite、不以 src 为主要代码目录的项目。

🔗 查看以下例子的完整项目

1. (点击展开) 分包优化

分包优化 是本插件运行时默认开启的功能,无需额外配置,只需要确认 manifest.json 中的 mp-weixin.optimization.subPackages 配置项为 true 即可。

详情见本文档中的 使用 部分。

2. (点击展开) 模块异步跨包调用
  • 模块异步跨包调用 是指在一个分包中引用另一个分包中的模块(不限主包与分包),这里的模块可以是 js/ts 模块(插件)。
  • TODO: 是否支持 json 文件?
  • TODO: 是否支持 vue 文件?当然,小程序环境引入 vue 文件一般是没有什么意义的。

    目前实测,小程序环境下,千万不要对一个 vue 组件进行 import()

    这会导致这个 vue 组件对应的页面或者文件空白,和 “分包优化” 功能有些许冲突”,后续会尽可能填补这个缺陷

可以直接使用 esm 的原生异步导入语法 import() 来实现模块的异步引入。

  • h5:原生支持
  • mp:转译成 require.async()
  • app:TODO: 待兼容
  • 其他 mp:TODO: 未做兼容测试,欢迎反馈
// js/ts 模块(插件) 异步引入
await import('@/pages-sub-async/async-plugin/index').then((res) => {
  console.log(res?.AsyncPlugin()) // 该插件导出了一个具名函数
})

// vue 文件 异步引入(页面文件)❌ 暂时不要这样使用,不要这样引用组件文件
import('@/pages-sub-async/index.vue').then((res) => {
  console.log(res.default || res)
})

// vue 文件 异步引入(组件文件)❌ 暂时不要这样使用,不要这样引用组件文件
import('@/pages-sub-async/async-component/index.vue').then((res) => {
  console.log(res.default || res)
})
3. (点击展开) 组件异步跨包引用
  • 组件异步跨包引用 是指在一个分包中引用另一个分包中的组件(不限主包与分包),这里的组件就是 vue 文件;貌似支持把页面文件也作为组件引入。
  • 需要在 vue 组件的 defineOptions 宏指令或者默认导出下配置 componentPlaceholder
  • 由于小程序端需要 kebab-case 风格的组件名称,插件内部会自动处理你的 componentPlaceholder 配置:将组件名称(key)以及占位目标组件名(value)转换成 kebab-case 风格。

setup 模式(组合式):

<!-- setup 模式(组合式) -->
<script setup>
import SubComponent from '@/pages-sub-async/component.vue'
import SubDemo from '@/pages-sub-demo/index.vue'

defineOptions({
  componentPlaceholder: {
    SubComponent: 'view',
    SubDemo: 'view',
  },
})
</script>

默认导出模式(选项式):

可能有些环境不能使用 defineOptions 宏

<!-- 默认导出模式(选项式) -->
<script>
import SubComponent from '@/pages-sub-async/component.vue'
import SubDemo from '@/pages-sub-demo/index.vue'

// 同样支持支持 defineComponent
export default {
  components: {
    SubComponent,
    SubDemo,
  },
  componentPlaceholder: {
    SubComponent: 'view',
    SubDemo: 'view',
  },
}
</script>

🙏 感谢

🏝 周边

项目 描述
Uni Ku 有很多 Uniapp(Uni) 的酷(Ku) 😎
create-uni 🛠️ 快速创建uni-app项目
Wot Design Uni 一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件

🧔 找到我

加我微信私聊,方便定位、解决问题。

wechat-qrcode

微信

💖 赞赏

如果我的工作帮助到了您,可以请我吃辣条,使我能量满满 ⚡

请留下您的Github用户名,感谢 ❤

直接赞助

wechat-pay

微信

alipay

支付宝

赞赏榜单

sponsors


Happy coding!

About

🦾 Uniapp Vue3 版本的分包优化实现

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •