Hvigor允許開發者實現自己的外掛,開發者可以定義自己的構建邏輯,並與他人共享。Hvigor主要提供了兩種方式來實現外掛:基於hvigorfile指令碼開發外掛、基於typescript專案開發。下面以基於hvigorfile指令碼開發外掛進行介紹。
基於hvigorfile指令碼開發
基於hvigorfile.ts指令碼開發的方式,其優點是可實現快速開發,直接編輯工程或模組下hvigorfile.ts即可編寫外掛程式碼,不足之處是在多個專案中,無法方便的進行外掛程式碼的複用和共享分發。
- 匯入模組依賴。
// 匯入介面
import { HvigorPlugin, HvigorNode } from '@ohos/hvigor'
- 編寫外掛程式碼。
在hvigorfile.ts中定義外掛方法,實現HvigorPlugin介面。
// 實現自定義外掛
function customPlugin(): HvigorPlugin {
return {
pluginId: 'customPlugin',
apply(node: HvigorNode) {
// 外掛主體
console.log('hello customPlugin!');
}
}
}
- 在匯出宣告中使用外掛。
export default {
system: appTasks,
plugins:[
customPlugin() // 應用自定義Plugin
]
}
使用hvigorfile外掛動態生成navigation防混淆檔案
我們在使用navigation的系統路由表時,每次新增新頁面,都需要配置一下release環境防混淆。若將這些頁面放在一個固定的目錄下,則與我們的模組化設計相違背,若命名使用固定的字首或字尾,總感覺有點多餘,手動一個一個的新增,雖然符合我們的程式碼規範設計,但就是有點繁瑣。有沒有更方便的方式來處理這個混淆配置呢?
其實我們可以在寫一個hvigorfilew外掛來自動生成混淆配置檔案。我們自定義一個HvigorPlugin任務,透過OhosHapContext物件讀取module.json5檔案中的routerMap欄位,可以獲取系統路由表的名稱,再讀取profile目錄下的路由表。解析json檔案記憶體,並將頁面路徑寫到一個混淆檔案中,這樣每次編譯時,自動生成防混淆檔案,我們只需要引入這個檔案就可以了。示例如下
import { hapTasks, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin'
import { HvigorPlugin, HvigorNode, FileUtil } from '@ohos/hvigor'
function parseRouterMap(): HvigorPlugin {
return {
pluginId: 'parseRouterMap',
apply(node: HvigorNode) {
const hapCtx = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext
const moduleJson = hapCtx.getModuleJsonOpt()
const routerMapName = moduleJson['module']['routerMap'].split(':')[1]
const dir = hapCtx.getModulePath()
const srcFile = FileUtil.pathResolve(dir, 'src', 'main', 'resources', 'base', 'profile', `${routerMapName}.json`)
const json = FileUtil.readJson5(srcFile)
const routerRuleFile = FileUtil.pathResolve(dir, 'obfuscation-router.txt')
FileUtil.ensureFileSync(routerRuleFile)
const routerMapArray = json['routerMap']
let rules = '-keep-file-name\n'
for (const element of routerMapArray) {
const pageSourceFile = element['pageSourceFile']
const path = pageSourceFile.substring(0, pageSourceFile.lastIndexOf('.'))
rules += `${path}\n`
}
FileUtil.writeFileSync(routerRuleFile, rules)
}
}
}
export default {
system: hapTasks,
plugins:[parseRouterMap()]
}
編譯後會在entry目錄下生成obfuscation-router.txt防混淆檔案,只要引入這個檔案就可以了。
使用hvigorfile外掛動態生成navigation頁面列舉名稱
我們在我們navigation的push跳轉到新頁面時,都得提前定義好系統路由表中的頁面name,因為使用的name與系統路由表中定義的name不相同時,跳轉頁面則會白屏。有了前面的經驗,其它我們也可以動態生成一個ets檔案,將系統路由表中的頁面名稱自動生成一個列舉,這樣就不用每次配置系統路由表,還是複製一下名稱了。例如我們的系統路由表是這樣的
{
"routerMap": [
{
"name": "dialog",
"pageSourceFile": "src/main/ets/pages/dialog/DialogPage.ets",
"buildFunction": "dialogBuilder"
},
{
"name": "web",
"pageSourceFile": "src/main/ets/pages/web/WebPage.ets",
"buildFunction": "webBuilder"
},
{
"name": "login",
"pageSourceFile": "src/main/ets/pages/login/LoginPage.ets",
"buildFunction": "loginBuilder"
}
]
}
我們現在實現一個hvigorfile外掛,來解析系統路由表中的name欄位,並生成對應的列舉值。示例如下
import { hapTasks, OhosHapContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin'
import { HvigorPlugin, HvigorNode, FileUtil } from '@ohos/hvigor'
function parseRouterMap(): HvigorPlugin {
return {
pluginId: 'parseRouterMap',
apply(node: HvigorNode) {
const hapCtx = node.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext
const moduleJson = hapCtx.getModuleJsonOpt()
const routerMapName = moduleJson['module']['routerMap'].split(':')[1]
const dir = hapCtx.getModulePath()
const srcFile = FileUtil.pathResolve(dir, 'src', 'main', 'resources', 'base', 'profile', `${routerMapName}.json`)
const json = FileUtil.readJson5(srcFile)
const routerMapFile = FileUtil.pathResolve(dir, 'src', 'main', 'ets', 'Pages.ets')
FileUtil.ensureFileSync(routerMapFile)
const routerMapArray = json['routerMap']
let ss = ''
for (const element of routerMapArray) {
const name = element['name']
ss += ` ${name} = '${name}',\n`
}
ss = `export enum Pages {\n${ss}}`
FileUtil.writeFileSync(routerMapFile, ss)
}
}
}
export default {
system: hapTasks,
plugins:[parseRouterMap()]
}
我們在ets目錄下生成了一個Pages.ets檔案,並將所有navigation頁面生成對應的列舉值,頁面跳轉時,使用這些列舉值就不怕出錯了。Pages.ets內容如下
export enum Pages {
dialog = 'dialog',
web = 'web',
login = 'login',
}