Skip to content

04 - 路由与分包

路由配置

app.config.js 概述

src/app.config.js 是 Taro 路由配置入口,定义了:

  • 主包页面列表(22 个)
  • 分包配置(19 个分包)
  • 插件配置(条件性注入)
  • 窗口显示配置
  • 权限配置

主包页面(22个)

路径说明
pages/index首页(非内购模式)
pages/purchase/index内购首页(内购模式时替换为首页)
pages/webviewWebView 容器页
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/purchase17内购(会员、商品、结算、家属分享、选企业)
subpages/guide10导购货架
subpages/store8门店(首页、品牌、商品、自提)
subpages/ecshopx3店铺选择、商家列表
subpages/item2商品列表、详情
subpages/member7会员中心、积分、等级、设置
subpages/marketing7优惠券、兑换券、实名认证
subpages/dianwu20店务POS
subpages/pointshop3积分商城
subpages/community27社区团购
subpages/trade14订单、售后、物流、发票
subpages/game-activity2游戏活动
subpages/mdugc10UGC内容(笔记、话题)
subpages/case3案例
subpages/merchant5商户入驻
subpages/salesman~33业务员
subpages/delivery9配送员
subpages/auth10授权(登录、注册、找回密码)
subpages/prescription2处方药
subpages/i18n1i18n 非默认语言资源分包
marketing~35推广管理、分销、秒杀、团购、会员营销
subpage15软文、订单、二维码购买、PC登录
boost6砍价/翻牌
others10协议、客服、储值

插件配置

插件通过环境变量条件性注入:

微信客服插件

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.scss

3. 注册路由

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