04 - 路由与分包
路由配置
app.config.js 概述
src/app.config.js 是 Taro 路由配置入口,定义了:
- 主包页面列表(22 个)
- 分包配置(19 个分包)
- 插件配置(条件性注入)
- 窗口显示配置
- 权限配置
主包页面(22个)
| 路径 | 说明 |
|---|---|
pages/index | 首页(非内购模式) |
pages/purchase/index | 内购首页(内购模式时替换为首页) |
pages/webview | WebView 容器页 |
pages/category/index | 商品分类 |
pages/cart/espier-index | 购物车 |
pages/cart/espier-checkout | 结算页 |
pages/cart/cashier-result | 支付结果 |
pages/cart/cashier-weapp | 微信收银台(adapay) |
pages/cart/offline-transfer | 线下转账 |
pages/home/landing | 跳转等待页 |
pages/floorguide/index | 楼层引导 |
pages/article/index | 文章详情 |
pages/recommend/list | 种草列表 |
pages/recommend/detail | 种草详情 |
pages/member/item-fav | 收藏页面 |
pages/custom/custom-page | 自定义页面 |
pages/chat/index | 客服 |
pages/liveroom/index | 直播间 |
pages/purchase/auth | 采购授权 |
pages/cart/prescription-information | 补充处方信息 |
pages/cart/add-personnel | 添加用药人员 |
pages/share-land | 太阳码统一落地页 |
pages/reset-password | 邮箱重置密码 |
产品版本首页策略
当前项目只使用 standard(云店 B2C)和 platform(ECShopX BBC)两个产品版本,首页按标准云店入口配置;不纳入内购、官方商城等其他版本的路由策略。
分包配置(19个分包)
| root | 页面数 | 业务域 |
|---|---|---|
subpages/purchase | 17 | 内购(会员、商品、结算、家属分享、选企业) |
subpages/guide | 10 | 导购货架 |
subpages/store | 8 | 门店(首页、品牌、商品、自提) |
subpages/ecshopx | 3 | 店铺选择、商家列表 |
subpages/item | 2 | 商品列表、详情 |
subpages/member | 7 | 会员中心、积分、等级、设置 |
subpages/marketing | 7 | 优惠券、兑换券、实名认证 |
subpages/dianwu | 20 | 店务POS |
subpages/pointshop | 3 | 积分商城 |
subpages/community | 27 | 社区团购 |
subpages/trade | 14 | 订单、售后、物流、发票 |
subpages/game-activity | 2 | 游戏活动 |
subpages/mdugc | 10 | UGC内容(笔记、话题) |
subpages/case | 3 | 案例 |
subpages/merchant | 5 | 商户入驻 |
subpages/salesman | ~33 | 业务员 |
subpages/delivery | 9 | 配送员 |
subpages/auth | 10 | 授权(登录、注册、找回密码) |
subpages/prescription | 2 | 处方药 |
subpages/i18n | 1 | i18n 非默认语言资源分包 |
marketing | ~35 | 推广管理、分销、秒杀、团购、会员营销 |
subpage | 15 | 软文、订单、二维码购买、PC登录 |
boost | 6 | 砍价/翻牌 |
others | 10 | 协议、客服、储值 |
插件配置
插件通过环境变量条件性注入:
微信客服插件
js
// APP_CONTACT_PLUGIN == 'true' 时启用
'contactPlugin': {
'version': '1.4.8',
'provider': 'wx104a1a20c3f81ec2'
}直播插件
js
// APP_LIVE == 'true' 时启用
'live-player-plugin': {
'version': '1.3.5',
'provider': 'wx2b03c6e691cd7370'
}Adapay 支付插件
js
// APP_ADAPAY == 'true' 时启用
'Adapay': {
'version': 'latest',
'provider': 'wx308088053f4ecc3a'
}微信小程序特有配置
usingComponents
微信小程序环境注入 mp-html 富文本组件:
js
if (process.env.TARO_ENV == 'weapp') {
Object.assign(config, {
usingComponents: {
'mp-html': './components/sp-html/mp-weixin/index'
}
})
}i18n 分包预下载
js
if (process.env.TARO_ENV === 'weapp') {
const I18N_SUBPACKAGE_ROOT = 'subpages/i18n'
config.preloadRule = {
'pages/index': { network: 'all', packages: [I18N_SUBPACKAGE_ROOT] },
'pages/purchase/index': { network: 'all', packages: [I18N_SUBPACKAGE_ROOT] }
}
// 确保首页也预下载
const entryPage = config.pages[0]
if (entryPage && !config.preloadRule[entryPage]) {
config.preloadRule[entryPage] = { network: 'all', packages: [I18N_SUBPACKAGE_ROOT] }
}
}窗口与权限配置
Window 配置
js
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: '小程序',
navigationBarTextStyle: 'black'
}权限配置
js
permission: {
'scope.userLocation': {
desc: '您的位置信息将用于定位附近门店'
}
},
requiredPrivateInfos: ['getLocation', 'chooseAddress']分包 API 隔离规则
问题
小程序主包有体积限制(2MB),所有 API 模块如果都从主包导出,会导致主包膨胀。
解决方案
src/api/index.js 只导出主包使用的 API 模块,分包专用 API 在分包内部直接引入:
js
// src/api/index.js
// 主包导出(30个模块)
export { default as article } from './article'
export { default as cart } from './cart'
export { default as item } from './item'
// ... 共30个主包模块
// 分包专用 API 不从主包导出(注释说明)
// 分包内请直接 import from '@/api/community'
// 分包用: community, dianwu, game, boost, mdugc, delivery, merchant分包内使用:
js
// 在 subpages/community/ 下
import communityApi from '@/api/community'
// 而不是
// import { community } from '@/api' // ❌ 会导致主包变大主包优化
js
// config/index.js
mini: {
optimizeMainPackage: { enable: true }, // 主包优化
imageUrlLoaderOption: { limit: 0 }, // 图片不转 base64
}optimizeMainPackage 是 Taro 内置的主包体积优化功能,自动分析依赖关系,将仅被分包使用的模块移到分包。
新增页面步骤
1. 确定页面归属
| 场景 | 放置位置 |
|---|---|
| 核心入口页(首页、购物车、分类) | 主包 pages/ |
| 业务功能页 | 对应分包 subpages/<domain>/ |
| 营销活动页 | marketing/pages/<category>/ |
2. 创建页面文件
bash
# 示例:在 trade 分包新增售后详情页
mkdir -p src/subpages/trade/aftersale-detail
touch src/subpages/trade/aftersale-detail/index.jsx
touch src/subpages/trade/aftersale-detail/index.scss3. 注册路由
在 src/app.config.js 对应分包的 pages 数组中添加:
js
{
root: 'subpages/trade',
pages: [
'list/index',
'detail/index',
'aftersale-detail/index', // ← 新增
]
}4. 页面配置
每个页面可以有自己的 index.config.js:
js
// src/subpages/trade/aftersale-detail/index.config.js
export default {
navigationBarTitleText: '售后详情',
enablePullDownRefresh: true,
usingComponents: {}
}5. 检查路由拦截
如果页面路径可能被路由拦截器匹配(如内购场景的路由重定向),检查 src/plugin/routeIntercept.js 中的 routes 配置是否需要更新。
页面间通信
EventChannel
js
// 页面 A:跳转并监听回传
Taro.navigateTo({ url: '/pages/some-page' })
const channel = Taro.getCurrentOpenerEventChannel?.()
channel?.on('someEvent', (data) => { /* ... */ })
// 页面 B:回传数据
const channel = Taro.getCurrentOpenerEventChannel?.()
channel?.emit('someEvent', { result: 'ok' })Taro.eventCenter
js
// 全局事件总线
Taro.eventCenter.on('cartUpdated', () => { /* ... */ })
Taro.eventCenter.trigger('cartUpdated', { count: 5 })
Taro.eventCenter.off('cartUpdated')项目中
emitOpenerEvent()函数封装了两种方式的回退逻辑:优先使用原生 EventChannel,回退到 eventCenter。
路由工具函数
js
// 获取当前路由信息
import { getCurrentRoute } from '@/utils'
const { path, fullPath, params } = getCurrentRoute()
// 页面跳转
import { navigateTo } from '@/utils'
navigateTo('/subpages/item/detail?item_id=123')
// 构建分享路径
import { buildSharePath } from '@/utils'
const shareUrl = buildSharePath('item_detail', { item_id: '123' })
// → /pages/share-land?from_scene=item_detail&item_id=123