Taro 4 微信小程序搭一个不占主包体积的组件走查台我是这么干的摘要组件越写越多每次想看真实效果都得切到业务页、塞假数据烦得要命。本文讲我怎么在项目里搭一套「组件走查台」——独立分包、中枢注册表、每组件一页、共享布局真机上一键核对像素与浮层。顺手把「漏 import scss」「分包短路径」两个高频翻车点也说了。作者FungLeo 适用Taro 4 / React / 微信小程序 / 任何需要大量自定义组件的团队前言各位看官先把一句话撂这一个项目自定义组件只要超过十个我就建议从搭脚手架那天起把「组件走查台」规划进去。这是基本功不是等项目乱了再补的补丁。我这个项目自定义组件前前后后写了二十多个——按钮、输入框、对话框、底部抽屉、标签、芯片……组件少的时候改完样式切到业务页塞个假数据瞄一眼倒也凑合。可一旦数量上来每次就为看一个按钮圆角对不对还得专门绕到业务页去纯属给自己找罪受。而且有些问题模拟器上根本看不出来——px 和 rpx 的偏差、浮层被 scroll-view 困住、安全区被胶囊挡住——这些玩意儿只有真机才露原形。所以走查台这块从项目一开始我就留了位置。下面是我沉淀下来的搭法各位看官直接抄就行。第一刀它必须是个分包不是主包页面对分包这件事我一开始就把走查台摁在了独立分包里——这是基本的工程直觉不用纠结。原因很硬微信小程序主包有体积上限现在是 2M。走查台是给开发和设计看的不是给用户用的凭什么占主包的体积你要是真把它塞进主包等组件涨到十几个业务页都得给你腾地方。一句话讲就是——走查台是给开发和设计看的不是给用户用的凭什么占主包的体积所以第一刀把整个走查台丢进一个独立分包。分包在用户真正进到那个页面时才会下载平时不占主包。// app.config.ts —— 把走查台整体放进一个独立分包exportdefault{pages:[pages/index/index,// ... 你的主包业务页],subPackages:[{// 分包根目录所有走查页都在它下面不占主包体积root:component-preview,pages:[pages/index/index,// 中枢页组件列表pages/button/index,pages/dialog/index,pages/sheet/index,// ... 每写一个组件预览页就在这里加一行]}]}⚠️分包路径坑我替你踩过了pages里必须写完整路径pages/button/index千万别图省事写成pages/button。写短了编译不报错但 WXSS 会错输出到上级目录样式静默 0 加载你盯着白屏半天不知道哪出了问题。就特么一行路径的事儿。第二刀中枢页 每组件一页分包定下来里面怎么组织我的结构是一个中枢页管列表每个组件一个预览页。miniapp/src/ ├── app.config.ts # subPackages.root component-preview ├── components/ # 你的真实业务组件Button / Dialog / ... └── component-preview/ # 走查台分包独立不占主包 ├── components/ │ └── DemoBlock/ # 共享的标题 描述 内容展示块 ├── styles/ │ └── showcase.scss # 共享页面布局灰底、间距 └── pages/ ├── index/ # 中枢页组件注册表 ├── button/ # 每组件一页 ├── dialog/ └── sheet/中枢页干一件核心的事维护一张组件注册表。每接入一个组件就往表里加一项没开发完的把ready置false列表里自动置灰、点不进去。// component-preview/pages/index/index.tsx —— 中枢页 import { Text, View } from tarojs/components import Taro from tarojs/taro import ./index.scss interface CompItem { key: string name: string desc: string ready: boolean } /** 组件注册表每接入一个组件预览页就在这里加一项 */ const COMPONENTS: CompItem[] [ { key: button, name: Button 按钮, desc: 主要 / 次要 / 文本 / 禁用, ready: true }, { key: dialog, name: Dialog 对话框, desc: 确认 / 警示 / 自定义, ready: true }, { key: sheet, name: BottomSheet 底部抽屉, desc: 列表 / 表单 / 卡片, ready: true }, { key: tag, name: Tag 标签, desc: 默认 / 成功 / 警告, ready: false }, // 还没做置灰 ] export default function PreviewHub() { const handleTap (item: CompItem) { if (!item.ready) return // 没开发完的不让进 Taro.navigateTo({ url: /component-preview/pages/${item.key}/index }) } return ( View classNamepreview-hub View classNamepreview-hub__header Text classNamepreview-hub__title组件走查台/Text Text classNamepreview-hub__sub基础 UI 组件 · 真机核对入口/Text /View View classNamepreview-hub__list {COMPONENTS.map(item ( View key{item.key} className{comp-item ${item.ready ? : comp-item--disabled}} hoverClass{item.ready ? comp-item--hover : } onClick{() handleTap(item)} View classNamecomp-item__main Text classNamecomp-item__name{item.name}/Text Text classNamecomp-item__desc{item.desc}/Text /View {item.ready ? Text classNamecomp-item__arrow›/Text : Text classNamecomp-item__soon待开发/Text} /View ))} /View /View ) }这个ready开关是我给这套走查台定的规矩——组件还没完工就置false列表里自动灰掉、点不进去既不误导自己也不会在评审时露怯。第三刀抽个 DemoBlock别每页重写布局预览页的外壳——「标题 描述 内容区」这套结构我是统一用DemoBlock兜住的再配一份共享的showcase.scss各预览页直接use进来。早年我也一个页一个页手写外壳二十个页面重复的样式类堆成山后来干脆抽成公共组件一劳永逸——这事儿顺手就办了不值当专门讲。// component-preview/components/DemoBlock/index.tsx import { Text, View } from tarojs/components import type { ReactNode } from react import ./index.scss interface DemoBlockProps { title?: string desc?: string children?: ReactNode } export default function DemoBlock({ title, desc, children }: DemoBlockProps) { return ( View classNamedemo-block {title ( View classNamedemo-block__head Text classNamedemo-block__title{title}/Text {desc Text classNamedemo-block__desc{desc}/Text} /View )} View classNamedemo-block__body{children}/View /View ) }// component-preview/styles/showcase.scss —— 各预览页共享的展示布局 // 注意文件名不要带 _ 前缀sass partial 在 webpack alias 下认不到会编译失败 .showcase { min-height: 100vh; background: var(--bg-page); // 走查台用页面灰底方便看清白卡边界 padding: 24px 16px 32px; } .demo-block { background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 16px; __head { margin-bottom: 12px; } __title { font-size: 15px; font-weight: 600; color: var(--color-text-1); } __desc { display: block; margin-top: 4px; font-size: 12px; color: var(--color-text-3); } }小提示上面 scss 里我写的就是px不用手贱改成rpx。Taro 的pxtransform会按designWidth: 375自动 ×2 转成 rpx源码里老老实实写 px 就行。一个预览页写出来就清爽了// component-preview/pages/button/index.tsx import { Text, View } from tarojs/components import Button from /components/Button import DemoBlock from /component-preview/components/DemoBlock import ./index.scss export default function ButtonShowcase() { return ( View classNameshowcase DemoBlock title1. 主要按钮 desc实心填充页面主操作 Button variantprimary主要操作/Button /DemoBlock DemoBlock title2. 次要按钮 desc描边 / 浅底 Button variantoutline次要操作/Button /DemoBlock DemoBlock title3. 禁用态 Button disabled不可点击/Button /DemoBlock /View ) }// component-preview/pages/button/index.scss use /component-preview/styles/showcase as *; // 引入共享布局 别名 不带扩展名 .button-showcase { // 本页特有的布局写这里通用布局已在 showcase 里 }一个让我拍脑门的坑白卡不能套白底我给所有组件都用白色DemoBlock包着。结果轮到 Card 这类本身是白底、还没阴影没描边的组件时——白卡放进白块里边界直接「隐身」根本看不出圆角和描边对不对。办法简单得让人想笑白卡类组件别套白色 DemoBlock改用透明的分区容器让卡片直接落在走查台的灰底上。// 透明分区白卡类组件不要套白底 DemoBlock否则隐身改用透明 Section function Section({ title, desc, children }: { title: string; desc?: string; children: ReactNode }) { return ( View classNamesection View classNamesection__head Text classNamesection__title{title}/Text {desc Text classNamesection__desc{desc}/Text} /View View classNamesection__body{children}/View /View ) }各位看官记住这个凡是预览「白底 / 浅色透明」的组件预览容器必须给个非白底否则你啥也看不清。第四刀注册一个组件三处必须同步这地方容易漏我给团队立过一条铁律每接入一个组件预览页下面三处必须一起改。漏任何一处要么跳转失败、要么样式全丢而且编译都不报错。位置改什么漏了会怎样app.config.ts的subPackages.pages加pages/key/index完整路径navigateTo直接失败进不去中枢页COMPONENTS数组加一项ready: true列表里看不到这个组件预览页index.tsx顶部import ./index.scss样式完全不进包页面白板编译还不报错第三条尤其阴险。import ./index.scss漏写的话Taro 编译一切正常但你那个页的样式压根没打进产物——页面干干净净一张白纸你还得挨个文件去查为什么。我现在新建组件第一件事就是确认 scss 被引了。第五刀从业务页跳进来走查台搭好总得有个入口能进。我在首页业务页底部放了个「查看组件库 ›」的开发入口// pages/index/index.tsx 某处 const goPreview () { Taro.navigateTo({ url: /component-preview/pages/index/index }) } // View classNamedev-link onClick{goPreview}查看组件库 ›/View生产环境你可以拿环境变量包一层或者只在 debug 构建里显示别让真实用户看到这个入口。我倾向保留——开发和设计同事都爱点进去核对反正它在分包里不占主包体积。顺手聊走查台还能干啥除了肉眼看效果它还是个真机核对的好地方像素级核对designWidth/deviceRatio怎么转 rpx模拟器看不准真机一眼便知。浮层与滚动遮罩盖不盖得住、抽屉被 scroll-view 困不困只有真机暴露。安全区自定义导航栏怎么躲状态栏和胶囊走查台里调最方便。给设计 / 测试看甩个二维码过去比截图强一百倍。小结好啦组件走查台怎么搭就讲到这。回头看核心就四样东西独立分包不占主包 中枢注册表ready 开关 每组件一页 共享布局DemoBlock / showcase.scss。剩下都是细节——而细节里最坑的是「漏 import scss」和「分包短路径」这两个编译不报错、运行才露馅的雷。各位看官记住一句话就行走查台是给开发和设计看的别让它进主包也别让它没样式。如果这套搭法帮你省下了重复切页面的功夫希望看官您用发财的小手点个小赞哈要是你有不同的组织方式也欢迎在评论区聊聊让我这个老前端也开开眼。本文由 FungLeo 主导Deepseek 优化校阅转发请注明首发地址谢谢大家
Taro 4 微信小程序:搭一个不占主包体积的组件走查台,我是这么干的
Taro 4 微信小程序搭一个不占主包体积的组件走查台我是这么干的摘要组件越写越多每次想看真实效果都得切到业务页、塞假数据烦得要命。本文讲我怎么在项目里搭一套「组件走查台」——独立分包、中枢注册表、每组件一页、共享布局真机上一键核对像素与浮层。顺手把「漏 import scss」「分包短路径」两个高频翻车点也说了。作者FungLeo 适用Taro 4 / React / 微信小程序 / 任何需要大量自定义组件的团队前言各位看官先把一句话撂这一个项目自定义组件只要超过十个我就建议从搭脚手架那天起把「组件走查台」规划进去。这是基本功不是等项目乱了再补的补丁。我这个项目自定义组件前前后后写了二十多个——按钮、输入框、对话框、底部抽屉、标签、芯片……组件少的时候改完样式切到业务页塞个假数据瞄一眼倒也凑合。可一旦数量上来每次就为看一个按钮圆角对不对还得专门绕到业务页去纯属给自己找罪受。而且有些问题模拟器上根本看不出来——px 和 rpx 的偏差、浮层被 scroll-view 困住、安全区被胶囊挡住——这些玩意儿只有真机才露原形。所以走查台这块从项目一开始我就留了位置。下面是我沉淀下来的搭法各位看官直接抄就行。第一刀它必须是个分包不是主包页面对分包这件事我一开始就把走查台摁在了独立分包里——这是基本的工程直觉不用纠结。原因很硬微信小程序主包有体积上限现在是 2M。走查台是给开发和设计看的不是给用户用的凭什么占主包的体积你要是真把它塞进主包等组件涨到十几个业务页都得给你腾地方。一句话讲就是——走查台是给开发和设计看的不是给用户用的凭什么占主包的体积所以第一刀把整个走查台丢进一个独立分包。分包在用户真正进到那个页面时才会下载平时不占主包。// app.config.ts —— 把走查台整体放进一个独立分包exportdefault{pages:[pages/index/index,// ... 你的主包业务页],subPackages:[{// 分包根目录所有走查页都在它下面不占主包体积root:component-preview,pages:[pages/index/index,// 中枢页组件列表pages/button/index,pages/dialog/index,pages/sheet/index,// ... 每写一个组件预览页就在这里加一行]}]}⚠️分包路径坑我替你踩过了pages里必须写完整路径pages/button/index千万别图省事写成pages/button。写短了编译不报错但 WXSS 会错输出到上级目录样式静默 0 加载你盯着白屏半天不知道哪出了问题。就特么一行路径的事儿。第二刀中枢页 每组件一页分包定下来里面怎么组织我的结构是一个中枢页管列表每个组件一个预览页。miniapp/src/ ├── app.config.ts # subPackages.root component-preview ├── components/ # 你的真实业务组件Button / Dialog / ... └── component-preview/ # 走查台分包独立不占主包 ├── components/ │ └── DemoBlock/ # 共享的标题 描述 内容展示块 ├── styles/ │ └── showcase.scss # 共享页面布局灰底、间距 └── pages/ ├── index/ # 中枢页组件注册表 ├── button/ # 每组件一页 ├── dialog/ └── sheet/中枢页干一件核心的事维护一张组件注册表。每接入一个组件就往表里加一项没开发完的把ready置false列表里自动置灰、点不进去。// component-preview/pages/index/index.tsx —— 中枢页 import { Text, View } from tarojs/components import Taro from tarojs/taro import ./index.scss interface CompItem { key: string name: string desc: string ready: boolean } /** 组件注册表每接入一个组件预览页就在这里加一项 */ const COMPONENTS: CompItem[] [ { key: button, name: Button 按钮, desc: 主要 / 次要 / 文本 / 禁用, ready: true }, { key: dialog, name: Dialog 对话框, desc: 确认 / 警示 / 自定义, ready: true }, { key: sheet, name: BottomSheet 底部抽屉, desc: 列表 / 表单 / 卡片, ready: true }, { key: tag, name: Tag 标签, desc: 默认 / 成功 / 警告, ready: false }, // 还没做置灰 ] export default function PreviewHub() { const handleTap (item: CompItem) { if (!item.ready) return // 没开发完的不让进 Taro.navigateTo({ url: /component-preview/pages/${item.key}/index }) } return ( View classNamepreview-hub View classNamepreview-hub__header Text classNamepreview-hub__title组件走查台/Text Text classNamepreview-hub__sub基础 UI 组件 · 真机核对入口/Text /View View classNamepreview-hub__list {COMPONENTS.map(item ( View key{item.key} className{comp-item ${item.ready ? : comp-item--disabled}} hoverClass{item.ready ? comp-item--hover : } onClick{() handleTap(item)} View classNamecomp-item__main Text classNamecomp-item__name{item.name}/Text Text classNamecomp-item__desc{item.desc}/Text /View {item.ready ? Text classNamecomp-item__arrow›/Text : Text classNamecomp-item__soon待开发/Text} /View ))} /View /View ) }这个ready开关是我给这套走查台定的规矩——组件还没完工就置false列表里自动灰掉、点不进去既不误导自己也不会在评审时露怯。第三刀抽个 DemoBlock别每页重写布局预览页的外壳——「标题 描述 内容区」这套结构我是统一用DemoBlock兜住的再配一份共享的showcase.scss各预览页直接use进来。早年我也一个页一个页手写外壳二十个页面重复的样式类堆成山后来干脆抽成公共组件一劳永逸——这事儿顺手就办了不值当专门讲。// component-preview/components/DemoBlock/index.tsx import { Text, View } from tarojs/components import type { ReactNode } from react import ./index.scss interface DemoBlockProps { title?: string desc?: string children?: ReactNode } export default function DemoBlock({ title, desc, children }: DemoBlockProps) { return ( View classNamedemo-block {title ( View classNamedemo-block__head Text classNamedemo-block__title{title}/Text {desc Text classNamedemo-block__desc{desc}/Text} /View )} View classNamedemo-block__body{children}/View /View ) }// component-preview/styles/showcase.scss —— 各预览页共享的展示布局 // 注意文件名不要带 _ 前缀sass partial 在 webpack alias 下认不到会编译失败 .showcase { min-height: 100vh; background: var(--bg-page); // 走查台用页面灰底方便看清白卡边界 padding: 24px 16px 32px; } .demo-block { background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 16px; __head { margin-bottom: 12px; } __title { font-size: 15px; font-weight: 600; color: var(--color-text-1); } __desc { display: block; margin-top: 4px; font-size: 12px; color: var(--color-text-3); } }小提示上面 scss 里我写的就是px不用手贱改成rpx。Taro 的pxtransform会按designWidth: 375自动 ×2 转成 rpx源码里老老实实写 px 就行。一个预览页写出来就清爽了// component-preview/pages/button/index.tsx import { Text, View } from tarojs/components import Button from /components/Button import DemoBlock from /component-preview/components/DemoBlock import ./index.scss export default function ButtonShowcase() { return ( View classNameshowcase DemoBlock title1. 主要按钮 desc实心填充页面主操作 Button variantprimary主要操作/Button /DemoBlock DemoBlock title2. 次要按钮 desc描边 / 浅底 Button variantoutline次要操作/Button /DemoBlock DemoBlock title3. 禁用态 Button disabled不可点击/Button /DemoBlock /View ) }// component-preview/pages/button/index.scss use /component-preview/styles/showcase as *; // 引入共享布局 别名 不带扩展名 .button-showcase { // 本页特有的布局写这里通用布局已在 showcase 里 }一个让我拍脑门的坑白卡不能套白底我给所有组件都用白色DemoBlock包着。结果轮到 Card 这类本身是白底、还没阴影没描边的组件时——白卡放进白块里边界直接「隐身」根本看不出圆角和描边对不对。办法简单得让人想笑白卡类组件别套白色 DemoBlock改用透明的分区容器让卡片直接落在走查台的灰底上。// 透明分区白卡类组件不要套白底 DemoBlock否则隐身改用透明 Section function Section({ title, desc, children }: { title: string; desc?: string; children: ReactNode }) { return ( View classNamesection View classNamesection__head Text classNamesection__title{title}/Text {desc Text classNamesection__desc{desc}/Text} /View View classNamesection__body{children}/View /View ) }各位看官记住这个凡是预览「白底 / 浅色透明」的组件预览容器必须给个非白底否则你啥也看不清。第四刀注册一个组件三处必须同步这地方容易漏我给团队立过一条铁律每接入一个组件预览页下面三处必须一起改。漏任何一处要么跳转失败、要么样式全丢而且编译都不报错。位置改什么漏了会怎样app.config.ts的subPackages.pages加pages/key/index完整路径navigateTo直接失败进不去中枢页COMPONENTS数组加一项ready: true列表里看不到这个组件预览页index.tsx顶部import ./index.scss样式完全不进包页面白板编译还不报错第三条尤其阴险。import ./index.scss漏写的话Taro 编译一切正常但你那个页的样式压根没打进产物——页面干干净净一张白纸你还得挨个文件去查为什么。我现在新建组件第一件事就是确认 scss 被引了。第五刀从业务页跳进来走查台搭好总得有个入口能进。我在首页业务页底部放了个「查看组件库 ›」的开发入口// pages/index/index.tsx 某处 const goPreview () { Taro.navigateTo({ url: /component-preview/pages/index/index }) } // View classNamedev-link onClick{goPreview}查看组件库 ›/View生产环境你可以拿环境变量包一层或者只在 debug 构建里显示别让真实用户看到这个入口。我倾向保留——开发和设计同事都爱点进去核对反正它在分包里不占主包体积。顺手聊走查台还能干啥除了肉眼看效果它还是个真机核对的好地方像素级核对designWidth/deviceRatio怎么转 rpx模拟器看不准真机一眼便知。浮层与滚动遮罩盖不盖得住、抽屉被 scroll-view 困不困只有真机暴露。安全区自定义导航栏怎么躲状态栏和胶囊走查台里调最方便。给设计 / 测试看甩个二维码过去比截图强一百倍。小结好啦组件走查台怎么搭就讲到这。回头看核心就四样东西独立分包不占主包 中枢注册表ready 开关 每组件一页 共享布局DemoBlock / showcase.scss。剩下都是细节——而细节里最坑的是「漏 import scss」和「分包短路径」这两个编译不报错、运行才露馅的雷。各位看官记住一句话就行走查台是给开发和设计看的别让它进主包也别让它没样式。如果这套搭法帮你省下了重复切页面的功夫希望看官您用发财的小手点个小赞哈要是你有不同的组织方式也欢迎在评论区聊聊让我这个老前端也开开眼。本文由 FungLeo 主导Deepseek 优化校阅转发请注明首发地址谢谢大家