首页 / 资讯中心 / 文章详情

@rematch/core 版本演进全解:从 0.2 到 2.2,一个 Redux Framework 如何打磨自己的 API

@rematch/core 版本演进全解:从 0.2 到 2.2,一个 Redux Framework 如何打磨自己的 API ★ FEATURED ARTICLE
前端【免费下载链接】rematchThe Redux Framework项目地址https://gitcode.com/gh_mirrors/re/rematch点击查看免费下载CHANGELOG.md 是rematch/core包Rematch 框架的核心运行时的完整变更记录它记录了这个包从 2018 年 0.2.0 起步、经历 1.0.0 正式化、2.0 大版本重构monorepo、类型系统重写、架构调整、再到当前仓库锁定的 2.2.0 的全部关键节点。本文以这份 CHANGELOG 为骨架逐版本解读每个版本“改了什么、为什么改”并对照当前仓库的源码packages/core/src与测试packages/core/test验证这些变更今天依然落在哪些代码路径上。读完你可以掌握三件事Rematch 核心 APIinit、addModel、dispatch/effects、插件钩子的来历与底层实现位置各版本破坏性变更对升级的影响以及如何把 CHANGELOG 与源码、测试对应起来定位历史问题的回归测试。版本总览CHANGELOG 中部的文件头说明了它的组织方式All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.即 2.0.0-next 系列之后的条目按 Conventional Commits 规范生成按 Bug Fixes / Features / Reverts 分组附 commit hash文件下半部分则沿用了更早的 Keep a Changelog 风格按 Added / Changed / Breaking Change 分组。整个仓库由 lerna 管理多包结构见根目录 lerna.json当前 packages/core/package.json 中version: 2.2.0与 CHANGELOG 的最新版一致。按时间倒序CHANGELOG 覆盖的版本节点如下版本日期性质核心主题2.2.02021-11-09正式版循环模型解构修复devtoolComposer配置2.1.12021-10-11补丁TypeScript 类型推断修复2.1.02021-08-13正式版类型修复集中批次 treeshaking 优化2.0.12021-02-23补丁devtools 选项类型2.0.02021-01-31正式版从 next.10 转正仅版本号提升2.0.0-next.1 ~ next.102020-07-30 ~ 2020-12-27预发布类型系统重写、bundle 瘦身、重新引入 action.meta2.0.0旧格式条目2020-03-29大版本monorepo 重组、validate 重写、插件钩子新增1.4.0 / 1.2.0 / 1.0.72019 ~ 2020正式版类型改进、依赖更新、IE11 修复1.0.0-beta.0 ~ beta.52018-06预发布移除全局 dispatch/getState、baseReducer、devtools 开关1.0.0-alpha.0 ~ alpha.92018-04 ~ 2018-06预发布TypeScript 支持、多 store、插件 API 重写0.2.0 ~ 0.6.02018-02 ~ 2018-03早期覆盖 store.dispatch、dispatch 返回 Promise、跨模型监听下面按 2.x、2.0 大重构、1.x 预发布、0.x 早期四段展开并逐一给出当前源码中的对应实现位置。2.x 正式版从 2.0.0 到 2.2.02.2.02021-11-09循环模型解构修复与 devtoolComposerCHANGELOG 中 2.2.0 记录了两类变更Bug Fixescircular reference destructuring works with all models#947commit7ada366——修复了相互引用的模型在 effects 中以解构方式互相访问时的工作问题。Featuresallow to config pass custom devtoolComposer for handling remote-dev-tools#941commit3634f5c——允许用户在配置中传入自定义的devtoolComposer用于对接远程 DevTools 一类的自定义 compose 方案。Reverts回滚了一次误发布的 release chorecommit6d2ebc7。循环模型修复的源码印证。“解构”指的是 effects 写作函数形式时把 dispatch 解构成模型名映射effects: ({ dolphins, sharks }) ({ ... })让模型之间可以互相调用比如 dolphins 的 effect 调用sharks.incrementAsync(1)。这个两阶段构建过程就在 rematchStore.ts 中——注意源码注释直接点明了为什么要分两步/** * generate dispatch[modelName][actionName] for all reducers and effects * * Note: To have circular models accessible in effects method with destructing, * ensure that model generation and effects generation execute in * different steps. */ bag.models.forEach((model) prepareModel(rematchStore, model)) bag.models.forEach((model) enhanceModel(rematchStore, bag, model))第一阶段prepareModel先把每个模型的 dispatcher 占位注入rematchStore.dispatch[model.name]rematchStore.ts第二阶段enhanceModel才真正调用createEffectDispatcher展开 effects 并绑定rematchStore.ts。如果两个阶段合并在一次遍历里完成后注册的模型在解构时还拿不到先注册模型的 dispatcher循环引用就会失效。对应的回归测试是 circurlarmodels.test.ts其中 dolphins 与 sharks 两个模型互相在 effects 中解构引用并跨模型 dispatch断言最终 stateawait store.dispatch.sharks.incrementAsync(4) expect(store.getState().sharks).toEqual(4) await store.dispatch.dolphins.increment() await store.dispatch.dolphins.incrementSharksAsync() expect(store.getState().dolphins).toEqual(3)devtoolComposer 的源码印证。该配置项定义在 types.ts 的InitConfigRedux接口中devtoolComposer?: DevtoolComposerGeneric消费点在 reduxStore.tsconst middlewares Redux.applyMiddleware(...bag.reduxConfig.middlewares) const enhancers bag.reduxConfig.devtoolComposer ? bag.reduxConfig.devtoolComposer(...bag.reduxConfig.enhancers, middlewares) : composeEnhancersWithDevtools(bag.reduxConfig.devtoolOptions)( ...bag.reduxConfig.enhancers, middlewares )即用户提供了devtoolComposer时完全接管 enhancer 组合过程否则回落到内置的composeEnhancersWithDevtoolsreduxStore.ts后者在devtoolOptions.disabled未开启且浏览器存在window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__时才接入 Redux DevTools Extension。这正是 1.0.0-beta.2 引入的“关闭 devtools”能力在 2.2.0 之后的最终形态。2.1.12021-10-11TypeScript 类型修复批次CHANGELOG 记录两条 Bug Fixests typings, reducer now accepts void due to Immer usagecommita869a1f——reducer 的类型允许返回void。这是为 immer 插件让路immer 风格的 reducer 直接在传入的 state 上 mutate 而不显式 return类型上必须容忍 void 返回。当前源码在 reduxStore.ts 中有直接注释佐证if (action.type in modelReducers) { return modelReducersaction.type as TState }types: improve the accuracy of dispatcher inference#937commit4bca82dcloses #939——提升 dispatcher 的类型推断精度。dispatcher 的类型系统有专门测试目录 test/ts_typings例如 dispatcher-typings.test.ts 即用于约束这一能力不回退。2.1.02021-08-13类型修复集中批次 构建优化这是 2.x 中变更最多的一次正式发布CHANGELOG 记录了 8 条 Bug Fixes按主题可以归为三类类型与推断connect() fails on Typescript 4.3#893commitf794263——修复 React-Reduxconnect在 TS 4.3 下的兼容性。make models on init() PartialT#892commit991a9d8——init()的models入参类型放宽为PartialT。当前 types.ts 中InitConfig.models?: TModels | PartialTModels就是这一修复的落地形态。optional payload inference#901commitdfff163closes #902——payload 可选时的推断修复。reducers and effects with same name are correctly typed 4.3.X#913commit3db2d9f——同名 reducer 与 effect 的 typing 冲突。this.reducer typed partially correctcommitf43c3a7。运行时行为context binding in addModel#873commit7f99a45——addModel时 effects 的 this 绑定修复。当前实现中 effects 被bind(modelDispatcher)dispatcher.ts使 effect 内部通过this调用同模型 action 时上下文正确。updated peerDependencies#898commit3013605——当前 package.json 中为peerDependencies: { redux: 4 }即核心包要求 redux 4.x 或更高作为对等依赖。构建与产物build to modules to .mjs instead of .js and sideEffects: false for better treeshakingcommitc2978f3——产物模块格式调整并声明无副作用以便 tree-shaking。当前 package.json 保留了sideEffects: false并以main/module/browser三字段分别指向 CJS、ESM 与 UMD 产物。2.0.1 与 2.0.02021-02-23 / 2021-01-312.0.1只有一条修复redux devtool options ts typescommit5fbf8ea对应 types.ts 中的DevtoolOptions类型定义。2.0.0标注为Version bump only for package rematch/core——即从2.0.0-next.10转正时没有代码变更纯版本号提升。这也解释了为什么 2.0 系列的实际功能演进全部集中在下文 2.0.0-next 序列中。2.0.0-next.1 ~ next.10类型系统重写的预发布窗口2020 年 7 月到 12 月的十个预发布版本是rematch/core历史上一次集中重写 TypeScript 类型的窗口。逐版本看 CHANGELOG 的条目2.0.0-next.12020-07-30仅两条 Reverts回滚了publish %v [ci skip]的发布 chorecommit10b7f71、fbc6307属于发布流程修正。2.0.0-next.22020-08-19typescript types inference documentationcommit178be27开启类型推断改进。2.0.0-next.32020-08-26本序列中条目最多的一次包含 12 条 Bug Fixes核心是类型架构定型model state type inference0d29531、type inference for state and dispatch541863b、type inference of dispatchersa129852、rootState type inference on effectsa8b8484——把 state / dispatch / rootState 的推断链路打通createModel refactorede024deb——createModel重构为当前的简单形态见 index.tsexport const createModel: ModelCreator () (mo) mo as any它作为 TS 中的类型辅助工具存在removed dispatch3e153ae、incompability of redux dispatch with rematch9b68614——统一 rematch 自有 dispatch 与 redux dispatch 的语义using Models as default option4e7c29c——类型默认泛型约定loading: complete typingsdfa8688、loading: removed ts-ignore and fixed typings0ab397d——连带把 rematch/loading 的类型补全。2.0.0-next.42020-08-26regression state on effects returning nevercommit671a372修复 effects 返回never时 state 类型退化。2.0.0-next.52020-09-07regression in destructuring dispatchcommitf50c6e4——注意这与 2.2.0 的 #947 是同一条问题线解构 dispatch 的类型/行为在预发布期反复修复最终在 2.2.0 以“works with all models”收尾。2.0.0-next.62020-10-08core: changed option value of TExtraModelscommit8b416cd。TExtraModels这个泛型参数用于表达插件注入的额外模型如 loading/persist 会往根 state 上挂自己的字段当前 types.ts 中InitConfigTModels, TExtraModels/Config/RematchStore等接口均以它为第二个泛型参数。2.0.0-next.72020-11-30一条 Bug Fixrematch/select typescript plugin compatibility#828commit61890ca与一条 Featuresupport optional payload parameter on reducercommit681acba。后者使 reducer 的 payload 成为可选参数与 2.1.0 的optional payload inference一脉相承当前 dispatcher.ts 中createActionDispatcher对payload/meta都是“未传则不写入 action”return Object.assign( (payload?: any, meta?: any): Action { const action: Action { type: ${modelName}/${actionName} } if (typeof payload ! undefined) { action.payload payload } if (typeof meta ! undefined) { action.meta meta } return rematch.dispatch(action) }, { isEffect } )2.0.0-next.82020-12-21Improved overall bundle size#847commit16e3271。2.0.0-next.92020-12-22Introduced meta to action#848commit2d55ae4。这是 CHANGELOG 中一个值得注意的“先删后加”节点2020-03-29 的旧格式 2.0.0 条目删除了meta参数理由见下文而 next.9 又以新形态重新引入——action 上的meta字段在 dispatcher.ts 中写入在 effects middleware 中作为第三个实参传给 effect 实现rematchStore.tsreducer 侧同样以第三参接收reduxStore.ts。2.0.0-next.102020-12-27Reduced rematch/core bundle-size#852commit98f3f80与 next.8 的 bundle 优化同线。2.0.0 大版本重构2020-03-29旧格式条目CHANGELOG 后半段保留了一条更早的2.0.0 - 2020-03-29条目Keep a Changelog 风格它才是 2.0 架构层面的真正说明。逐条对照当前源码重组目录与文件以支持 monorepo 结构构建脚本改用 tsdx 并统一 tsconfig——当前仓库正是 monorepo 布局packages/core 与 immer、loading、persist、select、typed-state、updated 等插件包并列tsconfig.base.json 为各包 tsconfig 提供公共基线。core 的 tsdx.config.js 与 package.json 中的dtstsdx 系脚本是这一决策的延续。validate入参从“直接传校验列表”改为“传一个返回校验列表的函数”目的是不在生产环境执行无谓的计算——因为生产环境下错误反正不会抛出。当前 validate.ts 完整呈现了这一设计const validate (runValidations: () Validation[]): void { if (process.env.NODE_ENV ! production) { const validations runValidations() const errors: string[] [] validations.forEach((validation) { const isInvalid validation[0] const errorMessage validation[1] if (isInvalid) { errors.push(errorMessage) } }) if (errors.length 0) { throw new Error(errors.join(, )) } } }注意runValidations只在NODE_ENV ! production分支内被调用生产构建可被 tree-shake 掉。validate 收集并抛出全部错误而不是只抛第一个——上述实现里errors.join(, )即“收集后一次抛出”的落地validateConfig/validateModel/validatePlugin/validateModelReducer/validateModelEffectvalidate.ts都遵循同一套行为测试见 validatePlugins.test.ts 与 config.test.ts。store 默认名从纯数字改为Rematch Store ${number}——当前 config.ts 精确实现了这一点let count 0 ... const storeName initConfig.name ?? Rematch Store ${count} count 1该名字同时用作 Redux DevTools 中 store 的展示名devtoolOptions.nameconfig.ts。移除插件配置内嵌其他插件的能力避免重复注册等问题——改为在插件 README 中声明依赖顺序。当前 config.ts 中插件配置合并只处理models与redux两个维度无递归插件机制。移除 action 的meta参数——CHANGELOG 给出的理由是它“仅面向高级场景”且其能力可以不依赖 meta 实现后文可见该参数在 2.0.0-next.9#848以更规范的形态回归。移除onInit钩子——CHANGELOG 称“确实没有使用场景”。新增插件钩子onReducer与onRootReducer——当前消费点分别是 reduxStore.ts每个模型 reducer 生成后依次交给各插件包裹与 reduxStore.tsroot reducer 合并后交给插件包裹插件类型定义见 types.ts 的Plugin接口。dispatch与effects从插件下沉为 core 内置能力——CHANGELOG 的理由是“更易推理、更易写插件、类型声明更清晰”。当前源码印证effects 由内置 middleware 处理rematchStore.ts 的createEffectsMiddleware先执行同名的 reducer action再执行 effect 并返回其结果dispatcher 构建在 core 的 dispatcher.ts 中而非任何插件。改进类型定义——为 2.0.0-next 系列的大规模类型重写做铺垫。1.x从 alpha 到正式版的稳定化路径1.0.0 正式版与 1.0.72018-09-27 / 2019-03-02CHANGELOG 记录 1.0.0 为里程碑版本条目以一句“Happy 1.0!”收尾1.0.7 则插件统一采用 MIT 许可证更新依赖与示例修复 IE11 上的问题建立 TypeScript 测试与 CI 构建。1.0.0-beta 系列多 store 时代的关键 API 定型beta.52018-06-27新增model.baseReducer允许在模型内使用“普通 Redux reducer”先处理 actionmodel.reducers再在其结果之上运行以产出最终 state。当前 reduxStore.ts 完整保留了这一语义const modelBaseReducer model.baseReducer let reducer !modelBaseReducer ? combinedReducer : (state: TState model.state, action: Action): TState combinedReducer(modelBaseReducer(state, action), action)且 validateModel 允许state与baseReducer二者择一只有两者都缺失才报model state is required。beta.32018-06-23破坏性变更——移除从 core 导入的全局dispatch与getState推荐从init()返回值上解构import { init } from rematch/core const store init() export const { getState, dispatch } store export default store当前 index.ts 的init返回RematchStore其类型继承自 Redux store 并额外暴露name、dispatch、addModeltypes.ts与这一推荐用法一致。同版本还新增插件onStoreCreated可以返回一个对象合并进init的返回值当前消费点在 rematchStore.tsrematchStore onStoreCreated(rematchStore, bag) || rematchStore。beta.22018-06-16支持关闭 devtoolscommit9a17312——对应 reduxStore.ts 中devtoolOptions.disabled的判断支持在init时给 store 命名commit6c69529——对应 config.ts 的initConfig.name ?? \Rematch Store ${count}插件开发可在内部访问 config——即 bag.ts 创建的 RematchBagmodels/reduxConfig/forEachPlugin/effects注释明确其“故意对最终用户隐藏”。beta.12018-06-12修复懒加载 store 的更新问题commit9a44865——与当前 rematchStore.ts 中addModel的实现呼应动态addModel后通过reduxStore.replaceReducer(createRootReducer(bag))重建根 reducer 并派发redux/REPLACE触发重算。beta.02018-06-11类型修复、支持 TS strict null checks。1.0.0-alpha 系列TypeScript、多 store 与插件 API 重写alpha.9 / alpha.82018-06-10 / 2018-06-02修复 select 插件类型、修复 effects 中 rootState 问题新增“用函数形式写 effects 以访问局部 dispatch”{ effects: dispatch ({ async someEffect() { dispatch.someModel.someAction() }, }), }当前 dispatcher.ts 仍按此约定运行effects是函数时以rematch.dispatch调用得到真实 effects否则直接取对象。alpha.7 / alpha.3 / alpha.12018-06-02 至 2018-04-10连续的类型改进——createModel用于 TS 模型、getSelect用于 TS select、dispatch 自动补全以及在 Redux DevTools 中展示 store 名称。alpha.02018-04-071.0 系列的起点变更密集支持 TypeScript、支持多 store插件 API 变更以避免在插件中调用init共享依赖改经this访问插件需全部升级适配导入的全局dispatch会触发所有 store、全局getState汇总所有 store 的 stateinit({ name })作为 store.name缺省则用索引号。0.x 早期版本API 雏形的形成0.2.0 ~ 0.6.0 五个版本奠定了 Rematch 今天仍在使用的基础语义0.2.02018-02-03用 rematch 的 dispatch 覆盖store.dispatch使配合 react-redux 使用时无需单独导入 dispatch。这一覆盖语义延续至今——RematchStore的dispatch字段类型是RematchDispatchTModelstypes.ts而非原生 redux dispatch。0.3.02018-02-10dispatch调用返回 Promise——effect dispatcher 会返回 effect 执行的 PromiseCHANGELOG 中该条目与 rematchStore.ts 中 effects middleware “return its result” 的实现对应。0.4.02018-02-18从 core 导出全局getStateimport { getState } from rematch/core注意这一全局 API 在 1.0.0-beta.3 被移除统一改为从 store 上解构——这是阅读 CHANGELOG 时容易踩的“同名字段跨版本语义不同”的典型例子dispatch 的meta第二参数dispatch.example.update(payload, { syncWithServer: true })等价于dispatch({ type: example/update, payload, meta: { syncWithServer } })reducer / effect 以第三参读取 meta。该机制在 2.0 大版本中删除、又在 next.9 以 action.meta 的形态回归。0.5.02018-03-05reducer 支持监听其他模型的 action——即 reducer key 直接写成完整 action 名const count2 { state: 0, reducers: { // listens for action from other reducer count1/increment: state state 1, }, }当前实现见 reduxStore.ts 与 reduxStore.ts 的isAlreadyActionNamereducer key 含/时原样作为 action 名否则自动拼为modelName/reducerKey。0.5.32018-03-05支持 devtool action creators#281。0.6.02018-03-27effects 开始派发可在 DevTools 中看到的 action——这正是今天 dispatcher.ts 中 effect dispatcher 同样走type: \${modelName}/${actionName} 标准 action 通道的历史源头。把 CHANGELOG 与当前源码、测试对上号读完逐版本解读后可以建立一个“变更 → 代码落点”的速查视图便于日后排查问题或写插件时直接跳转CHANGELOG 关键变更版本当前源码/测试落点store 命名Rematch Store N、devtools 默认关闭判断1.0.0-beta.2 / 2.0.0config.ts、reduxStore.ts插件配置合并models/redux 两维2.0.0config.tsvalidate 函数化、收集全部错误、生产跳过2.0.0validate.ts测试 config.test.ts、validatePlugins.test.tsdispatch/effects 内置化2.0.0rematchStore.ts、dispatcher.ts新增onReducer/onRootReducer钩子2.0.0reduxStore.tsreducer 可选 payload、action.metanext.7 / next.9dispatcher.tsmodels 入参PartialT、peerDeps redux42.1.0types.ts、package.jsonreducer 可返回 voidimmer 兼容2.1.1reduxStore.ts测试 immer.test.tsaddModel 时 context 绑定2.1.0dispatcher.ts、rematchStore.ts循环模型解构works with all models2.2.0rematchStore.ts测试 circurlarmodels.test.ts自定义devtoolComposer2.2.0types.ts、reduxStore.ts类型推断链路state/dispatch/rootStatenext.3test/ts_typings含 circular-references、dispatcher-typings 测试两点使用提醒适用前提以上源码行号与实现均对应当前仓库中rematch/core2.2.0的代码packages/core/package.json 的version字段peerDependencies要求redux 4Node 引擎要求10package.json。若你使用其他版本的 core部分行为尤其 2.0 前后 meta、全局getState/dispatch的存废需以对应版本的 CHANGELOG 为准。阅读方法Conventional Commits 格式的条目中fix:/feat:前缀与版本号升档semver一一对应——patch 版本如 2.1.1通常只含类型或行为修复minor/major如 2.2.0、2.0.0才会出现 Features 或破坏性变更遇到“regression”字样next.4、next.5时优先查 test/v1_regressions 与对应ts_typings测试来确认该回归是否已有守护用例。小结packages/core/CHANGELOG.md 完整记录了rematch/core从“覆盖 store.dispatch 的轻量增强”0.2.0到“monorepo 全类型推断 插件钩子体系”2.x的演进主线1.x 完成了多 store、插件 API 与 devtools 集成等 API 定型2.0 以旧格式条目说明了 monorepo 重组、validate 函数化、dispatch/effects 内置化等架构决策2.0.0-next 十个预发布版本集中重写了类型系统并两次瘦身 bundle2.1/2.2 则把类型推断与运行时行为打磨到当前仓库的形态。CHANGELOG 中每一条 fix 几乎都能在 packages/core/src 找到对应实现在 packages/core/test 找到守护测试——这也正是这份变更记录对排查历史问题、评估升级风险最有价值的地方。赞分享前端【免费下载链接】rematchThe Redux Framework项目地址https://gitcode.com/gh_mirrors/re/rematch点击查看免费下载相关推荐Ionic Framework ionic/core 版本演进全解从 v6 到 v9 的 CHANGELOG 深度导读Ionic Framework ionic/core 版本演进全解从 v6 到 v9 的 CHANGELOG 深度导读 本篇技术指南以开源仓库 gh_mir前端移动开发跨平台Gensim 版本演进全解从 0.2 到 4.4 的 API 变迁、性能优化与迁移指南Gensim 版本演进全解从 0.2 到 4.4 的 API 变迁、性能优化与迁移指南 本篇技术指南以仓库根目录 CHANGELOG.md https://l人工智能NLP机器学习深度学习rrweb 2.x 版本演进全解析从 2.0 架构重组到 2.1 性能打磨rrweb 2.x 版本演进全解析从 2.0 架构重组到 2.1 性能打磨 rrwebrecord and replay the web是开源社区中用于前端可观测性开发工具上一篇Path of Building PoE2终极指南15分钟掌握流放之路2最强角色规划神器下一篇FastBle在智能家居场景中的实践多设备联动控制方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站