Taro 小程序路由全自动配置

前言

使用过 Umi 框架的人必定会对它的约定式路由印象深入。在约定式路由模式下,pages 目录下新建文件,其余页面便可直接书写连接进行跳转。webpack

Taro 框架中自带了路由功能,可是每新建一个页面文件后,须要在 app.config.ts 文件中配置页面地址,在进行页面跳转时,还须要带上长长的一串连接,书写麻烦的同时还容易出错。git

navigateTo({
  url: `/package-appointment/pages/manage-appointments/index?roomId=${roomId}&appointmentId=${appointmentId}&scriptId=${scriptId}`
})
复制代码

将页面地址维护到一个映射表中,方便管理和使用。github

navigateTo({
  url: `${URLs.ManageAppointment}?roomId=${roomId}&appointmentId=${appointmentId}&scriptId=${scriptId}`
})
复制代码

可是又带来的新的问题,开发一个页面,不只要维护 app.config.ts 还要维护映射表文件。且参数又长又不美观。web

如何解决这些问题呢?typescript

通过我不断摸索,能够作到新建页面文件后,0配置,其余页面直接调用相似下面的API,便可进行跳转shell

routerService.toManageAppointments({ roomId, appointmentId, scriptId })
复制代码

下图演示了,删除分包页面后,自动更新 app.config.tsnpm

正文

实现原理很简单:1.监听页面文件建立。2.执行脚本修改和生成代码。json

监听页面文件/文件夹建立

说到监听,咱们首先会想到 webpack -watch 模式。但要注意的是,webpack 只监听代码依赖树中的文件,即新建的文件或文件夹是不会被 webpack 监听的。那如何实现监听页面文件的建立呢?Node 有 watch API 能够实现这一点,但在各个平台可能存在各类各样的问题,于是我使用了 chokidar 去监听文件建立。babel

工具是有了,但怎么整合到项目中呢?总不能打开两个控制台,一个跑项目,一个跑文件监听吧。webpack-plugin-chokidar插件能够解决问题,经过 taro 的 webpackChain 配置,能够很容易监听文件/文件夹修改。markdown

插件监听配置实例以下

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.jsonapp.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,不想安装这几个包的,能够参考modifyAppConfiggenerateRouterService 代码实现,改一改以后,编译成 js 代码,直接在监听文件变动的回调函数中使用便可。

generated

这是一个代码生成管理工具。代码很简单,它注册了一个 generated 命令,读取插件配置文件夹的配置供插件使用。咱们的功能须要经过插件实现,安装该工具后进行下列配置。

一、在根目录新建 generated 配置文件 .generatedrc.ts

二、注册插件

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文件。

须要进行下列配置

一、在根目录新建 gconfig 文件夹,文件夹下新建 router.ts 配置文件.

二、写入配置

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 进行脚本调用

在文件监听的回调函数中,利用 shelljs 执行 generated 命令便可。

其余

本文提到的几个仓库以下:

相关文章
相关标签/搜索