uniapp中使用unocss适配多端

在 uni-app 中适配多端的 UnoCSS 安装与配置指南(H5/微信小程序/飞书 H5)

本文档规范化说明如何在 uni-app 项目中接入 UnoCSS,并同时适配 H5、微信小程序(mp-weixin)与飞书 H5(H5 容器)等多端场景。内容包含版本选择、安装命令、关键配置、使用示例,以及常见问题与排错建议。

一、版本与前置条件

  • 推荐版本(与本项目已验证):
    • unocss: 0.62.3
    • unocss-preset-weapp: 66.0.2
    • @unocss/reset: 0.62.3(仅 H5 使用)
    • vite: 5.2.x
    • vue: 3.4.x/3.5.x(与 @dcloudio 版本需兼容)
  • Node.js 与包管理器:Node 18+,pnpm 10+
  • uni-app 3 + Vite 构建链(@dcloudio/vite-plugin-uni)

说明:不同版本组合会影响插件 ESM/CJS 加载与 DevServer 行为,推荐按上面版本锁定,避免不必要的兼容问题。

二、安装依赖

bash 复制代码
pnpm add -D unocss@0.62.3 unocss-preset-weapp@66.0.2 @unocss/reset@0.62.3

三、关键文件与配置

1) Vite 插件配置(解决 ESM-only 与插件顺序)

文件:vite.config.ts

要点:

  • 使用动态导入加载 unocss/vite,规避 ESM-only 被 CJS require 导致的报错。
  • 插件顺序必须保证 UnoCSS()uni() 之前,使得小程序端的类名转换在 uni 编译前生效。

示例:

ts 复制代码
import { fileURLToPath, URL } from "node:url";
import uni from "@dcloudio/vite-plugin-uni";
import { defineConfig } from "vite";

export default defineConfig(async () => {
  const { default: UnoCSS } = await import("unocss/vite");
  return {
    plugins: [UnoCSS(), uni()],
    resolve: {
      alias: {
        "@": fileURLToPath(new URL("./src", import.meta.url)),
      },
    },
  };
});

2) UnoCSS 跨端预设切换

文件:uno.config.ts

要点:

  • H5:使用 presetUno + presetAttributify,获得完整的原子化体验。
  • 微信小程序:使用 presetWeapp({ platform: 'uniapp' }),并启用 transformerAttributifytransformerClass,将任意值语法如 color-[red] 转换为小程序安全类名(如 _lfl_..._lfr_)。
  • 可按需设置 whRpxprefixpreflightarbitraryVariants 等选项。

示例:

ts 复制代码
import { presetAttributify, presetUno } from "unocss";
import { presetWeapp } from "unocss-preset-weapp";
import { transformerAttributify, transformerClass } from "unocss-preset-weapp/transformer";

const isH5 = process.env.UNI_PLATFORM === "h5";

export default {
  presets: isH5
    ? [presetUno(), presetAttributify()]
    : [
        presetWeapp({
          platform: "uniapp",
          // prefix: 'u-',
          // whRpx: true,
          // preflight: true,
          // arbitraryVariants: true,
        }),
      ],
  transformers: isH5 ? [] : [transformerAttributify(), transformerClass()],
  shortcuts: [{ center: "flex items-center justify-center" }],
};

3) 入口样式引入

文件:src/main.ts

要点:

  • H5 端引入 @unocss/reset/tailwind.css(仅在 H5 条件编译),保证一致的 CSS reset。
  • 所有端统一引入 uno.css

示例:

ts 复制代码
import { createSSRApp } from "vue";
import App from "./App.vue";
// #ifdef H5
import "@unocss/reset/tailwind.css";
// #endif
import "uno.css";

export function createApp() {
  const app = createSSRApp(App);
  return {
    app,
  };
}

四、使用示例

在任意 *.vue 模板中:

vue 复制代码
<template>
  <view class="content">
    <view class="color-[red] m-auto w-[700rpx] bg-[red] font-bold text-[30rpx]">飞鼠</view>
    <!-- 或属性式(Attributify)写法: -->
    <!-- <view color="[red]" font="bold" text="[30rpx]" bg="[red]" w="[700rpx]" m="auto" /> -->
  </view>
  <!-- 小程序端构建后将生成 `_lfl_..._lfr_` 风格的安全类名,并汇总到 app.wxss -->
  <!-- H5 端直接使用原子类名 -->
