Taro 小程序路由全自动配置
发表时间:2021-1-5
发布人:葵宇科技
浏览次数:236
使用过 Umi 框架的人一定会对它的约定式路由印象深刻。在约定式路由模式下,pages 目录下新建文件,其他页面即可直接书写链接进行跳转。
Taro 框架中自带了路由功能,但是每新建一个页面文件后,需要在 app.config.ts 文件中配置页面地址,在进行页面跳转时,还需要带上长长的一串链接,书写麻烦的同时还容易出错。
navigateTo({
url: `/package-appointment/pages/manage-appointments/index?roomId=${roomId}&appointmentId=${appointmentId}&scriptId=${scriptId}`
})
复制代码
将页面地址维护到一个映射表中,方便管理和使用。
navigateTo({
url: `${URLs.ManageAppointment}?roomId=${roomId}&appointmentId=${appointmentId}&scriptId=${scriptId}`
})
复制代码
但是又带来的新的问题,开发一个页面,不仅要维护 app.config.ts 还要维护映射表文件。且参数又长又不美观。
如何解决这些问题呢?
经过我不断摸索,可以做到新建页面文件后,0配置,其他页面直接调用类似下面的API,即可进行跳转
routerService.toManageAppointments({ roomId, appointmentId, scriptId })
复制代码
下图演示了,删除分包页面后,自动更新 app.config.ts

实现原理很简单:1.监听页面文件创建。2.执行脚本修改和生成代码。
监听页面文件/文件夹创建说到监听,我们首先会想到 webpack -watch 模式。但要注意的是,webpack 只监听代码依赖树中的文件,即新建的文件或文件夹是不会被 webpack 监听的。那如何实现监听页面文件的创建呢?Node 有 watch API 可以实现这一点,但在各个平台可能存在各种各样的问题,因而我使用了 chokidar 去监听文件创建。
工具是有了,但怎么整合到项目中呢?总不能打开两个控制台,一个跑项目,一个跑文件监听吧。webpack-plugin-chokidar插件可以解决问题,通过 taro 的 webpackChain 配置,可以很容易监听文件/文件夹修改。
插件监听配置实例如下
const basePath = path.resolve(__dirname, '../src');
...
new WebPackPluginChokidar({
chokidarConfigList: [
{
file: basePath + '/**/pages/**/index.tsx', // 监听路径(支持主包和分包)
opt: { persistent: true, ignoreInitial: true }, // 监听配置选项( 配置项参考chokidar)
actions: {
on: {
add: ({ compiler, compilation, watcher }, path, ...rest) => { // 监听文件创建
console.log(`File ${path} has been added`);
},
},
},
},
],
});
复制代码
在上面代码中,只需要在 add 回调函数中,调用修改代码脚本即可。
这一步中,需要修改 project.config.json和app.config.ts,和生成 routerService.ts 文件。project.config.json 文件很好处理,直接在脚本中通过 require 引入,当做一个 JS 对象操作,最后通过 Node fs API 写入即可。
我们修改代码最常用的是直接 fs.readFile 读文件,字符串匹配更换文本,这样操作虽然简单快捷,但精度低,且不够优雅。
Babel玩的熟的,会使用 babel 解析代码成 ast,修改 ast, 最后 generate 代码,再写入文件。
ts-morph是一个新增/修改 typescript 代码的库,相比 babel 修改 ts 代码, 更简单,更易使用。
我使用了 ts-morph 修改 app.config.ts 和生成 routerService.ts。
下面的配置,是我们项目目前在使用的部分配置,嫌麻烦的,可以直接到这里下载 demo,不想安装这几个包的,可以参考modifyAppConfig,generateRouterService 代码实现,改一改之后,编译成 js 代码,直接在监听文件变更的回调函数中使用即可。
generated
这是一个代码生成管理工具。代码很简单,它注册了一个 generated 命令,读取插件配置文件夹的配置供插件使用。我们的功能需要通过插件实现,安装该工具后进行下列配置。
1、在根目录新建 generated 配置文件 .generatedrc.ts
2、注册插件
import { GeneratedrcConfig } from 'generated'
const generatedrc: GeneratedrcConfig = {
configDir: './gconfig', // generated 插件配置目录
plugins: [
'generated-plugin-taro-router-service' // 注册插件
],
}
export default generatedrc
复制代码
generated-plugin-taro-router-service
在这个插件中,实现了修改代码和生成routerService文件。
需要进行下列配置
1、在根目录新建 gconfig 文件夹,文件夹下新建 router.ts 配置文件.
2、写入配置
import { Config } from 'generated-plugin-taro-router-service'
const basePath = process.cwd()
export const taroRouter: Config = {
// 源码目录
pageDir: basePath + '/src',
// app.config 路径
appConfigPath: basePath + '/src/app.config.ts',
// project.config.json 路径
projectConfigPath: basePath + '/project.config.json',
// 输出文件名
outputFileName: 'routerService',
/**
* 导入组件
*
* 输出的文件将导入方法
* import { customNavigateTo } from '@/business/app'
*/
navigateFnName: 'customNavigateTo', // 导入方法名
navigateSpecifier: '@/business/app', // 方法导入标识符
/**
* 格式化文件名
* 页面文件名可能会出现类似 edit-name 的写法,这种 name 无法作为类属性,所以需要 formatter 函数格式化
*/
formatter(name) {
return (name.split('-') || []).reduce((t, c) => t + upFirst(c), '')
}
}
复制代码
工具内部没有直接使用taro 原生的 navigateTo 方法,而是需要手动配置方法。一是因为 taro 导出的路由 API 并不好用,二是 API 封装在内部,自定义程度不够高。
在文件监听的回调函数中,利用 shelljs 执行 generated 命令即可。
本文提到的几个仓库如下:
- ts-morph 修改、生成 typescript 代码
- chokidar 监听文件变动
- webpack-plugin-chokidar 将 chokidar 整合到 webpack 使用,需在 webpack dev 模式下使用
- generated 代码生成管理工具
- generated-plugin-taro-router-service 修改代码脚本








