您當前位置>首頁 » 新聞資(zī)訊 » 小程序相關(guān) >
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
實現原理很簡單: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 修改代碼腳本