</template>

五、构建与运行

  • H5 开发/构建:
    • pnpm dev:h5
    • pnpm build:h5
  • 微信小程序开发/构建:
    • pnpm dev:mp-weixin
    • pnpm build:mp-weixin
    • 在微信开发者工具中导入 dist/build/mp-weixin 运行(注意不要导入 dev 目录)。
  • 飞书 H5 应用:
    • 与 H5 一致(容器内运行),按飞书应用接入要求配置入口与权限。

六、常见问题与排错

  1. Vite 报错:ESM-only 插件无法被 require 加载(unocss/vite
  • 现象:在打包/加载 vite.config.ts 时提示 ESM-only cannot be loaded by require。
  • 解决:在 vite.config.ts 使用 await import('unocss/vite') 动态导入。
  1. 小程序端类名被拆分(如 color- redtext- 30rpx),页面 wxss 为空
  • 原因:未在 uni 编译前完成 weapp 类名转换;或错误使用了 H5 预设。
  • 解决:
    • 确保 UnoCSS() 插件在 uni() 之前;
    • 小程序端使用 presetWeapp({ platform: 'uniapp' }),并启用 transformerAttributify/transformerClass
    • 构建后样式集中在 app.wxss,页面级 index.wxss 为空属正常。
  1. H5 样式初始化不一致
  • 解决:仅在 H5 条件引入 @unocss/reset/tailwind.css,避免影响小程序端。
  1. 任意值/十六进制颜色等不生效
  • 检查是否在小程序端使用了 presetUno(不应使用)。
  • 确认类名构建后已被转换为 _lfl_..._lfr_,并出现在 app.wxss
  1. HMR/白屏(TopLevelAwait 相关)
  • 如遇浏览器不支持 Top level await,可在 UnoCSS({ hmrTopLevelAwait: false }) 关闭(按需)。
  1. 依赖与 Peer 依赖告警
  • @dcloudio 生态对 vue 版本较敏感,建议按模板/官方推荐范围锁定。

七、可选高级配置

  • presetWeapp 选项:
    • prefix: 为生成的类名前缀,避免与其他框架冲突。
    • whRpx: 宽高是否默认 rpx 单位。
    • preflight: 是否注入基础样式(可设为 'on-demand')。
    • arbitraryVariants: 任意变体开关,性能敏感时可关闭。
    • transformRules: 自定义转换规则(极端场景下微调)。

八、结论与最佳实践

  • 多端共存策略:
    • H5 用 presetUno + attributify,获得最完整的原子化能力;
    • 小程序用 presetWeapp + transformers,确保类名安全与 css 汇总。
  • 构建链顺序关键:UnoCSS() 必须在 uni() 之前。
  • 样式归集:小程序端 UnoCSS 输出集中在 app.wxss,无需每页单独产出。
  • 降本与稳定性:锁定兼容版本,避免跨大版本升级导致构建链异常。

如需扩展主题色、设计系统变量或新增快捷类(shortcuts),可在 uno.config.ts 中统一维护,保证多端一致性。

相关推荐
tangbin5830851 分钟前
iOS Swift 工具类:数据转换工具 ParseDataTool
前端
潜水豆3 分钟前
AI 时代的前端究竟还能积累什么
前端
www_stdio3 分钟前
手写 instanceof:深入理解 JavaScript 原型与继承机制
前端·javascript·html
boombb7 分钟前
国际化方案:多环境、多语言、动态加载的完整实践
前端
狗哥哥9 分钟前
我是如何治理一个混乱的 Pinia 状态管理系统的
前端·vue.js·架构
一 乐25 分钟前
物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot
测试人社区—527228 分钟前
你的单元测试真的“单元”吗?
前端·人工智能·git·测试工具·单元测试·自动化·log4j
c骑着乌龟追兔子30 分钟前
Day 32 函数专题1:函数定义与参数
开发语言·前端·javascript
fruge38 分钟前
前端性能优化实战:首屏加载从 3s 优化到 800ms
前端·性能优化
zlpzlpzyd1 小时前
vue.js 2和vue.js 3的生命周期与对应的钩子函数区别
前端·javascript·vue.js