{T}

组件库局部引入方案:Element-Plus 自动按需解析

概述

上一节靠「消费方全局 app.use(ElementPlus)」打通了链路,这一节把第二条路线真正跑通:让组件库内部按需解析并带出自己用到的 Element Plus 组件和样式,从而 Playground 不必再全局安装 Element Plus。本文把「局部使用 Element Plus」拆成作者开发体验和消费方运行体验两层,讲清 unplugin-auto-import + unplugin-vue-components + ElementPlusResolver 的组合、库产物样式如何通过 exports["./style.css"] 暴露、element-plus 到底该进 peerDependencies 还是 devDependencies,以及这条路线在体积与升级上的代价。

学习目标

  • 区分「作者开发期自动按需解析」与「消费方运行期依赖是否 external」这两层不同问题
  • unplugin-auto-import + unplugin-vue-components + ElementPlusResolver 降低手写导入成本
  • 理解库产物带出的 CSS 应通过 exports["./style.css"] 暴露,而非自定义非标准字段
  • 根据 external 策略决定 element-plus 进入 peerDependencies 还是 devDependencies
  • 认识局部打包方案的代价:包体积变大、样式耦合更强、升级更被动

一、「局部使用」要分清两层含义

课程里很容易把两件事混成一件:作者开发组件时希望自动按需引入 Element Plus 组件和 Vue API;消费方使用组件库时希望不必全局安装 Element Plus。这两层关联但不是同一问题:

  • 作者开发体验:关心 ElAvatar 要不要手写 import、computed 要不要手写 import,解决方案是自动导入插件;
  • 消费方接入体验:关心安装库后还要不要额外装 element-plus、还要不要在 main.tsapp.use(ElementPlus),解决方案是依赖是否 external、样式是否随库分发。

自动导入插件解决的是作者写代码的体验,不直接决定最终库产物的依赖边界。

二、Element Plus 按需解析的插件组合

Element Plus 官方 Quick Start 当前给出的按需导入方案,就是 unplugin-auto-import + unplugin-vue-components + ElementPlusResolver。在组件库项目里,这套方案同时解决两类问题:自动导入 Vue API(如 computedref),以及自动解析模板中的 Element Plus 组件(如 ElAvatar)。

ts
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ['vue', '@vueuse/core'],
      resolvers: [ElementPlusResolver()],
      dts: true,
    }),
    Components({
      resolvers: [ElementPlusResolver()],
      dts: true,
    }),
  ],
})

AutoImport 负责自动导入脚本里用到的 API,Components 负责自动注册模板里用到的组件,ElementPlusResolver 把 Element Plus 纳入自动按需解析体系,dts: true 生成类型声明降低编辑器异常。@vueuse/core 如果组件内部要用才装,否则自动导入里不必提前塞太多东西。

三、库产物带出的样式如何暴露

如果组件库内部引用了 ElAvatar,构建器和解析器会把组件相关样式一起带到库的 CSS 中。从消费方角度看,意味着不一定非要在入口再手动引 element-plus/dist/index.css,但必须把组件库样式入口引进来(import 'el-admin-components/style.css')。

Vite 官方库模式文档给出的推荐方式是:如果库会额外产出 CSS 文件,就在 package.json.exports 中显式暴露 ./style.css,而不是自定义一个不规范的 exports.style 字段。

json
{
  "name": "el-admin-components",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/el-admin-components.js",
      "require": "./dist/el-admin-components.umd.cjs"
    },
    "./style.css": "./dist/el-admin-components.css"
  }
}

样式文件名默认跟 build.lib.fileName 相关,也可通过 cssFileName 单独控制。一旦想让消费方稳定引用样式,最好明确给出 ./style.css 这样的子路径出口。

四、element-plus 的归属取决于是否 external

如果 external 掉 element-plus,消费方运行时必须提供它,那它应当进入 peerDependencies(同时为本地开发把它放进 devDependencies);如果把 element-plus 打进产物,消费方不一定需要直接安装它,但你要接受包体积增加和依赖耦合增强。本地实验阶段把 element-plus 先装到开发依赖可以成立,但准备发布前归属必须和 external 策略一致,否则消费方最容易遇到「本地能跑、发出去别人不能用」。

json
{
  "peerDependencies": {
    "vue": "^3.0.0",
    "element-plus": "^2.0.0",
    "@vueuse/core": "^10.0.0"
  },
  "devDependencies": {
    "element-plus": "^2.0.0"
  }
}

五、局部打包方案的代价与取舍

课程在 Playground 里去掉 app.use(ElementPlus) 后组件仍能渲染,说明组件库自己吸收了需要的局部 Element Plus 能力。但副作用很明确:dist 体积增大、组件库和 Element Plus 样式更紧耦合、后续走 CDN / external 策略更麻烦、新组件或新样式能力很难像「全局安装 Element Plus」那样自然继承。

自动导入 Vue API 和自动解析 Element Plus 组件,不等于可以放弃显式依赖管理——构建链路会帮你少写 import,但不会替你决定架构边界。对 Vue API 这类语法层能力,自动导入对打包边界影响很小;对 Element Plus 这类大体量 UI 依赖,是否开启自动解析会直接影响产物体积、样式分发、external 策略和使用者负担。

这节课真正的结论不是「哪种方案绝对更好」,而是:在组件库从 0 到 1 阶段,先把两条链路都验证一遍,后面才能有依据做取舍。课程最后更推荐 external 掉 Element Plus,这个判断有工程经验支撑——尤其当组件库主要服务同一套 admin 体系内部项目时,external 策略通常更划算。


常见问题

问题原因解决方案
去掉 Playground 的 app.use(ElementPlus) 后组件能渲染但样式丢了组件库 JS 已带能力,但样式入口没引入给组件库导出 ./style.css 并在消费方显式导入
ElementPlusResolver 配了但构建报找不到 element-plus构建期依赖里根本没装在组件库项目至少安装 element-plus 作为开发依赖
组件库发布后别人还得装 element-plus 但文档没写实际走 external 方案,依赖边界没说清写入 peerDependencies 并在 README 标明
组件库包体积明显变大把 Element Plus 局部能力和样式打进产物评估是否改为 external 策略
课程说 exports.style 但消费方导入不稳定样式出口设计不规范改成 exports["./style.css"]
想保留 Vue API 自动导入但不想把 Element Plus 打进库把自动导入工具和依赖打包策略混在一起保留 AutoImport 对 Vue API 的支持,收敛 ElementPlusResolver 相关打包策略

延伸阅读