
react-boilerplate 精简指南彻底移除 redux-saga 与 reselect 依赖【免费下载链接】react-boilerplate A highly scalable, offline-first foundation with the best developer experience and a focus on performance and best practices.项目地址: https://gitcode.com/gh_mirrors/rea/react-boilerplate本篇指南围绕 react-boilerplate 官方文档 docs/js/remove.md 展开完整讲解如何从项目中移除副作用管理库redux-saga与状态选择器库reselect。文章将逐文件给出精确的删除清单与替代写法并结合本仓库源码app/configureStore.js、app/utils/checkStore.js、package.json 等说明每一步的底层原理帮助你在保持应用可运行的前提下自主更换状态管理技术栈。适用前提本文步骤针对本仓库当前版本redux-saga1.0.2、reselect4.0.0、eslint-plugin-redux-saga1.0.0见 package.json。实际操作前建议先提交一次代码快照便于回滚。一、两个库在项目中的角色react-boilerplate 的 JavaScript 技术栈见 docs/js/README.md是这样组织的状态管理使用Reduxdocs/js/redux.md并用Immer保证不可变性docs/js/immer.md通过reselect派生并缓存选择器保证状态访问的性能docs/js/reselect.md通过redux-saga管理异步流程例如登录、拉取仓库列表等docs/js/redux-saga.md。也就是说redux-saga承担「副作用管理」reselect承担「高效选择器」。移除它们之后你需要自行选择替代方案例如redux-thunk、redux-observable或手写mapStateToProps因此官方文档也特别声明并不推荐移除redux-saga因为它被认为是多数 Redux 应用的最佳实践选择只有当你确实需要更换技术栈时才按本文步骤操作。二、移除 redux-saga从 Store 配置到测试的完整清单移除redux-saga需要同时清理运行时代码、测试代码、工具函数与 ESLint 配置共涉及 8 个位置。下面逐一说明。1. 清理 app/configureStore.js这是 saga 中间件的注册入口共 5 处修改删除import createSagaMiddleware from redux-saga;当前第 7 行删除const sagaMiddleware createSagaMiddleware(reduxSagaMonitorOptions);当前第 30 行从middlewares数组中移除sagaMiddleware——当前数组为const middlewares [sagaMiddleware, routerMiddleware(history)];移除后应只剩路由中间件const middlewares [routerMiddleware(history)];删除store.runSaga sagaMiddleware.run;当前第 46 行该语句把 saga 中间件的run方法挂到 store 上供动态注入 saga 使用删除store.injectedSagas {}; // Saga registry当前第 48 行这是动态注入 saga 的注册表。清理后app/configureStore.js 中reduxSagaMonitorOptions变量及其注释块当前第 12、21-26 行与 Saga Dev Tools 相关也可以一并删除composeEnhancers相关逻辑保持不变。2. 清理 app/tests/store.test.js该测试文件app/tests/store.test.js验证了 store 的扩展能力需要删除describe(injectedSagas, ...)块——断言store.injectedSagas是对象当前第 21-25 行describe(runSaga, ...)块——断言store.runSaga是函数当前第 27-31 行。保留injectedReducers测试块与configureStore params测试块即可。3. 删除 app/utils 下的三个文件动态注入 saga 机制由三个文件支撑全部删除app/utils/injectSaga.js提供injectSagaHOC 与useInjectSagaHook在组件挂载时注入 saga、卸载时弹出ejectapp/utils/sagaInjectors.js提供injectSagaFactory/ejectSagaFactory/getInjectors内部通过store.runSaga启动任务并支持三种运行模式app/utils/constants.js定义三种 saga 运行模式的常量——RESTART_ON_REMOUNT组件重挂载时重启、DAEMON常驻挂载时启动且永不取消、ONCE_TILL_UNMOUNT挂载时启动、卸载时取消且不再重启。从源码看sagaInjectors.js中的injectSaga在非生产环境还会检测 hot reload 场景通过对比新旧 saga 引用来取消旧任务app/utils/sagaInjectors.js 第 41-48 行。这套机制是 react-boilerplate「按需加载、动态注入」架构的关键一环删除后容器将不再具备运行时注入 saga 的能力。4. 清理 app/utils/checkStore.jscheckStore用于校验传入的 store 是否符合注入器的预期形状app/utils/checkStore.js 第 7-21 行。删除两项校验runSaga: isFunction, ... injectedSagas: isObject,清理后保留的 shape 为dispatch、subscribe、getState、replaceReducer函数类型以及injectedReducers对象类型。5. 删除 app/utils/tests 下的两个测试文件app/utils/tests/injectSaga.test.jsapp/utils/tests/sagaInjectors.test.js6. 清理 app/utils/tests/checkStore.test.js该测试用「构造非法 store 应抛异常」的方式验证校验逻辑删除两行当前第 28、30 行expect(() checkStore({ ...store, injectedSagas: null })).toThrow(); expect(() checkStore({ ...store, runSaga: null })).toThrow();7. 清理容器组件中的动态注入调用仓库中所有通过injectSaga/useInjectSaga注入 saga 的容器都要同步清理。以 app/containers/HomePage/index.js 为例删除import { useInjectSaga } from utils/injectSaga;当前第 16 行删除import saga from ./saga;当前第 34 行删除组件体内的调用useInjectSaga({ key, saga });当前第 47 行。旧版写法对应文档所述const withSaga injectSaga({ key: home, saga });由于HomePage使用compose(withConnect, memo)(HomePage)组合高阶组件若采用 HOC 写法还需从compose调用中去掉withSaga。仓库中还可能存在其他容器使用同样的模式建议全局搜索injectSaga与useInjectSaga逐一清理。8. 最后清理 package.json 与 ESLint 配置完成以上代码清理后移除依赖声明对应文档的收尾步骤从dependencies中删除redux-saga: 1.0.2package.json 第 90 行从devDependencies中删除eslint-plugin-redux-saga: 1.0.0第 129 行删除eslintConfig plugins中的redux-saga插件删除eslintConfig rules中所有redux-saga/*规则。之后重新执行npm install更新锁文件并运行npm test、npm run lint验证清理结果。三、移除 reselect回归手写 mapStateToPropsreselect的移除比redux-saga简单得多核心就两步删除依赖 改写选择器。1. 从 package.json 移除依赖从dependencies中删除reselect: 4.0.0package.json 第 91 行。2. 用普通函数改写 mapStateToProps原选择器使用createStructuredSelector与createSelector。以 app/containers/HomePage/index.js 当前代码为例import { createStructuredSelector } from reselect; const mapStateToProps createStructuredSelector({ repos: makeSelectRepos(), username: makeSelectUsername(), loading: makeSelectLoading(), error: makeSelectError(), });移除reselect后直接按 Redux 常规方式手写const mapStateToProps state ({ repos: state.global.userData.repositories, username: state.global.username, loading: state.global.loading, error: state.global.error, });文档明确指出移除后「像平时一样写你的mapStateToProps函数即可」。需要注意reselect自带结果缓存同一组输入不重复计算改写为普通函数后每次 dispatch 都会重新计算若涉及昂贵计算需自行缓存。3. 在 app/app.js 中处理 location 状态文档要求移除app/app.js中import { makeSelectLocationState } from containers/App/selectors语句并手动把路由状态接入 storeconst makeSelectLocationState () { let prevRoutingState; let prevRoutingStateJS; return state { const routingState state.get(router); // or state.route if (!routingState.equals(prevRoutingState)) { prevRoutingState routingState; prevRoutingStateJS routingState.toJS(); } return prevRoutingStateJS; }; }; const history syncHistoryWithStore(browserHistory, store, { selectLocationState: makeSelectLocationState(), });需要说明的是上述代码中的makeSelectLocationState/syncHistoryWithStore对应 react-boilerplate 早期基于react-router-redux的写法。在当前仓库中路由同步已经由connected-react-router承担——app/app.js 直接使用ConnectedRouter包裹应用app/reducers.js 通过connectRouter(history)合并路由 reducerapp/containers/App/selectors.js 中的makeSelectLocation也是基于state.router的createSelector。因此在本仓库场景下移除reselect时删除 app/containers/App/selectors.js 中对createSelector的引用第 5 行import { createSelector } from reselect;将各个makeSelect*工厂改写为直接读取state.global/state.router的普通函数路由状态本身继续由connected-react-router维护无需自行实现makeSelectLocationState文档中的syncHistoryWithStore方案仅适用于不使用connected-react-router的历史版本。四、清理后的验证与可替代方案完成全部步骤后建议执行以下验证npm run lint # 确认无 redux-saga/reselect 相关引用残留 npm test # 确认 store、注入器相关测试全部通过 npm run build # 确认生产构建正常从源码结构看移除后失去的能力包括动态 saga 注入app/utils/injectSaga.js 的 HOC/Hook 与 app/utils/sagaInjectors.js 的三种运行模式、store 上的runSaga钩子、以及 store 形状校验中对 saga 相关字段的检查。如果你仍需要异步副作用管理可选用其他中间件替换redux-saga并保持dispatch动作的接口不变——app/containers/HomePage/index.js 中的mapDispatchToProps与 app/containers/App/actions.js 的动作定义均可复用。五、小结redux-saga与reselect是 react-boilerplate 异步流程与选择器性能的两大支柱。移除它们需要联动清理 store 配置、工具函数、容器组件、测试与依赖声明五个层面本文给出的清单以官方文档 docs/js/remove.md 为骨架并对照本仓库当前源码逐一标注了确切位置与行号。建议在动手前评估替代方案如redux-thunk 手写选择器并按「先删运行时代码、再删测试、最后删依赖」的顺序推进每一步都可用npm test验证。【免费下载链接】react-boilerplate A highly scalable, offline-first foundation with the best developer experience and a focus on performance and best practices.项目地址: https://gitcode.com/gh_mirrors/rea/react-boilerplate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考