乐趣区

小程序拍了拍你来看看如何避开路由雷区

全文阅读时长 6 分钟,案例为真实事件改编,小程序名称、人名仅为代号,如有雷同……那我就改。

典型案例

在一个夜黑风高的夜晚,“xx 饭很多”百度智能小程序悄然上线,目录结构如下:

├── pages
│   └── home
│       ├── index.js
│       ├── index.json
│       ├── index.css
│       └── index.swan
│   └── eat // 大口吃
│       ├── index.js
│       ...
│   └── meat // 肉
│       ├── index.js
│       ...
│    └── drink // 大碗喝
│       ├── index.js
│       ...
│    └── wine // 酒
│       ├── index.js
│       ...
│    ...
├── app.json
├── app.css
├── app.js

其中,app.jsonpages 包含了小程序的所有页面地址:

{
    ...
    pages: [
      "pages/home/index",
      "pages/eat/index",
      "pages/meat/index",
      "pages/drink/index",
      "pages/wine/index",
        ...
    ]
}

为了能让自家小程序接入搜索流量,前端小明,第一时间在开发者平台提交了自然搜索资源:

功夫不负有心人,“xx 饭很多”小程序终于被搜索引擎收录,可以搜到了。

……

数月后,在老板的英(zi)明(ben)指(bi)挥(po)下,“xx 饭很多”小程序,功能不断迭,实现了满汉全席;而公司,为了提升流量傍大腿、砸银子,众多小程序页面都被投放了广告渠道。

与此同时,小程序体积变得愈发庞大,性能体验也遭到了严峻考验……

优秀如小明,怎会被难倒,他当即选择了分包加载,进行性能优化:

 // 分包 A
├── packageA
│   └── eat
│         ├── index.js
│      ├── index.json
│      ├── index.css
│      └── index.swan
│   └── meat
│        ├── index.js
│          ...
│   └── ...
│ // 分包 B
├── packageB
│    └── drink
│         ├── index.js
│       ...
│    └── wine
│         ├── index.js
│         ...
│    └── ...
├── pages
│    └── home
│      ├── index.js
│       ...
├── app.js
├── app.json
├── app.css

app.json 则变成了这个样子:

{
  // 主包配置
  "pages": [
      "pages/home/index",
      ...
   ],
   // 分包入口及配置
  "subPackages": [
    {
      "root": "packageA",
      "pages": [
          "eat/index",
          "meat/index",
          ...
       ]
    },
    {
      "root": "packageB",
      "pages": [
          "drink/index",
          "wine/index",
          ...
       ]
    }
  ]
}

然而,包体积虽然小了——之前投放的地址,却失效了!

由于搜索引擎收录的是失效死链,“xx 饭很多”小程序被降级了!

因为被降级,资源提交的配额减少了!

不仅如此,之前投放过的所有渠道,都需要协调资源从新替换,渠道的上线时间不可控……白花花的银子付诸流水!

老板龙颜大怒,小明束手无策……

求问:小明距离被开还有几天??

如何解决

其实,如果配置了小程序的自定义路由映射规则,小明的悲剧便不会发生。

app.json 中存在 routes 字段,框架则认为该小程序启用了自定义路由,将根据 routes 中的映射规则获取路径。

  // 主包配置
  "pages": [
      "pages/home/index",
      ...
   ],
   // 分包入口及配置
  "subPackages": [
    {
      "root": "packageA",
      "pages": [
          "eat/index",
          "meat/index",
          ...
       ]
    },
    {
      "root": "packageB",
      "pages": [
         "drink/index",
          "wine/index",
          ...
       ]
    }
  ],
  // 自定义路由
  routes: [
      {
         "path": "home", // 投放入口,scheme 中的 path
      "page": "pages/home/index" // 真实的物理存储路径
    }, {
         "path": "eat",
      "page": "packageA/eat/index"
    }, {
         "path": "drink",
      "page": "packageB/drink/index"
    }, {
         "path": "wine",
      "page": "packageB/wine/index"
    }, {
         "path": "meat",
      "page": "packageA/meat/index"
    },
    ...
  ]
}

通过配置自定义路由,可以使源码结构与配置路径解耦,组织目录变得更加灵活,方便代码重构。

接下来,我们用一张图,简单说明下自定义路由的具体映射规则:

映射规则

规则还在哪里生效

使用自定义路由后,小程序框架相关的 api、组件、事件等也会采用新的路由规则:

包含 path/url 参数的 api

swan.navigateToswan.switchTabswan.navigateToSmartProgramswan.openShare等 api 中的 path、url 参数;

// 以 navigateTo 为例,home 为自定义路由的 path,对应的真实物理地址是 'pages/home/index'
 swan.navigateTo({url: 'home'});

导航组件

navigator组件的 url 属性;

// home 为自定义路由的 path,对应的真实物理地址是 'pages/home/index'
<navigator url="home" />

分享、转发事件

页面的事件处理函数 onShareAppMessage,返回对象的path 字段;

Page({
    data: {title: 'xx 饭很多信息列表'},
    onShareAppMessage() {
        return {
            title: this.data.title,
            content: 'xx 饭很多信息列表',
            imageUrl: '',
            // home 为自定义路由的 path,对应的真实物理地址是 'pages/home/index'
            path: 'home',
            success(res) {// 分享成功},
            fail(err) {// 分享失败}
        };
    }
});

打开小程序的方法

调起小程序的相关 sdk,其中的 path 字段

// 该方法使用前,需要引入调起 sdk 的文件
window.swanInvoke({
    appKey: '4fecoAqgCIUtzIyA4FAPgoyrc4oUc25c',
    // home 为自定义路由的 path,对应的真实物理地址是 'pages/home/index'
    path: 'home', 
    query: {
        id: 1,
        type: 'a'
    }
});

routes 的框架原理

调起小程序 和使用 swan.navigateTo 为例,简单说下框架层对于自定义路由都做了啥:

前置名词解释 Swanjs 是百度智能小程序的前端框架,NAFramework代表小程序框架客户端层,server为小程序服务端。

结尾

总之,简单的 routes 配置只需 几分钟 ,未雨绸缪 千秋万代——愿小明们不再哭泣~????

退出移动版