@kinngyo/wx-refactor
v0.0.2
Published
用于重写小程序 `Page` 生命周期,在页面 `onLoad`、`onShow` 等生命周期执行前插入自定义逻辑。
Readme
wx-refactor
用于重写小程序 Page 生命周期,在页面 onLoad、onShow 等生命周期执行前插入自定义逻辑。
安装
yarn add @kinngyo/wx-refactor生命周期

核心概念
Refactor 会重写全局 Page,在页面生命周期执行前插入自定义逻辑。
每个被重写的生命周期都会提供两个执行入口:
runner():立即执行原始生命周期interceptor(beforeCallback?):把前置任务和原始生命周期加入延迟任务链,等待flush()执行
同一次生命周期触发时,runner() 和 interceptor() 只能调用一次;重复调用会直接抛出错误。
API
| 属性 | 参数 | 返回 | 说明 | 默认值 | | -------------------- | ------------------------------------------------------ | ------------- | ------------------ | ---------------- | | Refactor.Constructor | key?: string | Refactor | 定义页面自定义 key | 'customRefactor' | | Refactor.on | hook: RefactorHook, hookCallback: RefactorHookCallback | Refactor | 监听 hook | | | Refactor.listen | - | - | 完成页面监听 | | | Refactor.flush | - | Promise | 执行链式任务 | |
clear() 仅用于兼容历史调用,当前使用请统一调用 flush()。
types
type BeforeCallback = () => Promise<void> | void
type InterceptorFn = (beforeCallback?: BeforeCallback) => void
interface RefactorHookContext {
interceptor: InterceptorFn
runner: () => void
instance?: WechatMiniprogram.Page.TrivialInstance
options?: Record<string, any>
}
type RefactorHookCallback = (ctx: RefactorHookContext) => void初始化
import Refactor from '@kinngyo/wx-refactor'
const refactor = new Refactor()
const loginTask = silentLogin()
refactor
.on('onLoad', ({ runner, interceptor }) => {
if (needDelay()) {
interceptor(() => {
/* onBeforeCallback */
})
return
}
// 立即执行原始 onLoad
runner()
})
.on('onShow', ({ runner }) => {
runner()
})
.listen()listen() 需要在页面执行 Page({...}) 之前调用。
启动入口
主包入口:
import Refactor from '@kinngyo/wx-refactor'
const refactor = new Refactor()
refactor
.on('onLoad', ({ runner }) => {
runner()
})
.on('onShow', ({ runner }) => {
runner()
})
.listen()
App({
onLaunch() {
/* ... */
},
})普通分包依赖主包启动。主包已经完成 listen() 时,普通分包页面会命中重写后的 Page。
独立分包可以不先加载主包,因此独立分包冷启动时不能依赖主包初始化。独立分包内也需要在页面注册前执行一次初始化:
import Refactor from '@kinngyo/wx-refactor'
const refactor = new Refactor()
refactor
.on('onLoad', ({ runner }) => {
runner()
})
.listen()建议同一个运行上下文只初始化一次。当前版本使用 Page.prototype.__refactor__ 标记是否已重写,重复初始化没有业务收益。
延迟任务链
调用 interceptor() 后,原始生命周期不会立即执行,而是进入 chains 队列。
refactor
.on('onLoad', ({ interceptor }) => {
interceptor(async () => {
await prepare()
})
})
.listen()
refactor.flush().then(() => {
console.log('所有任务执行完成')
})
// 或使用 await
await refactor.flush()执行顺序:
// beforeCallback1 -> 原始生命周期1 -> beforeCallback2 -> 原始生命周期2 ...flush() 会消费当前 chains 队列;执行过程中新增到 chains 的任务也会继续按队列顺序执行。
静默登录示例
import Refactor from '@kinngyo/wx-refactor'
const refactor = new Refactor()
refactor
.on('onLoad', ({ runner, interceptor }) => {
if (isLogin()) {
runner()
return
}
// 登录流程在外部执行
silentLogin().then(() => {
// 登录完成后,恢复所有被挂起的生命周期
refactor.flush()
})
interceptor()
})
.on('onShow', ({ runner, interceptor }) => {
if (isLogin()) {
runner()
return
}
interceptor()
})
.listen()执行逻辑:
// 1. silentLogin() 在外部启动
// 2. 页面生命周期触发时,如果未登录则调用 interceptor() 挂起原生命周期
// 3. 登录完成后调用 refactor.flush()
// 4. flush() 恢复执行被挂起的原生命周期静默登录不应放进 interceptor(beforeCallback) 中;interceptor() 只负责挂起并恢复原始生命周期。
页面级配置
// 默认:重写 onLoad 和 onShow
Page({
onLoad() {
/* ... */
},
})
// 自定义:只重写指定 hooks
Page({
customRefactor: ['onLoad'],
onLoad() {
/* ... */
},
onShow() {
/* 不会被拦截 */
},
})
// 显式启用默认 hooks
Page({
customRefactor: true,
})
// 禁用重写
Page({
customRefactor: false,
})
// onReady 需要通过数组显式启用
Page({
customRefactor: ['onLoad', 'onReady'],
})默认重写 onLoad、onShow。onReady 只有在 customRefactor 数组中显式配置时才会重写。
执行标记
重写后会自动在页面实例上添加执行标记:
Page({
onLoad() {
console.log(this.__isOnLoad__) // true
},
onShow() {
console.log(this.__isOnShow__) // true
},
})