Taro 小程序路(lù)由全自動(dòng)配置 - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

Taro 小程序路(lù)由全自動(dòng)配置

發表時間:2021-1-5

發布人:葵宇科技

浏覽次數:150

前言

使用過 Umi 框架的人一定會對它的約定式路(lù)由印象深刻。在約定式路(lù)由模式下(xià),pages 目錄下(xià)新建文(wén)件,其他頁面即可(kě)直接書寫鍊接進行跳轉。

Taro 框架中(zhōng)自帶了路(lù)由功能,但是每新建一個(gè)頁面文(wén)件後,需要在 app.config.ts 文(wén)件中(zhōng)配置頁面地址,在進行頁面跳轉時,還需要帶上長長的一串鍊接,書寫麻煩的同時還容易出錯。

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

将頁面地址維護到一個(gè)映射表中(zhōng),方便管理和(hé)使用。

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

但是又帶來的新的問(wèn)題,開發一個(gè)頁面,不僅要維護 app.config.ts 還要維護映射表文(wén)件。且參數又長又不美觀。

如(rú)何解決這些問(wèn)題呢(ne)?

經過我不斷摸索,可(kě)以做到新建頁面文(wén)件後,0配置,其他頁面直接調用類似下(xià)面的API,即可(kě)進行跳轉

routerService.toManageAppointments({ roomId, appointmentId, scriptId })
複制代碼

下(xià)圖演示了,删除分包頁面後,自動(dòng)更新 app.config.ts

正文(wén)

實現原理很簡單:1.監聽頁面文(wén)件創建。2.執行腳本修改和(hé)生成代碼。

監聽頁面文(wén)件/文(wén)件夾創建

說到監聽,我們首先會想到 webpack -watch 模式。但要注意的是,webpack 隻監聽代碼依賴樹(shù)中(zhōng)的文(wén)件,即新建的文(wén)件或文(wén)件夾是不會被 webpack 監聽的。那如(rú)何實現監聽頁面文(wén)件的創建呢(ne)?Node 有 watch API 可(kě)以實現這一點,但在各個(gè)平台可(kě)能存在各種各樣的問(wèn)題,因而我使用了 chokidar 去監聽文(wén)件創建。

工具是有了,但怎麼整合到項目中(zhōng)呢(ne)?總不能打開兩個(gè)控制台,一個(gè)跑項目,一個(gè)跑文(wén)件監聽吧。webpack-plugin-chokidar插件可(kě)以解決問(wèn)題,通(tōng)過 taro 的 webpackChain 配置,可(kě)以很容易監聽文(wén)件/文(wén)件夾修改。

插件監聽配置實例如(rú)下(xià)

const basePath = path.resolve(__dirname, '../src');

...
new WebPackPluginChokidar({
  chokidarConfigList: [
    {
      file:  basePath + '/**/pages/**/index.tsx',	// 監聽路(lù)徑(支持主包和(hé)分包)
      opt: { persistent: true, ignoreInitial: true },	// 監聽配置選項( 配置項參考chokidar)
      actions: {
        on: {
          add: ({ compiler, compilation, watcher }, path, ...rest) => {	// 監聽文(wén)件創建
            console.log(`File ${path} has been added`);
          },
        },
      },
    },
  ],
});

複制代碼

在上面代碼中(zhōng),隻需要在 add 回調函數中(zhōng),調用修改代碼腳本即可(kě)。

代碼修改與生成

這一步中(zhōng),需要修改 project.config.json和(hé)app.config.ts,和(hé)生成 routerService.ts 文(wén)件。project.config.json 文(wén)件很好處理,直接在腳本中(zhōng)通(tōng)過 require 引入,當做一個(gè) JS 對象操作,最後通(tōng)過 Node fs API 寫入即可(kě)。

我們修改代碼最常用的是直接 fs.readFile 讀文(wén)件,字符串匹配更換文(wén)本,這樣操作雖然簡單快捷,但精度低,且不夠優雅。

Babel玩的熟的,會使用 babel 解析代碼成 ast,修改 ast, 最後 generate 代碼,再寫入文(wén)件。

ts-morph是一個(gè)新增/修改 typescript 代碼的庫,相比 babel 修改 ts 代碼, 更簡單,更易使用。

我使用了 ts-morph 修改 app.config.ts 和(hé)生成 routerService.ts。

下(xià)面的配置,是我們項目目前在使用的部分配置,嫌麻煩的,可(kě)以直接到這裡下(xià)載 demo,不想安裝這幾個(gè)包的,可(kě)以參考modifyAppConfig,generateRouterService 代碼實現,改一改之後,編譯成 js 代碼,直接在監聽文(wén)件變更的回調函數中(zhōng)使用即可(kě)。

generated

這是一個(gè)代碼生成管理工具。代碼很簡單,它注冊了一個(gè) generated 命令,讀取插件配置文(wén)件夾的配置供插件使用。我們的功能需要通(tōng)過插件實現,安裝該工具後進行下(xià)列配置。

1、在根目錄新建 generated 配置文(wén)件 .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

在這個(gè)插件中(zhōng),實現了修改代碼和(hé)生成routerService文(wén)件。

需要進行下(xià)列配置

1、在根目錄新建 gconfig 文(wén)件夾,文(wén)件夾下(xià)新建 router.ts 配置文(wén)件.

2、寫入配置

import { Config } from 'generated-plugin-taro-router-service'

const basePath = process.cwd()

export const taroRouter: Config = {
  // 源碼目錄
  pageDir: basePath + '/src',
  
  // app.config 路(lù)徑
  appConfigPath: basePath + '/src/app.config.ts',

  // project.config.json 路(lù)徑
  projectConfigPath: basePath + '/project.config.json',

  // 輸出文(wén)件名
  outputFileName: 'routerService',

  /**
   * 導入組件
   * 
   * 輸出的文(wén)件将導入方法
   * import { customNavigateTo } from '@/business/app'
  */
  navigateFnName: 'customNavigateTo', // 導入方法名
  navigateSpecifier: '@/business/app', // 方法導入标識符
  
  /**
   * 格式化文(wén)件名
   * 頁面文(wén)件名可(kě)能會出現類似 edit-name 的寫法,這種 name 無法作為類屬性,所以需要 formatter 函數格式化
  */
  formatter(name) {
	return (name.split('-') || []).reduce((t, c) => t + upFirst(c), '')
  }
}
複制代碼

工具内部沒有直接使用taro 原生的 navigateTo 方法,而是需要手動(dòng)配置方法。一是因為 taro 導出的路(lù)由 API 并不好用,二是 API 封裝在内部,自定義程度不夠高。

shelljs 進行腳本調用

在文(wén)件監聽的回調函數中(zhōng),利用 shelljs 執行 generated 命令即可(kě)。

其他

本文(wén)提到的幾個(gè)倉庫如(rú)下(xià):

  • ts-morph 修改、生成 typescript 代碼
  • chokidar 監聽文(wén)件變動(dòng)
  • webpack-plugin-chokidar 将 chokidar 整合到 webpack 使用,需在 webpack dev 模式下(xià)使用
  • generated 代碼生成管理工具
  • generated-plugin-taro-router-service 修改代碼腳本

相關(guān)案例查看更多