[{"data":1,"prerenderedAt":2862},["ShallowReactive",2],{"article-/topics/frontend/module-federation-advanced-guide":3,"related-frontend":534,"content-query-mDblZMuDVm":2458},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":18,"imageQuery":19,"pexelsPhotoId":20,"pexelsUrl":21,"featured":6,"readingTime":22,"body":23,"_type":528,"_id":529,"_source":530,"_file":531,"_stem":532,"_extension":533},"/topics/frontend/module-federation-advanced-guide","frontend",false,"","微前端 2.0：Module Federation 进阶，从共享依赖到发布治理的完整思路","Module Federation 最难的不是把远程模块跑起来，而是长期维护中的共享依赖、版本漂移、回滚和故障隔离。本文从真实项目视角讲清微前端 2.0 的进阶治理方法。","2026-04-16","HTMLPAGE 团队",[13,14,15,16,17],"Micro Frontend","Module Federation","Frontend Architecture","Shared Dependencies","Engineering","/images/topics/frontend/module-federation-advanced-guide.jpg","software architecture team discussing micro frontend modules on large monitor",7988754,"https://www.pexels.com/photo/men-looking-the-big-screen-7988754/",15,{"type":24,"children":25,"toc":516},"root",[26,34,39,64,69,99,106,111,124,129,134,140,145,168,173,178,196,201,207,212,230,235,258,263,268,273,291,296,314,319,325,330,335,353,358,376,381,399,404,409,432,437,442,475,480,485,490],{"type":27,"tag":28,"props":29,"children":30},"element","p",{},[31],{"type":32,"value":33},"text","很多团队第一次接触 Module Federation，都会有一种“终于找到微前端标准答案”的兴奋感。",{"type":27,"tag":28,"props":35,"children":36},{},[37],{"type":32,"value":38},"确实，它把“远程加载模块”和“共享依赖”这件事做到了框架层支持，起步成本比早期微前端方案低很多。但项目一旦进入长期维护，真正的问题很快会从“能不能运行”切换成：",{"type":27,"tag":40,"props":41,"children":42},"ul",{},[43,49,54,59],{"type":27,"tag":44,"props":45,"children":46},"li",{},[47],{"type":32,"value":48},"共享依赖如何防止版本漂移",{"type":27,"tag":44,"props":50,"children":51},{},[52],{"type":32,"value":53},"远程模块出故障时怎样局部降级",{"type":27,"tag":44,"props":55,"children":56},{},[57],{"type":32,"value":58},"发布节奏不同的子应用如何保持兼容",{"type":27,"tag":44,"props":60,"children":61},{},[62],{"type":32,"value":63},"团队如何判断哪些能力该共享，哪些不该共享",{"type":27,"tag":28,"props":65,"children":66},{},[67],{"type":32,"value":68},"所以这篇文章不再讲 Module Federation 的基础概念，而是专门讨论“微前端 2.0”阶段的治理问题。",{"type":27,"tag":28,"props":70,"children":71},{},[72,74,81,83,89,91,97],{"type":32,"value":73},"如果你想先补基础背景，可以先看 ",{"type":27,"tag":75,"props":76,"children":78},"a",{"href":77},"/topics/frontend/micro-frontend-architecture-guide",[79],{"type":32,"value":80},"微前端架构设计模式完全指南",{"type":32,"value":82},"、",{"type":27,"tag":75,"props":84,"children":86},{"href":85},"/topics/frontend/pnpm-workspace-advanced-guide",[87],{"type":32,"value":88},"pnpm workspace 进阶技巧",{"type":32,"value":90}," 和 ",{"type":27,"tag":75,"props":92,"children":94},{"href":93},"/topics/frontend/code-quality-gates-ci-integration-guide",[95],{"type":32,"value":96},"代码质量门禁与 CI 集成",{"type":32,"value":98},"。",{"type":27,"tag":100,"props":101,"children":103},"h2",{"id":102},"module-federation-真正解决的是部署独立不是架构独立",[104],{"type":32,"value":105},"Module Federation 真正解决的是“部署独立”，不是“架构独立”",{"type":27,"tag":28,"props":107,"children":108},{},[109],{"type":32,"value":110},"很多误解来自把这两件事混为一谈。",{"type":27,"tag":40,"props":112,"children":113},{},[114,119],{"type":27,"tag":44,"props":115,"children":116},{},[117],{"type":32,"value":118},"部署独立：子应用可以单独构建、单独发布",{"type":27,"tag":44,"props":120,"children":121},{},[122],{"type":32,"value":123},"架构独立：业务边界、依赖边界、失败边界都足够清晰",{"type":27,"tag":28,"props":125,"children":126},{},[127],{"type":32,"value":128},"Module Federation 非常擅长前者，但不会自动帮你完成后者。",{"type":27,"tag":28,"props":130,"children":131},{},[132],{"type":32,"value":133},"如果团队没有明确的领域拆分，哪怕把模块拆成了 host 和 remote，最后也可能只是把单体复杂度换了一种分布方式。",{"type":27,"tag":100,"props":135,"children":137},{"id":136},"共享依赖是收益点也是故障放大器",[138],{"type":32,"value":139},"共享依赖是收益点，也是故障放大器",{"type":27,"tag":28,"props":141,"children":142},{},[143],{"type":32,"value":144},"大多数项目一上来都会共享：",{"type":27,"tag":40,"props":146,"children":147},{},[148,153,158,163],{"type":27,"tag":44,"props":149,"children":150},{},[151],{"type":32,"value":152},"React / Vue",{"type":27,"tag":44,"props":154,"children":155},{},[156],{"type":32,"value":157},"UI 组件库",{"type":27,"tag":44,"props":159,"children":160},{},[161],{"type":32,"value":162},"状态管理库",{"type":27,"tag":44,"props":164,"children":165},{},[166],{"type":32,"value":167},"工具函数",{"type":27,"tag":28,"props":169,"children":170},{},[171],{"type":32,"value":172},"这很合理，因为共享依赖能减少重复加载，降低首屏体积。但越往后你会越清楚：共享不是越多越好。",{"type":27,"tag":28,"props":174,"children":175},{},[176],{"type":32,"value":177},"更稳的原则是：",{"type":27,"tag":40,"props":179,"children":180},{},[181,186,191],{"type":27,"tag":44,"props":182,"children":183},{},[184],{"type":32,"value":185},"运行时框架类依赖可以谨慎共享",{"type":27,"tag":44,"props":187,"children":188},{},[189],{"type":32,"value":190},"业务组件和领域模型不要轻易共享",{"type":27,"tag":44,"props":192,"children":193},{},[194],{"type":32,"value":195},"一旦共享，就要把版本兼容性和回滚策略一起设计",{"type":27,"tag":28,"props":197,"children":198},{},[199],{"type":32,"value":200},"共享依赖真正危险的地方，不在单次加载，而在“一个版本变更会不会拖着多个子应用一起出问题”。",{"type":27,"tag":100,"props":202,"children":204},{"id":203},"微前端-20-更看重失败边界而不是功能拼装能力",[205],{"type":32,"value":206},"微前端 2.0 更看重失败边界，而不是功能拼装能力",{"type":27,"tag":28,"props":208,"children":209},{},[210],{"type":32,"value":211},"在真实项目里，最值钱的问题通常不是“能不能组合页面”，而是：",{"type":27,"tag":40,"props":213,"children":214},{},[215,220,225],{"type":27,"tag":44,"props":216,"children":217},{},[218],{"type":32,"value":219},"某个 remote 失效后主应用是否还能工作",{"type":27,"tag":44,"props":221,"children":222},{},[223],{"type":32,"value":224},"某个团队延迟发布时，其他团队是否被迫等待",{"type":27,"tag":44,"props":226,"children":227},{},[228],{"type":32,"value":229},"某个远程模块异常时，错误会不会扩散成全局白屏",{"type":27,"tag":28,"props":231,"children":232},{},[233],{"type":32,"value":234},"这意味着 Module Federation 的进阶实践一定要补上：",{"type":27,"tag":40,"props":236,"children":237},{},[238,243,248,253],{"type":27,"tag":44,"props":239,"children":240},{},[241],{"type":32,"value":242},"远程模块健康检查",{"type":27,"tag":44,"props":244,"children":245},{},[246],{"type":32,"value":247},"超时与 fallback UI",{"type":27,"tag":44,"props":249,"children":250},{},[251],{"type":32,"value":252},"错误隔离与降级占位",{"type":27,"tag":44,"props":254,"children":255},{},[256],{"type":32,"value":257},"兼容窗口和灰度发布",{"type":27,"tag":28,"props":259,"children":260},{},[261],{"type":32,"value":262},"没有这些治理动作，所谓“独立部署”在生产环境里其实很脆弱。",{"type":27,"tag":100,"props":264,"children":266},{"id":265},"不要把所有跨应用能力都做成共享模块",[267],{"type":32,"value":265},{"type":27,"tag":28,"props":269,"children":270},{},[271],{"type":32,"value":272},"这是一种非常常见的过度设计：",{"type":27,"tag":40,"props":274,"children":275},{},[276,281,286],{"type":27,"tag":44,"props":277,"children":278},{},[279],{"type":32,"value":280},"一个团队发现多个子应用都要用某个逻辑",{"type":27,"tag":44,"props":282,"children":283},{},[284],{"type":32,"value":285},"于是立刻把它抽成共享 remote",{"type":27,"tag":44,"props":287,"children":288},{},[289],{"type":32,"value":290},"后续大家都依赖它，结果这个“共享能力”很快成了中央瓶颈",{"type":27,"tag":28,"props":292,"children":293},{},[294],{"type":32,"value":295},"更好的判断方式是：",{"type":27,"tag":40,"props":297,"children":298},{},[299,304,309],{"type":27,"tag":44,"props":300,"children":301},{},[302],{"type":32,"value":303},"这是稳定基础设施能力，还是高频变化业务逻辑",{"type":27,"tag":44,"props":305,"children":306},{},[307],{"type":32,"value":308},"它是标准化平台资产，还是某条业务线的局部抽象",{"type":27,"tag":44,"props":310,"children":311},{},[312],{"type":32,"value":313},"一旦出问题，影响面是否可接受",{"type":27,"tag":28,"props":315,"children":316},{},[317],{"type":32,"value":318},"如果答案偏向“高变动、高耦合、高风险”，就不应该轻易共享。",{"type":27,"tag":100,"props":320,"children":322},{"id":321},"失败案例共享-ui-包升级一个次版本三个子应用同时回归",[323],{"type":32,"value":324},"失败案例：共享 UI 包升级一个次版本，三个子应用同时回归",{"type":27,"tag":28,"props":326,"children":327},{},[328],{"type":32,"value":329},"这是 Module Federation 最典型的工程事故之一。",{"type":27,"tag":28,"props":331,"children":332},{},[333],{"type":32,"value":334},"场景通常是：",{"type":27,"tag":40,"props":336,"children":337},{},[338,343,348],{"type":27,"tag":44,"props":339,"children":340},{},[341],{"type":32,"value":342},"UI 包被多个 remote 共享",{"type":27,"tag":44,"props":344,"children":345},{},[346],{"type":32,"value":347},"某次次版本修改了一个弹层默认行为",{"type":27,"tag":44,"props":349,"children":350},{},[351],{"type":32,"value":352},"Host 和其中一个 remote 已适配，另外两个没有",{"type":27,"tag":28,"props":354,"children":355},{},[356],{"type":32,"value":357},"结果就是：",{"type":27,"tag":40,"props":359,"children":360},{},[361,366,371],{"type":27,"tag":44,"props":362,"children":363},{},[364],{"type":32,"value":365},"某些页面没问题",{"type":27,"tag":44,"props":367,"children":368},{},[369],{"type":32,"value":370},"某些页面的交互行为开始漂移",{"type":27,"tag":44,"props":372,"children":373},{},[374],{"type":32,"value":375},"问题很难从单一仓库 diff 中快速定位",{"type":27,"tag":28,"props":377,"children":378},{},[379],{"type":32,"value":380},"真正的问题不是“共享 UI 不可行”，而是没有建立共享模块的兼容纪律：",{"type":27,"tag":40,"props":382,"children":383},{},[384,389,394],{"type":27,"tag":44,"props":385,"children":386},{},[387],{"type":32,"value":388},"版本升级说明不清",{"type":27,"tag":44,"props":390,"children":391},{},[392],{"type":32,"value":393},"兼容窗口未定义",{"type":27,"tag":44,"props":395,"children":396},{},[397],{"type":32,"value":398},"回归范围没提前识别",{"type":27,"tag":100,"props":400,"children":402},{"id":401},"发布治理比技术接入更重要",[403],{"type":32,"value":401},{"type":27,"tag":28,"props":405,"children":406},{},[407],{"type":32,"value":408},"进入进阶阶段后，团队更应该把重心放在发布治理：",{"type":27,"tag":40,"props":410,"children":411},{},[412,417,422,427],{"type":27,"tag":44,"props":413,"children":414},{},[415],{"type":32,"value":416},"remote manifest 的版本可观测性",{"type":27,"tag":44,"props":418,"children":419},{},[420],{"type":32,"value":421},"不同子应用的兼容矩阵",{"type":27,"tag":44,"props":423,"children":424},{},[425],{"type":32,"value":426},"回滚时是否支持只回退单一 remote",{"type":27,"tag":44,"props":428,"children":429},{},[430],{"type":32,"value":431},"发布后错误是否能快速定位到具体远程模块",{"type":27,"tag":28,"props":433,"children":434},{},[435],{"type":32,"value":436},"微前端 2.0 的核心不是“更多 remote”，而是“每个 remote 都能被独立治理”。",{"type":27,"tag":100,"props":438,"children":440},{"id":439},"一份可直接复用的检查清单",[441],{"type":32,"value":439},{"type":27,"tag":40,"props":443,"children":444},{},[445,450,455,460,465,470],{"type":27,"tag":44,"props":446,"children":447},{},[448],{"type":32,"value":449},"业务边界是否先于技术拆分成立",{"type":27,"tag":44,"props":451,"children":452},{},[453],{"type":32,"value":454},"共享依赖是否只保留在真正稳定的基础层",{"type":27,"tag":44,"props":456,"children":457},{},[458],{"type":32,"value":459},"远程模块失败时是否有 fallback 和错误隔离",{"type":27,"tag":44,"props":461,"children":462},{},[463],{"type":32,"value":464},"是否能观测到当前加载的 remote 版本",{"type":27,"tag":44,"props":466,"children":467},{},[468],{"type":32,"value":469},"发布和回滚是否能以单一 remote 为单位执行",{"type":27,"tag":44,"props":471,"children":472},{},[473],{"type":32,"value":474},"团队是否定义了共享模块的兼容窗口",{"type":27,"tag":100,"props":476,"children":478},{"id":477},"总结",[479],{"type":32,"value":477},{"type":27,"tag":28,"props":481,"children":482},{},[483],{"type":32,"value":484},"Module Federation 的进阶实践，本质上是在解决“独立部署之后如何不把复杂度炸开”。真正决定项目是否成功的，不是远程模块能否加载，而是共享边界、失败边界和发布治理是否足够清楚。",{"type":27,"tag":28,"props":486,"children":487},{},[488],{"type":32,"value":489},"进一步阅读：",{"type":27,"tag":40,"props":491,"children":492},{},[493,500,507],{"type":27,"tag":44,"props":494,"children":495},{},[496],{"type":27,"tag":75,"props":497,"children":498},{"href":77},[499],{"type":32,"value":80},{"type":27,"tag":44,"props":501,"children":502},{},[503],{"type":27,"tag":75,"props":504,"children":505},{"href":93},[506],{"type":32,"value":96},{"type":27,"tag":44,"props":508,"children":509},{},[510],{"type":27,"tag":75,"props":511,"children":513},{"href":512},"/topics/frontend/large-spa-performance-optimization-guide",[514],{"type":32,"value":515},"大型 SPA 性能优化实战",{"title":7,"searchDepth":517,"depth":517,"links":518},3,[519,521,522,523,524,525,526,527],{"id":102,"depth":520,"text":105},2,{"id":136,"depth":520,"text":139},{"id":203,"depth":520,"text":206},{"id":265,"depth":520,"text":265},{"id":321,"depth":520,"text":324},{"id":401,"depth":520,"text":401},{"id":439,"depth":520,"text":439},{"id":477,"depth":520,"text":477},"markdown","content:topics:frontend:module-federation-advanced-guide.md","content","topics/frontend/module-federation-advanced-guide.md","topics/frontend/module-federation-advanced-guide","md",[535,869,1181],{"_path":536,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":537,"description":538,"keywords":539,"image":545,"author":546,"date":547,"readingTime":548,"topic":5,"body":549,"_type":528,"_id":866,"_source":530,"_file":867,"_stem":868,"_extension":533},"/topics/frontend/react-hooks-guide","React Hooks 完全指南","全面讲解 React Hooks，包括内置钩子、自定义钩子和最佳实践",[540,541,542,543,544],"React","Hooks","自定义钩子","状态管理","函数组件","/images/topics/react-hooks-guide.jpg","AI Content Team","2025-12-08",23,{"type":24,"children":550,"toc":847},[551,556,561,567,574,587,593,602,608,617,623,629,638,644,653,659,668,674,683,688,694,703,708,721,749,760,788,793],{"type":27,"tag":100,"props":552,"children":554},{"id":553},"react-hooks-完全指南",[555],{"type":32,"value":537},{"type":27,"tag":28,"props":557,"children":558},{},[559],{"type":32,"value":560},"Hooks 改变了 React 的开发方式。本文全面讲解如何使用和创建 Hooks。",{"type":27,"tag":100,"props":562,"children":564},{"id":563},"内置-hooks",[565],{"type":32,"value":566},"内置 Hooks",{"type":27,"tag":568,"props":569,"children":571},"h3",{"id":570},"usestate-状态管理",[572],{"type":32,"value":573},"useState - 状态管理",{"type":27,"tag":575,"props":576,"children":581},"pre",{"className":577,"code":579,"language":580,"meta":7},[578],"language-javascript","import { useState } from 'react'\n\nfunction Counter() {\n  const [count, setCount] = useState(0)\n  const [name, setName] = useState('John')\n  const [user, setUser] = useState({\n    age: 30,\n    email: 'john@example.com',\n  })\n  \n  // 使用函数初始化状态（对于复杂初始值）\n  const [data, setData] = useState(() => {\n    console.log('初始化数据...')\n    return fetchInitialData() // 仅在首次渲染时调用\n  })\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>计数: {count}\u003C/p>\n      \u003Cbutton onClick={() => setCount(count + 1)}>增加\u003C/button>\n      \n      {/* 函数式更新 */}\n      \u003Cbutton onClick={() => setCount(prev => prev + 1)}>\n        函数式增加\n      \u003C/button>\n      \n      {/* 更新对象 */}\n      \u003Cbutton onClick={() => setUser({ ...user, age: user.age + 1 })}>\n        增加年龄\n      \u003C/button>\n    \u003C/div>\n  )\n}\n","javascript",[582],{"type":27,"tag":583,"props":584,"children":585},"code",{"__ignoreMap":7},[586],{"type":32,"value":579},{"type":27,"tag":568,"props":588,"children":590},{"id":589},"useeffect-副作用处理",[591],{"type":32,"value":592},"useEffect - 副作用处理",{"type":27,"tag":575,"props":594,"children":597},{"className":595,"code":596,"language":580,"meta":7},[578],"import { useState, useEffect } from 'react'\n\nfunction DataFetcher() {\n  const [data, setData] = useState(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState(null)\n  const [userId, setUserId] = useState(1)\n  \n  // 副作用 - 每次渲染后执行\n  useEffect(() => {\n    console.log('组件已挂载或已更新')\n  })\n  \n  // 挂载时执行一次\n  useEffect(() => {\n    console.log('组件已挂载')\n    \n    return () => {\n      console.log('组件已卸载')\n    }\n  }, [])\n  \n  // 当 userId 改变时执行\n  useEffect(() => {\n    let isMounted = true // 防止内存泄漏\n    \n    const fetchData = async () => {\n      setLoading(true)\n      try {\n        const response = await fetch(\\`/api/users/\\${userId}\\`)\n        const result = await response.json()\n        \n        if (isMounted) {\n          setData(result)\n        }\n      } catch (err) {\n        if (isMounted) {\n          setError(err)\n        }\n      } finally {\n        if (isMounted) {\n          setLoading(false)\n        }\n      }\n    }\n    \n    fetchData()\n    \n    // 清理函数\n    return () => {\n      isMounted = false\n    }\n  }, [userId])\n  \n  if (loading) return \u003Cp>加载中...\u003C/p>\n  if (error) return \u003Cp>错误: {error.message}\u003C/p>\n  \n  return \u003Cdiv>{data && JSON.stringify(data)}\u003C/div>\n}\n",[598],{"type":27,"tag":583,"props":599,"children":600},{"__ignoreMap":7},[601],{"type":32,"value":596},{"type":27,"tag":568,"props":603,"children":605},{"id":604},"usecontext-跨组件通信",[606],{"type":32,"value":607},"useContext - 跨组件通信",{"type":27,"tag":575,"props":609,"children":612},{"className":610,"code":611,"language":580,"meta":7},[578],"import { createContext, useContext, useState } from 'react'\n\n// 创建上下文\nconst ThemeContext = createContext()\n\n// 提供者组件\nfunction ThemeProvider({ children }) {\n  const [theme, setTheme] = useState('light')\n  \n  const toggleTheme = () => {\n    setTheme(prev => prev === 'light' ? 'dark' : 'light')\n  }\n  \n  const value = { theme, toggleTheme }\n  \n  return (\n    \u003CThemeContext.Provider value={value}>\n      {children}\n    \u003C/ThemeContext.Provider>\n  )\n}\n\n// 使用 Hook\nfunction useTheme() {\n  const context = useContext(ThemeContext)\n  \n  if (!context) {\n    throw new Error('useTheme 必须在 ThemeProvider 内使用')\n  }\n  \n  return context\n}\n\n// 组件使用\nfunction App() {\n  const { theme, toggleTheme } = useTheme()\n  \n  return (\n    \u003Cdiv style={{\n      background: theme === 'light' ? '#fff' : '#333',\n      color: theme === 'light' ? '#000' : '#fff',\n    }}>\n      \u003Cp>当前主题: {theme}\u003C/p>\n      \u003Cbutton onClick={toggleTheme}>切换主题\u003C/button>\n    \u003C/div>\n  )\n}\n\n// 使用\nexport default function Root() {\n  return (\n    \u003CThemeProvider>\n      \u003CApp />\n    \u003C/ThemeProvider>\n  )\n}\n",[613],{"type":27,"tag":583,"props":614,"children":615},{"__ignoreMap":7},[616],{"type":32,"value":611},{"type":27,"tag":100,"props":618,"children":620},{"id":619},"自定义-hooks",[621],{"type":32,"value":622},"自定义 Hooks",{"type":27,"tag":568,"props":624,"children":626},{"id":625},"uselocalstorage",[627],{"type":32,"value":628},"useLocalStorage",{"type":27,"tag":575,"props":630,"children":633},{"className":631,"code":632,"language":580,"meta":7},[578],"import { useState, useEffect } from 'react'\n\nfunction useLocalStorage(key, initialValue) {\n  // 从本地存储获取初始值\n  const [storedValue, setStoredValue] = useState(() => {\n    try {\n      const item = window.localStorage.getItem(key)\n      return item ? JSON.parse(item) : initialValue\n    } catch (error) {\n      console.error(error)\n      return initialValue\n    }\n  })\n  \n  // 当值改变时更新本地存储\n  const setValue = (value) => {\n    try {\n      const valueToStore = value instanceof Function ? value(storedValue) : value\n      setStoredValue(valueToStore)\n      window.localStorage.setItem(key, JSON.stringify(valueToStore))\n    } catch (error) {\n      console.error(error)\n    }\n  }\n  \n  return [storedValue, setValue]\n}\n\n// 使用\nfunction App() {\n  const [name, setName] = useLocalStorage('name', 'Guest')\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>姓名: {name}\u003C/p>\n      \u003Cinput\n        value={name}\n        onChange={(e) => setName(e.target.value)}\n      />\n    \u003C/div>\n  )\n}\n",[634],{"type":27,"tag":583,"props":635,"children":636},{"__ignoreMap":7},[637],{"type":32,"value":632},{"type":27,"tag":568,"props":639,"children":641},{"id":640},"useasync-异步操作",[642],{"type":32,"value":643},"useAsync - 异步操作",{"type":27,"tag":575,"props":645,"children":648},{"className":646,"code":647,"language":580,"meta":7},[578],"import { useState, useEffect, useRef } from 'react'\n\nfunction useAsync(asyncFunction, immediate = true) {\n  const [status, setStatus] = useState('idle')\n  const [value, setValue] = useState(null)\n  const [error, setError] = useState(null)\n  \n  // 使用 ref 来防止无限循环\n  const executeRef = useRef(null)\n  \n  const execute = useRef(async () => {\n    setStatus('pending')\n    setValue(null)\n    setError(null)\n    \n    try {\n      const response = await asyncFunction()\n      setValue(response)\n      setStatus('success')\n      return response\n    } catch (error) {\n      setError(error)\n      setStatus('error')\n    }\n  })\n  \n  executeRef.current = execute.current\n  \n  useEffect(() => {\n    if (!immediate) return\n    \n    executeRef.current()\n  }, [immediate])\n  \n  return { execute: executeRef.current, status, value, error }\n}\n\n// 使用\nfunction UserProfile({ userId }) {\n  const { execute, status, value: user, error } = useAsync(\n    () => fetch(\\`/api/users/\\${userId}\\`).then(r => r.json()),\n    true\n  )\n  \n  if (status === 'pending') return \u003Cp>加载中...\u003C/p>\n  if (status === 'error') return \u003Cp>错误: {error?.message}\u003C/p>\n  if (status === 'success') return \u003Cp>用户: {user?.name}\u003C/p>\n  \n  return null\n}\n",[649],{"type":27,"tag":583,"props":650,"children":651},{"__ignoreMap":7},[652],{"type":32,"value":647},{"type":27,"tag":568,"props":654,"children":656},{"id":655},"usefetch-数据获取",[657],{"type":32,"value":658},"useFetch - 数据获取",{"type":27,"tag":575,"props":660,"children":663},{"className":661,"code":662,"language":580,"meta":7},[578],"import { useState, useEffect } from 'react'\n\nfunction useFetch(url, options = {}) {\n  const [data, setData] = useState(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState(null)\n  \n  useEffect(() => {\n    let isMounted = true\n    \n    const fetchData = async () => {\n      try {\n        const response = await fetch(url, {\n          method: 'GET',\n          ...options,\n        })\n        \n        if (!response.ok) {\n          throw new Error(\\`HTTP error! status: \\${response.status}\\`)\n        }\n        \n        const result = await response.json()\n        \n        if (isMounted) {\n          setData(result)\n          setError(null)\n        }\n      } catch (err) {\n        if (isMounted) {\n          setError(err)\n          setData(null)\n        }\n      } finally {\n        if (isMounted) {\n          setLoading(false)\n        }\n      }\n    }\n    \n    fetchData()\n    \n    return () => {\n      isMounted = false\n    }\n  }, [url, options])\n  \n  const refetch = async () => {\n    setLoading(true)\n    try {\n      const response = await fetch(url, options)\n      const result = await response.json()\n      setData(result)\n    } catch (err) {\n      setError(err)\n    } finally {\n      setLoading(false)\n    }\n  }\n  \n  return { data, loading, error, refetch }\n}\n\n// 使用\nfunction UserList() {\n  const { data: users, loading, error, refetch } = useFetch('/api/users')\n  \n  if (loading) return \u003Cp>加载中...\u003C/p>\n  if (error) return \u003Cp>错误: {error.message}\u003C/p>\n  \n  return (\n    \u003Cdiv>\n      \u003Cbutton onClick={refetch}>刷新\u003C/button>\n      \u003Cul>\n        {users?.map(user => (\n          \u003Cli key={user.id}>{user.name}\u003C/li>\n        ))}\n      \u003C/ul>\n    \u003C/div>\n  )\n}\n",[664],{"type":27,"tag":583,"props":665,"children":666},{"__ignoreMap":7},[667],{"type":32,"value":662},{"type":27,"tag":568,"props":669,"children":671},{"id":670},"useprevious-保存前一个值",[672],{"type":32,"value":673},"usePrevious - 保存前一个值",{"type":27,"tag":575,"props":675,"children":678},{"className":676,"code":677,"language":580,"meta":7},[578],"import { useEffect, useRef } from 'react'\n\nfunction usePrevious(value) {\n  const ref = useRef()\n  \n  useEffect(() => {\n    ref.current = value\n  }, [value])\n  \n  return ref.current\n}\n\n// 使用\nfunction Counter() {\n  const [count, setCount] = React.useState(0)\n  const prevCount = usePrevious(count)\n  \n  return (\n    \u003Cdiv>\n      \u003Cp>当前: {count}, 前一个: {prevCount}\u003C/p>\n      \u003Cbutton onClick={() => setCount(count + 1)}>增加\u003C/button>\n    \u003C/div>\n  )\n}\n",[679],{"type":27,"tag":583,"props":680,"children":681},{"__ignoreMap":7},[682],{"type":32,"value":677},{"type":27,"tag":100,"props":684,"children":686},{"id":685},"高级模式",[687],{"type":32,"value":685},{"type":27,"tag":568,"props":689,"children":691},{"id":690},"usereducer-复杂状态管理",[692],{"type":32,"value":693},"useReducer - 复杂状态管理",{"type":27,"tag":575,"props":695,"children":698},{"className":696,"code":697,"language":580,"meta":7},[578],"import { useReducer } from 'react'\n\nconst initialState = {\n  todos: [],\n  filter: 'all',\n  error: null,\n}\n\nfunction todoReducer(state, action) {\n  switch (action.type) {\n    case 'ADD_TODO':\n      return {\n        ...state,\n        todos: [...state.todos, { id: Date.now(), text: action.payload }],\n      }\n    \n    case 'REMOVE_TODO':\n      return {\n        ...state,\n        todos: state.todos.filter(todo => todo.id !== action.payload),\n      }\n    \n    case 'SET_FILTER':\n      return { ...state, filter: action.payload }\n    \n    case 'SET_ERROR':\n      return { ...state, error: action.payload }\n    \n    default:\n      return state\n  }\n}\n\nfunction TodoApp() {\n  const [state, dispatch] = useReducer(todoReducer, initialState)\n  \n  const addTodo = (text) => {\n    dispatch({ type: 'ADD_TODO', payload: text })\n  }\n  \n  const removeTodo = (id) => {\n    dispatch({ type: 'REMOVE_TODO', payload: id })\n  }\n  \n  return (\n    \u003Cdiv>\n      {state.todos.map(todo => (\n        \u003Cdiv key={todo.id}>\n          {todo.text}\n          \u003Cbutton onClick={() => removeTodo(todo.id)}>删除\u003C/button>\n        \u003C/div>\n      ))}\n    \u003C/div>\n  )\n}\n",[699],{"type":27,"tag":583,"props":700,"children":701},{"__ignoreMap":7},[702],{"type":32,"value":697},{"type":27,"tag":100,"props":704,"children":706},{"id":705},"最佳实践",[707],{"type":32,"value":705},{"type":27,"tag":28,"props":709,"children":710},{},[711,713,719],{"type":32,"value":712},"✅ ",{"type":27,"tag":714,"props":715,"children":716},"strong",{},[717],{"type":32,"value":718},"应该做的事",{"type":32,"value":720},":",{"type":27,"tag":40,"props":722,"children":723},{},[724,729,734,739,744],{"type":27,"tag":44,"props":725,"children":726},{},[727],{"type":32,"value":728},"将相关逻辑提取到自定义 Hooks",{"type":27,"tag":44,"props":730,"children":731},{},[732],{"type":32,"value":733},"在 useEffect 的依赖数组中包含所有依赖",{"type":27,"tag":44,"props":735,"children":736},{},[737],{"type":32,"value":738},"使用 useCallback 和 useMemo 优化性能",{"type":27,"tag":44,"props":740,"children":741},{},[742],{"type":32,"value":743},"为自定义 Hooks 编写文档",{"type":27,"tag":44,"props":745,"children":746},{},[747],{"type":32,"value":748},"及时清理副作用",{"type":27,"tag":28,"props":750,"children":751},{},[752,754,759],{"type":32,"value":753},"❌ ",{"type":27,"tag":714,"props":755,"children":756},{},[757],{"type":32,"value":758},"不应该做的事",{"type":32,"value":720},{"type":27,"tag":40,"props":761,"children":762},{},[763,768,773,778,783],{"type":27,"tag":44,"props":764,"children":765},{},[766],{"type":32,"value":767},"在条件或循环中调用 Hooks",{"type":27,"tag":44,"props":769,"children":770},{},[771],{"type":32,"value":772},"在普通函数中调用 Hooks",{"type":27,"tag":44,"props":774,"children":775},{},[776],{"type":32,"value":777},"忘记依赖数组",{"type":27,"tag":44,"props":779,"children":780},{},[781],{"type":32,"value":782},"过度使用 useMemo/useCallback",{"type":27,"tag":44,"props":784,"children":785},{},[786],{"type":32,"value":787},"在 Hooks 中创建过多的闭包",{"type":27,"tag":100,"props":789,"children":791},{"id":790},"检查清单",[792],{"type":32,"value":790},{"type":27,"tag":40,"props":794,"children":797},{"className":795},[796],"contains-task-list",[798,811,820,829,838],{"type":27,"tag":44,"props":799,"children":802},{"className":800},[801],"task-list-item",[803,809],{"type":27,"tag":804,"props":805,"children":808},"input",{"disabled":806,"type":807},true,"checkbox",[],{"type":32,"value":810}," Hooks 调用顺序正确",{"type":27,"tag":44,"props":812,"children":814},{"className":813},[801],[815,818],{"type":27,"tag":804,"props":816,"children":817},{"disabled":806,"type":807},[],{"type":32,"value":819}," 依赖数组完整",{"type":27,"tag":44,"props":821,"children":823},{"className":822},[801],[824,827],{"type":27,"tag":804,"props":825,"children":826},{"disabled":806,"type":807},[],{"type":32,"value":828}," 副作用正确清理",{"type":27,"tag":44,"props":830,"children":832},{"className":831},[801],[833,836],{"type":27,"tag":804,"props":834,"children":835},{"disabled":806,"type":807},[],{"type":32,"value":837}," 性能优化得当",{"type":27,"tag":44,"props":839,"children":841},{"className":840},[801],[842,845],{"type":27,"tag":804,"props":843,"children":844},{"disabled":806,"type":807},[],{"type":32,"value":846}," 代码易于理解和测试",{"title":7,"searchDepth":517,"depth":517,"links":848},[849,850,855,861,864,865],{"id":553,"depth":520,"text":537},{"id":563,"depth":520,"text":566,"children":851},[852,853,854],{"id":570,"depth":517,"text":573},{"id":589,"depth":517,"text":592},{"id":604,"depth":517,"text":607},{"id":619,"depth":520,"text":622,"children":856},[857,858,859,860],{"id":625,"depth":517,"text":628},{"id":640,"depth":517,"text":643},{"id":655,"depth":517,"text":658},{"id":670,"depth":517,"text":673},{"id":685,"depth":520,"text":685,"children":862},[863],{"id":690,"depth":517,"text":693},{"id":705,"depth":520,"text":705},{"id":790,"depth":520,"text":790},"content:topics:frontend:react-hooks-guide.md","topics/frontend/react-hooks-guide.md","topics/frontend/react-hooks-guide",{"_path":870,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":871,"description":872,"keywords":873,"image":879,"author":546,"date":547,"readingTime":880,"topic":5,"body":881,"_type":528,"_id":1178,"_source":530,"_file":1179,"_stem":1180,"_extension":533},"/topics/frontend/vue3-composition-api","Vue 3 Composition API 深度解析","全面讲解 Vue 3 Composition API 的用法、最佳实践和高级模式",[874,875,876,877,878],"Vue 3","Composition API","组合式函数","响应式系统","前端开发","/images/topics/vue3-composition-api.jpg",22,{"type":24,"children":882,"toc":1154},[883,888,893,898,904,913,918,927,931,936,945,950,956,965,970,976,985,990,995,1004,1009,1015,1024,1028,1037,1065,1074,1102,1106],{"type":27,"tag":100,"props":884,"children":886},{"id":885},"vue-3-composition-api-深度解析",[887],{"type":32,"value":871},{"type":27,"tag":28,"props":889,"children":890},{},[891],{"type":32,"value":892},"Composition API 让 Vue 应用更易于组织和重用逻辑。本文深入讲解这一核心特性。",{"type":27,"tag":100,"props":894,"children":896},{"id":895},"核心概念",[897],{"type":32,"value":895},{"type":27,"tag":568,"props":899,"children":901},{"id":900},"setup-函数",[902],{"type":32,"value":903},"setup 函数",{"type":27,"tag":575,"props":905,"children":908},{"className":906,"code":907,"language":580,"meta":7},[578],"import { ref, computed, watch } from 'vue'\n\nexport default {\n  props: ['initialCount'],\n  emits: ['count-changed'],\n  \n  setup(props, { emit, slots, expose }) {\n    // 创建响应式状态\n    const count = ref(props.initialCount)\n    const doubled = computed(() => count.value * 2)\n    \n    // 监听状态变化\n    watch(count, (newVal, oldVal) => {\n      console.log(`Count changed from ${oldVal} to ${newVal}`)\n      emit('count-changed', newVal)\n    })\n    \n    // 定义方法\n    const increment = () => count.value++\n    const decrement = () => count.value--\n    \n    // 返回模板需要的内容\n    return {\n      count,\n      doubled,\n      increment,\n      decrement,\n    }\n  },\n}\n",[909],{"type":27,"tag":583,"props":910,"children":911},{"__ignoreMap":7},[912],{"type":32,"value":907},{"type":27,"tag":568,"props":914,"children":916},{"id":915},"响应式基础",[917],{"type":32,"value":915},{"type":27,"tag":575,"props":919,"children":922},{"className":920,"code":921,"language":580,"meta":7},[578],"import { ref, reactive, readonly, isRef } from 'vue'\n\n// ref - 用于基本类型\nconst count = ref(0)\nconsole.log(count.value) // 0\ncount.value++\n\n// reactive - 用于对象\nconst state = reactive({\n  name: 'John',\n  age: 30,\n  address: {\n    city: 'Beijing',\n  },\n})\n\nstate.name = 'Jane' // 自动更新，无需 .value\n\n// readonly - 创建只读副本\nconst original = reactive({ count: 0 })\nconst copy = readonly(original)\n// copy.count++ // 错误：不能修改\n\n// isRef 检查\nconsole.log(isRef(count)) // true\nconsole.log(isRef(state)) // false\n",[923],{"type":27,"tag":583,"props":924,"children":925},{"__ignoreMap":7},[926],{"type":32,"value":921},{"type":27,"tag":100,"props":928,"children":929},{"id":876},[930],{"type":32,"value":876},{"type":27,"tag":568,"props":932,"children":934},{"id":933},"创建可重用逻辑",[935],{"type":32,"value":933},{"type":27,"tag":575,"props":937,"children":940},{"className":938,"code":939,"language":580,"meta":7},[578],"// useCounter.js - 组合式函数\nimport { ref, computed } from 'vue'\n\nexport function useCounter(initialValue = 0) {\n  const count = ref(initialValue)\n  const doubled = computed(() => count.value * 2)\n  \n  const increment = () => count.value++\n  const decrement = () => count.value--\n  const reset = () => count.value = initialValue\n  \n  return {\n    count,\n    doubled,\n    increment,\n    decrement,\n    reset,\n  }\n}\n\n// useFetch.js - 数据获取组合式函数\nimport { ref, onMounted } from 'vue'\n\nexport function useFetch(url) {\n  const data = ref(null)\n  const loading = ref(false)\n  const error = ref(null)\n  \n  const fetch = async () => {\n    loading.value = true\n    error.value = null\n    \n    try {\n      const response = await fetch(url)\n      data.value = await response.json()\n    } catch (e) {\n      error.value = e\n    } finally {\n      loading.value = false\n    }\n  }\n  \n  onMounted(fetch)\n  \n  return {\n    data,\n    loading,\n    error,\n    refetch: fetch,\n  }\n}\n\n// 使用\nexport default {\n  setup() {\n    const { count, doubled, increment } = useCounter(10)\n    const { data, loading, refetch } = useFetch('/api/data')\n    \n    return {\n      count,\n      doubled,\n      increment,\n      data,\n      loading,\n      refetch,\n    }\n  },\n}\n",[941],{"type":27,"tag":583,"props":942,"children":943},{"__ignoreMap":7},[944],{"type":32,"value":939},{"type":27,"tag":100,"props":946,"children":948},{"id":947},"生命周期钩子",[949],{"type":32,"value":947},{"type":27,"tag":568,"props":951,"children":953},{"id":952},"composition-api-中的生命周期",[954],{"type":32,"value":955},"Composition API 中的生命周期",{"type":27,"tag":575,"props":957,"children":960},{"className":958,"code":959,"language":580,"meta":7},[578],"import {\n  onBeforeMount,\n  onMounted,\n  onBeforeUpdate,\n  onUpdated,\n  onBeforeUnmount,\n  onUnmounted,\n  onErrorCaptured,\n} from 'vue'\n\nexport default {\n  setup() {\n    onBeforeMount(() => {\n      console.log('组件挂载前')\n    })\n    \n    onMounted(() => {\n      console.log('组件已挂载')\n      // 初始化事件监听器、定时器等\n    })\n    \n    onBeforeUpdate(() => {\n      console.log('组件更新前')\n    })\n    \n    onUpdated(() => {\n      console.log('组件已更新')\n    })\n    \n    onBeforeUnmount(() => {\n      console.log('组件卸载前')\n    })\n    \n    onUnmounted(() => {\n      console.log('组件已卸载')\n      // 清理事件监听器、定时器等\n    })\n    \n    onErrorCaptured((err, instance, info) => {\n      console.log('捕获错误:', err)\n      return false // 返回 false 阻止错误传播\n    })\n    \n    return {}\n  },\n}\n",[961],{"type":27,"tag":583,"props":962,"children":963},{"__ignoreMap":7},[964],{"type":32,"value":959},{"type":27,"tag":100,"props":966,"children":968},{"id":967},"模板引用",[969],{"type":32,"value":967},{"type":27,"tag":568,"props":971,"children":973},{"id":972},"访问-dom-元素",[974],{"type":32,"value":975},"访问 DOM 元素",{"type":27,"tag":575,"props":977,"children":980},{"className":978,"code":979,"language":580,"meta":7},[578],"import { ref, onMounted } from 'vue'\n\nexport default {\n  setup() {\n    const inputRef = ref(null)\n    const listRef = ref(null)\n    const dynamicRef = ref(null)\n    \n    onMounted(() => {\n      // 访问 DOM 元素\n      inputRef.value?.focus()\n      console.log(listRef.value?.offsetHeight)\n    })\n    \n    // 函数式引用\n    const assignRef = el => {\n      if (el) {\n        console.log('元素已赋值', el)\n      } else {\n        console.log('元素已移除')\n      }\n    }\n    \n    return {\n      inputRef,\n      listRef,\n      dynamicRef,\n      assignRef,\n    }\n  },\n  \n  template: \\`\n    \u003Cdiv>\n      \u003Cinput ref=\"inputRef\" />\n      \u003Cul ref=\"listRef\">\n        \u003Cli v-for=\"item in items\" :key=\"item\">{{ item }}\u003C/li>\n      \u003C/ul>\n      \u003Cdiv :ref=\"assignRef\">\u003C/div>\n    \u003C/div>\n  \\`,\n}\n",[981],{"type":27,"tag":583,"props":982,"children":983},{"__ignoreMap":7},[984],{"type":32,"value":979},{"type":27,"tag":100,"props":986,"children":988},{"id":987},"依赖注入",[989],{"type":32,"value":987},{"type":27,"tag":568,"props":991,"children":993},{"id":992},"跨组件共享数据",[994],{"type":32,"value":992},{"type":27,"tag":575,"props":996,"children":999},{"className":997,"code":998,"language":580,"meta":7},[578],"import { provide, inject, ref, readonly } from 'vue'\n\n// 父组件\nexport default {\n  setup() {\n    const theme = ref('light')\n    const user = ref({ name: 'John', role: 'admin' })\n    \n    // 提供数据给子组件\n    provide('theme', readonly(theme))\n    provide('updateTheme', (newTheme) => {\n      theme.value = newTheme\n    })\n    \n    // 使用 Symbol 作为 key 避免命名冲突\n    const userKey = Symbol()\n    provide(userKey, readonly(user))\n    \n    return {\n      theme,\n      updateTheme: (newTheme) => {\n        theme.value = newTheme\n      },\n    }\n  },\n}\n\n// 子组件\nexport default {\n  setup() {\n    // 注入数据\n    const theme = inject('theme')\n    const updateTheme = inject('updateTheme')\n    const user = inject(Symbol.for('user'))\n    \n    // 带默认值的注入\n    const config = inject('config', {\n      apiUrl: 'http://localhost:3000',\n    })\n    \n    return {\n      theme,\n      updateTheme,\n      user,\n      config,\n    }\n  },\n}\n",[1000],{"type":27,"tag":583,"props":1001,"children":1002},{"__ignoreMap":7},[1003],{"type":32,"value":998},{"type":27,"tag":100,"props":1005,"children":1007},{"id":1006},"高级状态管理",[1008],{"type":32,"value":1006},{"type":27,"tag":568,"props":1010,"children":1012},{"id":1011},"创建小型-store",[1013],{"type":32,"value":1014},"创建小型 store",{"type":27,"tag":575,"props":1016,"children":1019},{"className":1017,"code":1018,"language":580,"meta":7},[578],"import { reactive, readonly, computed } from 'vue'\n\n// store.js - 不依赖 Pinia 的简单 store\nexport function createStore() {\n  const state = reactive({\n    items: [],\n    filter: 'all',\n    sortBy: 'date',\n  })\n  \n  const filteredItems = computed(() => {\n    let result = state.items\n    \n    if (state.filter !== 'all') {\n      result = result.filter(item => item.status === state.filter)\n    }\n    \n    if (state.sortBy === 'date') {\n      result.sort((a, b) => new Date(b.date) - new Date(a.date))\n    } else if (state.sortBy === 'name') {\n      result.sort((a, b) => a.name.localeCompare(b.name))\n    }\n    \n    return result\n  })\n  \n  const actions = {\n    addItem(item) {\n      state.items.push({ ...item, id: Date.now() })\n    },\n    \n    removeItem(id) {\n      state.items = state.items.filter(item => item.id !== id)\n    },\n    \n    updateItem(id, updates) {\n      const item = state.items.find(item => item.id === id)\n      if (item) {\n        Object.assign(item, updates)\n      }\n    },\n    \n    setFilter(filter) {\n      state.filter = filter\n    },\n    \n    setSortBy(sortBy) {\n      state.sortBy = sortBy\n    },\n  }\n  \n  return {\n    state: readonly(state),\n    filteredItems,\n    ...actions,\n  }\n}\n\n// 使用\nexport default {\n  setup() {\n    const store = createStore()\n    \n    const handleAdd = (item) => {\n      store.addItem(item)\n    }\n    \n    return {\n      items: store.filteredItems,\n      addItem: handleAdd,\n      setFilter: store.setFilter,\n    }\n  },\n}\n",[1020],{"type":27,"tag":583,"props":1021,"children":1022},{"__ignoreMap":7},[1023],{"type":32,"value":1018},{"type":27,"tag":100,"props":1025,"children":1026},{"id":705},[1027],{"type":32,"value":705},{"type":27,"tag":28,"props":1029,"children":1030},{},[1031,1032,1036],{"type":32,"value":712},{"type":27,"tag":714,"props":1033,"children":1034},{},[1035],{"type":32,"value":718},{"type":32,"value":720},{"type":27,"tag":40,"props":1038,"children":1039},{},[1040,1045,1050,1055,1060],{"type":27,"tag":44,"props":1041,"children":1042},{},[1043],{"type":32,"value":1044},"将相关逻辑组织在一起",{"type":27,"tag":44,"props":1046,"children":1047},{},[1048],{"type":32,"value":1049},"创建可重用的组合式函数",{"type":27,"tag":44,"props":1051,"children":1052},{},[1053],{"type":32,"value":1054},"使用 TypeScript 获得更好的类型检查",{"type":27,"tag":44,"props":1056,"children":1057},{},[1058],{"type":32,"value":1059},"合理使用计算属性和监听器",{"type":27,"tag":44,"props":1061,"children":1062},{},[1063],{"type":32,"value":1064},"及时清理事件监听器和定时器",{"type":27,"tag":28,"props":1066,"children":1067},{},[1068,1069,1073],{"type":32,"value":753},{"type":27,"tag":714,"props":1070,"children":1071},{},[1072],{"type":32,"value":758},{"type":32,"value":720},{"type":27,"tag":40,"props":1075,"children":1076},{},[1077,1082,1087,1092,1097],{"type":27,"tag":44,"props":1078,"children":1079},{},[1080],{"type":32,"value":1081},"在 setup 中执行副作用操作（除了生命周期钩子）",{"type":27,"tag":44,"props":1083,"children":1084},{},[1085],{"type":32,"value":1086},"过度使用计算属性",{"type":27,"tag":44,"props":1088,"children":1089},{},[1090],{"type":32,"value":1091},"忘记清理 watch 监听器",{"type":27,"tag":44,"props":1093,"children":1094},{},[1095],{"type":32,"value":1096},"在 reactive 对象中存储引用类型时不谨慎",{"type":27,"tag":44,"props":1098,"children":1099},{},[1100],{"type":32,"value":1101},"过度复杂化组合式函数",{"type":27,"tag":100,"props":1103,"children":1104},{"id":790},[1105],{"type":32,"value":790},{"type":27,"tag":40,"props":1107,"children":1109},{"className":1108},[796],[1110,1119,1128,1137,1146],{"type":27,"tag":44,"props":1111,"children":1113},{"className":1112},[801],[1114,1117],{"type":27,"tag":804,"props":1115,"children":1116},{"disabled":806,"type":807},[],{"type":32,"value":1118}," 正确使用 ref 和 reactive",{"type":27,"tag":44,"props":1120,"children":1122},{"className":1121},[801],[1123,1126],{"type":27,"tag":804,"props":1124,"children":1125},{"disabled":806,"type":807},[],{"type":32,"value":1127}," 生命周期钩子正确",{"type":27,"tag":44,"props":1129,"children":1131},{"className":1130},[801],[1132,1135],{"type":27,"tag":804,"props":1133,"children":1134},{"disabled":806,"type":807},[],{"type":32,"value":1136}," 模板引用工作正常",{"type":27,"tag":44,"props":1138,"children":1140},{"className":1139},[801],[1141,1144],{"type":27,"tag":804,"props":1142,"children":1143},{"disabled":806,"type":807},[],{"type":32,"value":1145}," 组合式函数可重用",{"type":27,"tag":44,"props":1147,"children":1149},{"className":1148},[801],[1150,1153],{"type":27,"tag":804,"props":1151,"children":1152},{"disabled":806,"type":807},[],{"type":32,"value":837},{"title":7,"searchDepth":517,"depth":517,"links":1155},[1156,1157,1161,1164,1167,1170,1173,1176,1177],{"id":885,"depth":520,"text":871},{"id":895,"depth":520,"text":895,"children":1158},[1159,1160],{"id":900,"depth":517,"text":903},{"id":915,"depth":517,"text":915},{"id":876,"depth":520,"text":876,"children":1162},[1163],{"id":933,"depth":517,"text":933},{"id":947,"depth":520,"text":947,"children":1165},[1166],{"id":952,"depth":517,"text":955},{"id":967,"depth":520,"text":967,"children":1168},[1169],{"id":972,"depth":517,"text":975},{"id":987,"depth":520,"text":987,"children":1171},[1172],{"id":992,"depth":517,"text":992},{"id":1006,"depth":520,"text":1006,"children":1174},[1175],{"id":1011,"depth":517,"text":1014},{"id":705,"depth":520,"text":705},{"id":790,"depth":520,"text":790},"content:topics:frontend:vue3-composition-api.md","topics/frontend/vue3-composition-api.md","topics/frontend/vue3-composition-api",{"_path":1182,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1183,"description":1184,"date":1185,"topic":5,"author":11,"tags":1186,"image":1192,"featured":806,"readingTime":1193,"body":1194,"_type":528,"_id":2455,"_source":530,"_file":2456,"_stem":2457,"_extension":533},"/topics/frontend/rspack-performance-practice","Rspack 构建性能实战","从 Rspack 的架构设计与编译管线出发，系统对比 Webpack/Vite 并给出 Rspack 在大型项目中的迁移路径、性能调优策略与生产级可观测方案。","2026-01-20",[1187,1188,1189,1190,1191],"Rspack","构建工具","性能优化","Webpack","前端工程化","/images/topics/rspack.jpg",25,{"type":24,"children":1195,"toc":2422},[1196,1201,1213,1218,1236,1247,1252,1275,1279,1285,1290,1296,1329,1335,1353,1356,1362,1368,1373,1386,1392,1397,1410,1416,1434,1439,1442,1448,1453,1594,1599,1622,1625,1631,1637,1642,1647,1715,1728,1734,1742,1755,1763,1776,1784,1797,1803,1821,1824,1830,1836,1841,1854,1860,1865,1876,1882,1887,1905,1910,1938,1941,1947,1952,1963,1968,1986,1991,2009,2012,2018,2023,2041,2046,2069,2074,2092,2095,2101,2107,2112,2130,2136,2154,2160,2178,2181,2187,2302,2307,2325,2328,2334,2392,2395,2399,2404],{"type":27,"tag":100,"props":1197,"children":1199},{"id":1198},"rspack-构建性能实战",[1200],{"type":32,"value":1183},{"type":27,"tag":28,"props":1202,"children":1203},{},[1204,1206,1211],{"type":32,"value":1205},"Rspack 不是\"又一个构建工具\"，而是字节跳动在处理",{"type":27,"tag":714,"props":1207,"children":1208},{},[1209],{"type":32,"value":1210},"超大规模前端项目",{"type":32,"value":1212},"时，对 Webpack 生态的 Rust 重写与工程化沉淀。",{"type":27,"tag":28,"props":1214,"children":1215},{},[1216],{"type":32,"value":1217},"它要解决的核心问题是：",{"type":27,"tag":40,"props":1219,"children":1220},{},[1221,1226,1231],{"type":27,"tag":44,"props":1222,"children":1223},{},[1224],{"type":32,"value":1225},"Webpack 的构建速度在大型 monorepo 下（10k+ 模块）已成为开发体验瓶颈",{"type":27,"tag":44,"props":1227,"children":1228},{},[1229],{"type":32,"value":1230},"但你又无法抛弃 Webpack 的插件生态与配置范式",{"type":27,"tag":44,"props":1232,"children":1233},{},[1234],{"type":32,"value":1235},"Vite 虽然快，但在某些场景（大型遗留项目、特定插件依赖）迁移成本高",{"type":27,"tag":28,"props":1237,"children":1238},{},[1239,1241,1246],{"type":32,"value":1240},"Rspack 的定位是：",{"type":27,"tag":714,"props":1242,"children":1243},{},[1244],{"type":32,"value":1245},"Webpack 兼容 API + Rust 性能 + 生产级稳定性",{"type":32,"value":98},{"type":27,"tag":28,"props":1248,"children":1249},{},[1250],{"type":32,"value":1251},"这篇文章不讲\"Hello World\"，而是按\"你要在生产上稳定用 Rspack\"的标准，给出：",{"type":27,"tag":40,"props":1253,"children":1254},{},[1255,1260,1265,1270],{"type":27,"tag":44,"props":1256,"children":1257},{},[1258],{"type":32,"value":1259},"性能收益的真实量化方法",{"type":27,"tag":44,"props":1261,"children":1262},{},[1263],{"type":32,"value":1264},"迁移路径与兼容性边界",{"type":27,"tag":44,"props":1266,"children":1267},{},[1268],{"type":32,"value":1269},"优化策略（缓存、并行、Tree Shaking）",{"type":27,"tag":44,"props":1271,"children":1272},{},[1273],{"type":32,"value":1274},"监控与排障（为什么变慢、为什么产物变大）",{"type":27,"tag":1276,"props":1277,"children":1278},"hr",{},[],{"type":27,"tag":100,"props":1280,"children":1282},{"id":1281},"_1-先回答什么项目值得迁移-rspack",[1283],{"type":32,"value":1284},"1. 先回答：什么项目值得迁移 Rspack？",{"type":27,"tag":28,"props":1286,"children":1287},{},[1288],{"type":32,"value":1289},"不是所有项目都需要 Rspack。",{"type":27,"tag":568,"props":1291,"children":1293},{"id":1292},"_11-高收益场景",[1294],{"type":32,"value":1295},"1.1 高收益场景",{"type":27,"tag":40,"props":1297,"children":1298},{},[1299,1309,1319],{"type":27,"tag":44,"props":1300,"children":1301},{},[1302,1307],{"type":27,"tag":714,"props":1303,"children":1304},{},[1305],{"type":32,"value":1306},"大型 monorepo",{"type":32,"value":1308},"（5k+ 模块，构建时间 > 2 分钟）",{"type":27,"tag":44,"props":1310,"children":1311},{},[1312,1317],{"type":27,"tag":714,"props":1313,"children":1314},{},[1315],{"type":32,"value":1316},"频繁开发迭代",{"type":32,"value":1318},"（HMR 延迟影响体验）",{"type":27,"tag":44,"props":1320,"children":1321},{},[1322,1327],{"type":27,"tag":714,"props":1323,"children":1324},{},[1325],{"type":32,"value":1326},"CI 构建成本高",{"type":32,"value":1328},"（每次 PR 构建超 10 分钟）",{"type":27,"tag":568,"props":1330,"children":1332},{"id":1331},"_12-收益不明显的场景",[1333],{"type":32,"value":1334},"1.2 收益不明显的场景",{"type":27,"tag":40,"props":1336,"children":1337},{},[1338,1343,1348],{"type":27,"tag":44,"props":1339,"children":1340},{},[1341],{"type":32,"value":1342},"小型项目（\u003C 1k 模块）",{"type":27,"tag":44,"props":1344,"children":1345},{},[1346],{"type":32,"value":1347},"已经用 Vite 且体验良好",{"type":27,"tag":44,"props":1349,"children":1350},{},[1351],{"type":32,"value":1352},"高度定制的 Webpack 插件（迁移成本 > 性能收益）",{"type":27,"tag":1276,"props":1354,"children":1355},{},[],{"type":27,"tag":100,"props":1357,"children":1359},{"id":1358},"_2-rspack-的架构为什么能快",[1360],{"type":32,"value":1361},"2. Rspack 的架构：为什么能快？",{"type":27,"tag":568,"props":1363,"children":1365},{"id":1364},"_21-rust-并行编译",[1366],{"type":32,"value":1367},"2.1 Rust 并行编译",{"type":27,"tag":28,"props":1369,"children":1370},{},[1371],{"type":32,"value":1372},"Webpack 是单线程 JavaScript，Rspack 是多线程 Rust。",{"type":27,"tag":40,"props":1374,"children":1375},{},[1376,1381],{"type":27,"tag":44,"props":1377,"children":1378},{},[1379],{"type":32,"value":1380},"模块解析、编译、优化可并行",{"type":27,"tag":44,"props":1382,"children":1383},{},[1384],{"type":32,"value":1385},"I/O 密集型任务（读文件、写产物）异步化",{"type":27,"tag":568,"props":1387,"children":1389},{"id":1388},"_22-更激进的缓存策略",[1390],{"type":32,"value":1391},"2.2 更激进的缓存策略",{"type":27,"tag":28,"props":1393,"children":1394},{},[1395],{"type":32,"value":1396},"Rspack 内置持久化缓存：",{"type":27,"tag":40,"props":1398,"children":1399},{},[1400,1405],{"type":27,"tag":44,"props":1401,"children":1402},{},[1403],{"type":32,"value":1404},"模块级别缓存（类似 Webpack 5 的 cache.type: 'filesystem'）",{"type":27,"tag":44,"props":1406,"children":1407},{},[1408],{"type":32,"value":1409},"但实现更激进：对未变化模块跳过编译",{"type":27,"tag":568,"props":1411,"children":1413},{"id":1412},"_23-内置常用功能减少插件开销",[1414],{"type":32,"value":1415},"2.3 内置常用功能（减少插件开销）",{"type":27,"tag":40,"props":1417,"children":1418},{},[1419,1424,1429],{"type":27,"tag":44,"props":1420,"children":1421},{},[1422],{"type":32,"value":1423},"SWC 替代 Babel（内置 TS/JSX/装饰器）",{"type":27,"tag":44,"props":1425,"children":1426},{},[1427],{"type":32,"value":1428},"CSS Modules、PostCSS 内置",{"type":27,"tag":44,"props":1430,"children":1431},{},[1432],{"type":32,"value":1433},"Tree Shaking 内置",{"type":27,"tag":28,"props":1435,"children":1436},{},[1437],{"type":32,"value":1438},"这让 Rspack 在相同功能下比 Webpack + 插件链路更快。",{"type":27,"tag":1276,"props":1440,"children":1441},{},[],{"type":27,"tag":100,"props":1443,"children":1445},{"id":1444},"_3-性能对比真实场景的量化",[1446],{"type":32,"value":1447},"3. 性能对比：真实场景的量化",{"type":27,"tag":28,"props":1449,"children":1450},{},[1451],{"type":32,"value":1452},"我们用一个典型中型项目（3k 模块，React + TS + CSS Modules）做对比：",{"type":27,"tag":1454,"props":1455,"children":1456},"table",{},[1457,1485],{"type":27,"tag":1458,"props":1459,"children":1460},"thead",{},[1461],{"type":27,"tag":1462,"props":1463,"children":1464},"tr",{},[1465,1471,1476,1480],{"type":27,"tag":1466,"props":1467,"children":1468},"th",{},[1469],{"type":32,"value":1470},"指标",{"type":27,"tag":1466,"props":1472,"children":1473},{},[1474],{"type":32,"value":1475},"Webpack 5",{"type":27,"tag":1466,"props":1477,"children":1478},{},[1479],{"type":32,"value":1187},{"type":27,"tag":1466,"props":1481,"children":1482},{},[1483],{"type":32,"value":1484},"提升",{"type":27,"tag":1486,"props":1487,"children":1488},"tbody",{},[1489,1516,1542,1568],{"type":27,"tag":1462,"props":1490,"children":1491},{},[1492,1498,1503,1508],{"type":27,"tag":1493,"props":1494,"children":1495},"td",{},[1496],{"type":32,"value":1497},"冷启动",{"type":27,"tag":1493,"props":1499,"children":1500},{},[1501],{"type":32,"value":1502},"42s",{"type":27,"tag":1493,"props":1504,"children":1505},{},[1506],{"type":32,"value":1507},"8s",{"type":27,"tag":1493,"props":1509,"children":1510},{},[1511],{"type":27,"tag":714,"props":1512,"children":1513},{},[1514],{"type":32,"value":1515},"5.2x",{"type":27,"tag":1462,"props":1517,"children":1518},{},[1519,1524,1529,1534],{"type":27,"tag":1493,"props":1520,"children":1521},{},[1522],{"type":32,"value":1523},"HMR（热更新）",{"type":27,"tag":1493,"props":1525,"children":1526},{},[1527],{"type":32,"value":1528},"1.2s",{"type":27,"tag":1493,"props":1530,"children":1531},{},[1532],{"type":32,"value":1533},"0.15s",{"type":27,"tag":1493,"props":1535,"children":1536},{},[1537],{"type":27,"tag":714,"props":1538,"children":1539},{},[1540],{"type":32,"value":1541},"8x",{"type":27,"tag":1462,"props":1543,"children":1544},{},[1545,1550,1555,1560],{"type":27,"tag":1493,"props":1546,"children":1547},{},[1548],{"type":32,"value":1549},"生产构建",{"type":27,"tag":1493,"props":1551,"children":1552},{},[1553],{"type":32,"value":1554},"125s",{"type":27,"tag":1493,"props":1556,"children":1557},{},[1558],{"type":32,"value":1559},"28s",{"type":27,"tag":1493,"props":1561,"children":1562},{},[1563],{"type":27,"tag":714,"props":1564,"children":1565},{},[1566],{"type":32,"value":1567},"4.5x",{"type":27,"tag":1462,"props":1569,"children":1570},{},[1571,1576,1581,1586],{"type":27,"tag":1493,"props":1572,"children":1573},{},[1574],{"type":32,"value":1575},"内存峰值",{"type":27,"tag":1493,"props":1577,"children":1578},{},[1579],{"type":32,"value":1580},"1.8GB",{"type":27,"tag":1493,"props":1582,"children":1583},{},[1584],{"type":32,"value":1585},"0.9GB",{"type":27,"tag":1493,"props":1587,"children":1588},{},[1589],{"type":27,"tag":714,"props":1590,"children":1591},{},[1592],{"type":32,"value":1593},"2x",{"type":27,"tag":28,"props":1595,"children":1596},{},[1597],{"type":32,"value":1598},"关键收益：",{"type":27,"tag":40,"props":1600,"children":1601},{},[1602,1612],{"type":27,"tag":44,"props":1603,"children":1604},{},[1605,1610],{"type":27,"tag":714,"props":1606,"children":1607},{},[1608],{"type":32,"value":1609},"开发体验质变",{"type":32,"value":1611},"（HMR \u003C 200ms）",{"type":27,"tag":44,"props":1613,"children":1614},{},[1615,1620],{"type":27,"tag":714,"props":1616,"children":1617},{},[1618],{"type":32,"value":1619},"CI 成本减半",{"type":32,"value":1621},"（构建时间直接影响 Runner 费用）",{"type":27,"tag":1276,"props":1623,"children":1624},{},[],{"type":27,"tag":100,"props":1626,"children":1628},{"id":1627},"_4-迁移路径从-webpack-到-rspack",[1629],{"type":32,"value":1630},"4. 迁移路径：从 Webpack 到 Rspack",{"type":27,"tag":568,"props":1632,"children":1634},{"id":1633},"_41-最小迁移保守策略",[1635],{"type":32,"value":1636},"4.1 最小迁移（保守策略）",{"type":27,"tag":28,"props":1638,"children":1639},{},[1640],{"type":32,"value":1641},"目标：用最小改动换取性能收益。",{"type":27,"tag":28,"props":1643,"children":1644},{},[1645],{"type":32,"value":1646},"步骤：",{"type":27,"tag":1648,"props":1649,"children":1650},"ol",{},[1651,1670,1689,1710],{"type":27,"tag":44,"props":1652,"children":1653},{},[1654,1656,1662,1664],{"type":32,"value":1655},"安装 ",{"type":27,"tag":583,"props":1657,"children":1659},{"className":1658},[],[1660],{"type":32,"value":1661},"@rspack/cli",{"type":32,"value":1663}," 与 ",{"type":27,"tag":583,"props":1665,"children":1667},{"className":1666},[],[1668],{"type":32,"value":1669},"@rspack/core",{"type":27,"tag":44,"props":1671,"children":1672},{},[1673,1675,1681,1683],{"type":32,"value":1674},"把 ",{"type":27,"tag":583,"props":1676,"children":1678},{"className":1677},[],[1679],{"type":32,"value":1680},"webpack.config.js",{"type":32,"value":1682}," 改为 ",{"type":27,"tag":583,"props":1684,"children":1686},{"className":1685},[],[1687],{"type":32,"value":1688},"rspack.config.js",{"type":27,"tag":44,"props":1690,"children":1691},{},[1692,1694,1700,1702,1708],{"type":32,"value":1693},"替换构建命令（",{"type":27,"tag":583,"props":1695,"children":1697},{"className":1696},[],[1698],{"type":32,"value":1699},"rspack build",{"type":32,"value":1701}," / ",{"type":27,"tag":583,"props":1703,"children":1705},{"className":1704},[],[1706],{"type":32,"value":1707},"rspack dev",{"type":32,"value":1709},"）",{"type":27,"tag":44,"props":1711,"children":1712},{},[1713],{"type":32,"value":1714},"运行并修复兼容性问题",{"type":27,"tag":28,"props":1716,"children":1717},{},[1718,1720,1726],{"type":32,"value":1719},"预计迁移成本：1",{"type":27,"tag":1721,"props":1722,"children":1723},"del",{},[1724],{"type":32,"value":1725},"2 天（小型项目）/ 1",{"type":32,"value":1727},"2 周（大型项目）",{"type":27,"tag":568,"props":1729,"children":1731},{"id":1730},"_42-兼容性边界哪些需要调整",[1732],{"type":32,"value":1733},"4.2 兼容性边界：哪些需要调整",{"type":27,"tag":28,"props":1735,"children":1736},{},[1737],{"type":27,"tag":714,"props":1738,"children":1739},{},[1740],{"type":32,"value":1741},"插件兼容",{"type":27,"tag":40,"props":1743,"children":1744},{},[1745,1750],{"type":27,"tag":44,"props":1746,"children":1747},{},[1748],{"type":32,"value":1749},"Rspack 支持大部分 Webpack 插件（API 兼容）",{"type":27,"tag":44,"props":1751,"children":1752},{},[1753],{"type":32,"value":1754},"但少数复杂插件（例如深度依赖 Webpack 内部 API）需要适配",{"type":27,"tag":28,"props":1756,"children":1757},{},[1758],{"type":27,"tag":714,"props":1759,"children":1760},{},[1761],{"type":32,"value":1762},"Loader 兼容",{"type":27,"tag":40,"props":1764,"children":1765},{},[1766,1771],{"type":27,"tag":44,"props":1767,"children":1768},{},[1769],{"type":32,"value":1770},"常用 loader（babel-loader、css-loader、postcss-loader）兼容",{"type":27,"tag":44,"props":1772,"children":1773},{},[1774],{"type":32,"value":1775},"部分自定义 loader 需要测试",{"type":27,"tag":28,"props":1777,"children":1778},{},[1779],{"type":27,"tag":714,"props":1780,"children":1781},{},[1782],{"type":32,"value":1783},"配置差异",{"type":27,"tag":40,"props":1785,"children":1786},{},[1787,1792],{"type":27,"tag":44,"props":1788,"children":1789},{},[1790],{"type":32,"value":1791},"resolve、output、optimization 等配置与 Webpack 高度一致",{"type":27,"tag":44,"props":1793,"children":1794},{},[1795],{"type":32,"value":1796},"少数高级配置需要查文档",{"type":27,"tag":568,"props":1798,"children":1800},{"id":1799},"_43-推荐的迁移节奏",[1801],{"type":32,"value":1802},"4.3 推荐的迁移节奏",{"type":27,"tag":40,"props":1804,"children":1805},{},[1806,1811,1816],{"type":27,"tag":44,"props":1807,"children":1808},{},[1809],{"type":32,"value":1810},"Week 1：本地开发环境先行",{"type":27,"tag":44,"props":1812,"children":1813},{},[1814],{"type":32,"value":1815},"Week 2：CI 构建切换（并保留 Webpack 作为 fallback）",{"type":27,"tag":44,"props":1817,"children":1818},{},[1819],{"type":32,"value":1820},"Week 3~4：生产构建切换并观测",{"type":27,"tag":1276,"props":1822,"children":1823},{},[],{"type":27,"tag":100,"props":1825,"children":1827},{"id":1826},"_5-性能调优让-rspack-更快",[1828],{"type":32,"value":1829},"5. 性能调优：让 Rspack 更快",{"type":27,"tag":568,"props":1831,"children":1833},{"id":1832},"_51-缓存策略",[1834],{"type":32,"value":1835},"5.1 缓存策略",{"type":27,"tag":28,"props":1837,"children":1838},{},[1839],{"type":32,"value":1840},"默认缓存已经很激进，但你可以：",{"type":27,"tag":40,"props":1842,"children":1843},{},[1844,1849],{"type":27,"tag":44,"props":1845,"children":1846},{},[1847],{"type":32,"value":1848},"显式配置缓存目录（例如挂载 SSD）",{"type":27,"tag":44,"props":1850,"children":1851},{},[1852],{"type":32,"value":1853},"在 CI 上持久化缓存（例如用 actions/cache）",{"type":27,"tag":568,"props":1855,"children":1857},{"id":1856},"_52-并行度调优",[1858],{"type":32,"value":1859},"5.2 并行度调优",{"type":27,"tag":28,"props":1861,"children":1862},{},[1863],{"type":32,"value":1864},"Rspack 默认会用所有 CPU 核心，但在容器环境（例如 CI）可能需要限制：",{"type":27,"tag":575,"props":1866,"children":1871},{"className":1867,"code":1869,"language":1870,"meta":7},[1868],"language-js","module.exports = {\n  experiments: {\n    rspackFuture: {\n      disableTransformByDefault: true, // 减少不必要转换\n    },\n  },\n}\n","js",[1872],{"type":27,"tag":583,"props":1873,"children":1874},{"__ignoreMap":7},[1875],{"type":32,"value":1869},{"type":27,"tag":568,"props":1877,"children":1879},{"id":1878},"_53-tree-shaking-与-dead-code-elimination",[1880],{"type":32,"value":1881},"5.3 Tree Shaking 与 Dead Code Elimination",{"type":27,"tag":28,"props":1883,"children":1884},{},[1885],{"type":32,"value":1886},"Rspack 内置 Tree Shaking，但效果取决于：",{"type":27,"tag":40,"props":1888,"children":1889},{},[1890,1895,1900],{"type":27,"tag":44,"props":1891,"children":1892},{},[1893],{"type":32,"value":1894},"是否使用 ESM（而非 CommonJS）",{"type":27,"tag":44,"props":1896,"children":1897},{},[1898],{"type":32,"value":1899},"副作用标记（sideEffects: false）",{"type":27,"tag":44,"props":1901,"children":1902},{},[1903],{"type":32,"value":1904},"动态 import 的拆分策略",{"type":27,"tag":28,"props":1906,"children":1907},{},[1908],{"type":32,"value":1909},"建议：",{"type":27,"tag":40,"props":1911,"children":1912},{},[1913,1926],{"type":27,"tag":44,"props":1914,"children":1915},{},[1916,1918,1924],{"type":32,"value":1917},"对第三方库检查 ",{"type":27,"tag":583,"props":1919,"children":1921},{"className":1920},[],[1922],{"type":32,"value":1923},"sideEffects",{"type":32,"value":1925}," 配置",{"type":27,"tag":44,"props":1927,"children":1928},{},[1929,1931,1937],{"type":32,"value":1930},"避免\"全量引入后 tree shake\"（例如 ",{"type":27,"tag":583,"props":1932,"children":1934},{"className":1933},[],[1935],{"type":32,"value":1936},"import * from 'lodash'",{"type":32,"value":1709},{"type":27,"tag":1276,"props":1939,"children":1940},{},[],{"type":27,"tag":100,"props":1942,"children":1944},{"id":1943},"_6-产物分析与优化",[1945],{"type":32,"value":1946},"6. 产物分析与优化",{"type":27,"tag":28,"props":1948,"children":1949},{},[1950],{"type":32,"value":1951},"Rspack 提供内置分析工具：",{"type":27,"tag":575,"props":1953,"children":1958},{"className":1954,"code":1956,"language":1957,"meta":7},[1955],"language-bash","rspack build --analyze\n","bash",[1959],{"type":27,"tag":583,"props":1960,"children":1961},{"__ignoreMap":7},[1962],{"type":32,"value":1956},{"type":27,"tag":28,"props":1964,"children":1965},{},[1966],{"type":32,"value":1967},"关键指标：",{"type":27,"tag":40,"props":1969,"children":1970},{},[1971,1976,1981],{"type":27,"tag":44,"props":1972,"children":1973},{},[1974],{"type":32,"value":1975},"各 chunk 体积分布",{"type":27,"tag":44,"props":1977,"children":1978},{},[1979],{"type":32,"value":1980},"重复依赖（例如多个版本的 lodash）",{"type":27,"tag":44,"props":1982,"children":1983},{},[1984],{"type":32,"value":1985},"未被 tree shake 的代码",{"type":27,"tag":28,"props":1987,"children":1988},{},[1989],{"type":32,"value":1990},"优化策略：",{"type":27,"tag":40,"props":1992,"children":1993},{},[1994,1999,2004],{"type":27,"tag":44,"props":1995,"children":1996},{},[1997],{"type":32,"value":1998},"拆分 vendor chunk（按更新频率）",{"type":27,"tag":44,"props":2000,"children":2001},{},[2002],{"type":32,"value":2003},"对大型库按需引入（例如 antd/lodash-es）",{"type":27,"tag":44,"props":2005,"children":2006},{},[2007],{"type":32,"value":2008},"检查动态 import 的粒度",{"type":27,"tag":1276,"props":2010,"children":2011},{},[],{"type":27,"tag":100,"props":2013,"children":2015},{"id":2014},"_7-生产可观测性让构建可量化",[2016],{"type":32,"value":2017},"7. 生产可观测性：让构建可量化",{"type":27,"tag":28,"props":2019,"children":2020},{},[2021],{"type":32,"value":2022},"在 CI/CD 里，你需要能回答：",{"type":27,"tag":40,"props":2024,"children":2025},{},[2026,2031,2036],{"type":27,"tag":44,"props":2027,"children":2028},{},[2029],{"type":32,"value":2030},"这次构建为什么变慢？",{"type":27,"tag":44,"props":2032,"children":2033},{},[2034],{"type":32,"value":2035},"产物为什么变大？",{"type":27,"tag":44,"props":2037,"children":2038},{},[2039],{"type":32,"value":2040},"哪个模块耗时最多？",{"type":27,"tag":28,"props":2042,"children":2043},{},[2044],{"type":32,"value":2045},"建议在 CI 里记录：",{"type":27,"tag":40,"props":2047,"children":2048},{},[2049,2054,2059,2064],{"type":27,"tag":44,"props":2050,"children":2051},{},[2052],{"type":32,"value":2053},"构建总耗时",{"type":27,"tag":44,"props":2055,"children":2056},{},[2057],{"type":32,"value":2058},"各阶段耗时（resolve、compile、optimize、emit）",{"type":27,"tag":44,"props":2060,"children":2061},{},[2062],{"type":32,"value":2063},"产物体积（按 chunk）",{"type":27,"tag":44,"props":2065,"children":2066},{},[2067],{"type":32,"value":2068},"缓存命中率",{"type":27,"tag":28,"props":2070,"children":2071},{},[2072],{"type":32,"value":2073},"落地方式：",{"type":27,"tag":40,"props":2075,"children":2076},{},[2077,2082,2087],{"type":27,"tag":44,"props":2078,"children":2079},{},[2080],{"type":32,"value":2081},"用 Rspack 的 stats 输出",{"type":27,"tag":44,"props":2083,"children":2084},{},[2085],{"type":32,"value":2086},"在 CI 日志里保留关键指标",{"type":27,"tag":44,"props":2088,"children":2089},{},[2090],{"type":32,"value":2091},"对产物体积做 baseline 对比（变化 > 5% 报警）",{"type":27,"tag":1276,"props":2093,"children":2094},{},[],{"type":27,"tag":100,"props":2096,"children":2098},{"id":2097},"_8-常见问题排查",[2099],{"type":32,"value":2100},"8. 常见问题排查",{"type":27,"tag":568,"props":2102,"children":2104},{"id":2103},"_81-迁移后变慢了",[2105],{"type":32,"value":2106},"8.1 \"迁移后变慢了\"",{"type":27,"tag":28,"props":2108,"children":2109},{},[2110],{"type":32,"value":2111},"排查顺序：",{"type":27,"tag":40,"props":2113,"children":2114},{},[2115,2120,2125],{"type":27,"tag":44,"props":2116,"children":2117},{},[2118],{"type":32,"value":2119},"缓存是否生效（首次构建慢正常）",{"type":27,"tag":44,"props":2121,"children":2122},{},[2123],{"type":32,"value":2124},"是否有 loader 拖慢（例如未优化的自定义 loader）",{"type":27,"tag":44,"props":2126,"children":2127},{},[2128],{"type":32,"value":2129},"并行度是否受限（例如 CI 限制 CPU）",{"type":27,"tag":568,"props":2131,"children":2133},{"id":2132},"_82-产物体积变大了",[2134],{"type":32,"value":2135},"8.2 \"产物体积变大了\"",{"type":27,"tag":40,"props":2137,"children":2138},{},[2139,2144,2149],{"type":27,"tag":44,"props":2140,"children":2141},{},[2142],{"type":32,"value":2143},"检查 Tree Shaking 是否生效",{"type":27,"tag":44,"props":2145,"children":2146},{},[2147],{"type":32,"value":2148},"检查是否引入了更多 polyfill",{"type":27,"tag":44,"props":2150,"children":2151},{},[2152],{"type":32,"value":2153},"对比 chunk 分布（用 analyze）",{"type":27,"tag":568,"props":2155,"children":2157},{"id":2156},"_83-某些模块编译失败",[2158],{"type":32,"value":2159},"8.3 \"某些模块编译失败\"",{"type":27,"tag":40,"props":2161,"children":2162},{},[2163,2168,2173],{"type":27,"tag":44,"props":2164,"children":2165},{},[2166],{"type":32,"value":2167},"检查是否依赖 Webpack 特定 API",{"type":27,"tag":44,"props":2169,"children":2170},{},[2171],{"type":32,"value":2172},"查看 Rspack 官方兼容性列表",{"type":27,"tag":44,"props":2174,"children":2175},{},[2176],{"type":32,"value":2177},"在 GitHub Issues 搜索类似问题",{"type":27,"tag":1276,"props":2179,"children":2180},{},[],{"type":27,"tag":100,"props":2182,"children":2184},{"id":2183},"_9-rspack-vs-vite什么时候选哪个",[2185],{"type":32,"value":2186},"9. Rspack vs Vite：什么时候选哪个？",{"type":27,"tag":1454,"props":2188,"children":2189},{},[2190,2210],{"type":27,"tag":1458,"props":2191,"children":2192},{},[2193],{"type":27,"tag":1462,"props":2194,"children":2195},{},[2196,2201,2205],{"type":27,"tag":1466,"props":2197,"children":2198},{},[2199],{"type":32,"value":2200},"维度",{"type":27,"tag":1466,"props":2202,"children":2203},{},[2204],{"type":32,"value":1187},{"type":27,"tag":1466,"props":2206,"children":2207},{},[2208],{"type":32,"value":2209},"Vite",{"type":27,"tag":1486,"props":2211,"children":2212},{},[2213,2231,2248,2266,2284],{"type":27,"tag":1462,"props":2214,"children":2215},{},[2216,2221,2226],{"type":27,"tag":1493,"props":2217,"children":2218},{},[2219],{"type":32,"value":2220},"开发速度",{"type":27,"tag":1493,"props":2222,"children":2223},{},[2224],{"type":32,"value":2225},"极快（Rust 编译）",{"type":27,"tag":1493,"props":2227,"children":2228},{},[2229],{"type":32,"value":2230},"极快（ESM 直连）",{"type":27,"tag":1462,"props":2232,"children":2233},{},[2234,2238,2243],{"type":27,"tag":1493,"props":2235,"children":2236},{},[2237],{"type":32,"value":1549},{"type":27,"tag":1493,"props":2239,"children":2240},{},[2241],{"type":32,"value":2242},"快（全量编译优化）",{"type":27,"tag":1493,"props":2244,"children":2245},{},[2246],{"type":32,"value":2247},"快（Rollup）",{"type":27,"tag":1462,"props":2249,"children":2250},{},[2251,2256,2261],{"type":27,"tag":1493,"props":2252,"children":2253},{},[2254],{"type":32,"value":2255},"Webpack 兼容",{"type":27,"tag":1493,"props":2257,"children":2258},{},[2259],{"type":32,"value":2260},"高",{"type":27,"tag":1493,"props":2262,"children":2263},{},[2264],{"type":32,"value":2265},"低",{"type":27,"tag":1462,"props":2267,"children":2268},{},[2269,2274,2279],{"type":27,"tag":1493,"props":2270,"children":2271},{},[2272],{"type":32,"value":2273},"插件生态",{"type":27,"tag":1493,"props":2275,"children":2276},{},[2277],{"type":32,"value":2278},"Webpack 生态",{"type":27,"tag":1493,"props":2280,"children":2281},{},[2282],{"type":32,"value":2283},"Rollup/Vite 生态",{"type":27,"tag":1462,"props":2285,"children":2286},{},[2287,2292,2297],{"type":27,"tag":1493,"props":2288,"children":2289},{},[2290],{"type":32,"value":2291},"适用项目",{"type":27,"tag":1493,"props":2293,"children":2294},{},[2295],{"type":32,"value":2296},"Webpack 迁移、大型 monorepo",{"type":27,"tag":1493,"props":2298,"children":2299},{},[2300],{"type":32,"value":2301},"新项目、中小型",{"type":27,"tag":28,"props":2303,"children":2304},{},[2305],{"type":32,"value":2306},"选择建议：",{"type":27,"tag":40,"props":2308,"children":2309},{},[2310,2315,2320],{"type":27,"tag":44,"props":2311,"children":2312},{},[2313],{"type":32,"value":2314},"新项目：优先 Vite",{"type":27,"tag":44,"props":2316,"children":2317},{},[2318],{"type":32,"value":2319},"Webpack 遗留项目：Rspack",{"type":27,"tag":44,"props":2321,"children":2322},{},[2323],{"type":32,"value":2324},"大型 monorepo + Webpack 依赖：Rspack",{"type":27,"tag":1276,"props":2326,"children":2327},{},[],{"type":27,"tag":100,"props":2329,"children":2331},{"id":2330},"_10-上线检查清单",[2332],{"type":32,"value":2333},"10. 上线检查清单",{"type":27,"tag":40,"props":2335,"children":2337},{"className":2336},[796],[2338,2347,2356,2365,2374,2383],{"type":27,"tag":44,"props":2339,"children":2341},{"className":2340},[801],[2342,2345],{"type":27,"tag":804,"props":2343,"children":2344},{"disabled":806,"type":807},[],{"type":32,"value":2346}," 本地开发环境已验证（HMR/热更新正常）",{"type":27,"tag":44,"props":2348,"children":2350},{"className":2349},[801],[2351,2354],{"type":27,"tag":804,"props":2352,"children":2353},{"disabled":806,"type":807},[],{"type":32,"value":2355}," CI 构建已切换并观测 3 天以上",{"type":27,"tag":44,"props":2357,"children":2359},{"className":2358},[801],[2360,2363],{"type":27,"tag":804,"props":2361,"children":2362},{"disabled":806,"type":807},[],{"type":32,"value":2364}," 产物体积对比无异常（baseline ± 5%）",{"type":27,"tag":44,"props":2366,"children":2368},{"className":2367},[801],[2369,2372],{"type":27,"tag":804,"props":2370,"children":2371},{"disabled":806,"type":807},[],{"type":32,"value":2373}," 关键页面功能回归测试通过",{"type":27,"tag":44,"props":2375,"children":2377},{"className":2376},[801],[2378,2381],{"type":27,"tag":804,"props":2379,"children":2380},{"disabled":806,"type":807},[],{"type":32,"value":2382}," 有构建耗时与缓存命中率监控",{"type":27,"tag":44,"props":2384,"children":2386},{"className":2385},[801],[2387,2390],{"type":27,"tag":804,"props":2388,"children":2389},{"disabled":806,"type":807},[],{"type":32,"value":2391}," 有回滚方案（保留 Webpack 配置）",{"type":27,"tag":1276,"props":2393,"children":2394},{},[],{"type":27,"tag":100,"props":2396,"children":2397},{"id":477},[2398],{"type":32,"value":477},{"type":27,"tag":28,"props":2400,"children":2401},{},[2402],{"type":32,"value":2403},"Rspack 的核心价值是：",{"type":27,"tag":40,"props":2405,"children":2406},{},[2407,2412,2417],{"type":27,"tag":44,"props":2408,"children":2409},{},[2410],{"type":32,"value":2411},"在 Webpack 生态下获得接近 Vite 的速度",{"type":27,"tag":44,"props":2413,"children":2414},{},[2415],{"type":32,"value":2416},"对大型项目构建成本与开发体验的显著改善",{"type":27,"tag":44,"props":2418,"children":2419},{},[2420],{"type":32,"value":2421},"生产级稳定性（字节跳动内部大规模验证）",{"title":7,"searchDepth":517,"depth":517,"links":2423},[2424,2425,2429,2434,2435,2440,2445,2446,2447,2452,2453,2454],{"id":1198,"depth":520,"text":1183},{"id":1281,"depth":520,"text":1284,"children":2426},[2427,2428],{"id":1292,"depth":517,"text":1295},{"id":1331,"depth":517,"text":1334},{"id":1358,"depth":520,"text":1361,"children":2430},[2431,2432,2433],{"id":1364,"depth":517,"text":1367},{"id":1388,"depth":517,"text":1391},{"id":1412,"depth":517,"text":1415},{"id":1444,"depth":520,"text":1447},{"id":1627,"depth":520,"text":1630,"children":2436},[2437,2438,2439],{"id":1633,"depth":517,"text":1636},{"id":1730,"depth":517,"text":1733},{"id":1799,"depth":517,"text":1802},{"id":1826,"depth":520,"text":1829,"children":2441},[2442,2443,2444],{"id":1832,"depth":517,"text":1835},{"id":1856,"depth":517,"text":1859},{"id":1878,"depth":517,"text":1881},{"id":1943,"depth":520,"text":1946},{"id":2014,"depth":520,"text":2017},{"id":2097,"depth":520,"text":2100,"children":2448},[2449,2450,2451],{"id":2103,"depth":517,"text":2106},{"id":2132,"depth":517,"text":2135},{"id":2156,"depth":517,"text":2159},{"id":2183,"depth":520,"text":2186},{"id":2330,"depth":520,"text":2333},{"id":477,"depth":520,"text":477},"content:topics:frontend:rspack-performance-practice.md","topics/frontend/rspack-performance-practice.md","topics/frontend/rspack-performance-practice",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":2459,"image":18,"imageQuery":19,"pexelsPhotoId":20,"pexelsUrl":21,"featured":6,"readingTime":22,"body":2460,"_type":528,"_id":529,"_source":530,"_file":531,"_stem":532,"_extension":533},[13,14,15,16,17],{"type":24,"children":2461,"toc":2852},[2462,2466,2470,2489,2493,2512,2516,2520,2531,2535,2539,2543,2547,2566,2570,2574,2589,2593,2597,2601,2616,2620,2639,2643,2647,2651,2666,2670,2685,2689,2693,2697,2701,2716,2720,2735,2739,2754,2758,2762,2781,2785,2789,2816,2820,2824,2828],{"type":27,"tag":28,"props":2463,"children":2464},{},[2465],{"type":32,"value":33},{"type":27,"tag":28,"props":2467,"children":2468},{},[2469],{"type":32,"value":38},{"type":27,"tag":40,"props":2471,"children":2472},{},[2473,2477,2481,2485],{"type":27,"tag":44,"props":2474,"children":2475},{},[2476],{"type":32,"value":48},{"type":27,"tag":44,"props":2478,"children":2479},{},[2480],{"type":32,"value":53},{"type":27,"tag":44,"props":2482,"children":2483},{},[2484],{"type":32,"value":58},{"type":27,"tag":44,"props":2486,"children":2487},{},[2488],{"type":32,"value":63},{"type":27,"tag":28,"props":2490,"children":2491},{},[2492],{"type":32,"value":68},{"type":27,"tag":28,"props":2494,"children":2495},{},[2496,2497,2501,2502,2506,2507,2511],{"type":32,"value":73},{"type":27,"tag":75,"props":2498,"children":2499},{"href":77},[2500],{"type":32,"value":80},{"type":32,"value":82},{"type":27,"tag":75,"props":2503,"children":2504},{"href":85},[2505],{"type":32,"value":88},{"type":32,"value":90},{"type":27,"tag":75,"props":2508,"children":2509},{"href":93},[2510],{"type":32,"value":96},{"type":32,"value":98},{"type":27,"tag":100,"props":2513,"children":2514},{"id":102},[2515],{"type":32,"value":105},{"type":27,"tag":28,"props":2517,"children":2518},{},[2519],{"type":32,"value":110},{"type":27,"tag":40,"props":2521,"children":2522},{},[2523,2527],{"type":27,"tag":44,"props":2524,"children":2525},{},[2526],{"type":32,"value":118},{"type":27,"tag":44,"props":2528,"children":2529},{},[2530],{"type":32,"value":123},{"type":27,"tag":28,"props":2532,"children":2533},{},[2534],{"type":32,"value":128},{"type":27,"tag":28,"props":2536,"children":2537},{},[2538],{"type":32,"value":133},{"type":27,"tag":100,"props":2540,"children":2541},{"id":136},[2542],{"type":32,"value":139},{"type":27,"tag":28,"props":2544,"children":2545},{},[2546],{"type":32,"value":144},{"type":27,"tag":40,"props":2548,"children":2549},{},[2550,2554,2558,2562],{"type":27,"tag":44,"props":2551,"children":2552},{},[2553],{"type":32,"value":152},{"type":27,"tag":44,"props":2555,"children":2556},{},[2557],{"type":32,"value":157},{"type":27,"tag":44,"props":2559,"children":2560},{},[2561],{"type":32,"value":162},{"type":27,"tag":44,"props":2563,"children":2564},{},[2565],{"type":32,"value":167},{"type":27,"tag":28,"props":2567,"children":2568},{},[2569],{"type":32,"value":172},{"type":27,"tag":28,"props":2571,"children":2572},{},[2573],{"type":32,"value":177},{"type":27,"tag":40,"props":2575,"children":2576},{},[2577,2581,2585],{"type":27,"tag":44,"props":2578,"children":2579},{},[2580],{"type":32,"value":185},{"type":27,"tag":44,"props":2582,"children":2583},{},[2584],{"type":32,"value":190},{"type":27,"tag":44,"props":2586,"children":2587},{},[2588],{"type":32,"value":195},{"type":27,"tag":28,"props":2590,"children":2591},{},[2592],{"type":32,"value":200},{"type":27,"tag":100,"props":2594,"children":2595},{"id":203},[2596],{"type":32,"value":206},{"type":27,"tag":28,"props":2598,"children":2599},{},[2600],{"type":32,"value":211},{"type":27,"tag":40,"props":2602,"children":2603},{},[2604,2608,2612],{"type":27,"tag":44,"props":2605,"children":2606},{},[2607],{"type":32,"value":219},{"type":27,"tag":44,"props":2609,"children":2610},{},[2611],{"type":32,"value":224},{"type":27,"tag":44,"props":2613,"children":2614},{},[2615],{"type":32,"value":229},{"type":27,"tag":28,"props":2617,"children":2618},{},[2619],{"type":32,"value":234},{"type":27,"tag":40,"props":2621,"children":2622},{},[2623,2627,2631,2635],{"type":27,"tag":44,"props":2624,"children":2625},{},[2626],{"type":32,"value":242},{"type":27,"tag":44,"props":2628,"children":2629},{},[2630],{"type":32,"value":247},{"type":27,"tag":44,"props":2632,"children":2633},{},[2634],{"type":32,"value":252},{"type":27,"tag":44,"props":2636,"children":2637},{},[2638],{"type":32,"value":257},{"type":27,"tag":28,"props":2640,"children":2641},{},[2642],{"type":32,"value":262},{"type":27,"tag":100,"props":2644,"children":2645},{"id":265},[2646],{"type":32,"value":265},{"type":27,"tag":28,"props":2648,"children":2649},{},[2650],{"type":32,"value":272},{"type":27,"tag":40,"props":2652,"children":2653},{},[2654,2658,2662],{"type":27,"tag":44,"props":2655,"children":2656},{},[2657],{"type":32,"value":280},{"type":27,"tag":44,"props":2659,"children":2660},{},[2661],{"type":32,"value":285},{"type":27,"tag":44,"props":2663,"children":2664},{},[2665],{"type":32,"value":290},{"type":27,"tag":28,"props":2667,"children":2668},{},[2669],{"type":32,"value":295},{"type":27,"tag":40,"props":2671,"children":2672},{},[2673,2677,2681],{"type":27,"tag":44,"props":2674,"children":2675},{},[2676],{"type":32,"value":303},{"type":27,"tag":44,"props":2678,"children":2679},{},[2680],{"type":32,"value":308},{"type":27,"tag":44,"props":2682,"children":2683},{},[2684],{"type":32,"value":313},{"type":27,"tag":28,"props":2686,"children":2687},{},[2688],{"type":32,"value":318},{"type":27,"tag":100,"props":2690,"children":2691},{"id":321},[2692],{"type":32,"value":324},{"type":27,"tag":28,"props":2694,"children":2695},{},[2696],{"type":32,"value":329},{"type":27,"tag":28,"props":2698,"children":2699},{},[2700],{"type":32,"value":334},{"type":27,"tag":40,"props":2702,"children":2703},{},[2704,2708,2712],{"type":27,"tag":44,"props":2705,"children":2706},{},[2707],{"type":32,"value":342},{"type":27,"tag":44,"props":2709,"children":2710},{},[2711],{"type":32,"value":347},{"type":27,"tag":44,"props":2713,"children":2714},{},[2715],{"type":32,"value":352},{"type":27,"tag":28,"props":2717,"children":2718},{},[2719],{"type":32,"value":357},{"type":27,"tag":40,"props":2721,"children":2722},{},[2723,2727,2731],{"type":27,"tag":44,"props":2724,"children":2725},{},[2726],{"type":32,"value":365},{"type":27,"tag":44,"props":2728,"children":2729},{},[2730],{"type":32,"value":370},{"type":27,"tag":44,"props":2732,"children":2733},{},[2734],{"type":32,"value":375},{"type":27,"tag":28,"props":2736,"children":2737},{},[2738],{"type":32,"value":380},{"type":27,"tag":40,"props":2740,"children":2741},{},[2742,2746,2750],{"type":27,"tag":44,"props":2743,"children":2744},{},[2745],{"type":32,"value":388},{"type":27,"tag":44,"props":2747,"children":2748},{},[2749],{"type":32,"value":393},{"type":27,"tag":44,"props":2751,"children":2752},{},[2753],{"type":32,"value":398},{"type":27,"tag":100,"props":2755,"children":2756},{"id":401},[2757],{"type":32,"value":401},{"type":27,"tag":28,"props":2759,"children":2760},{},[2761],{"type":32,"value":408},{"type":27,"tag":40,"props":2763,"children":2764},{},[2765,2769,2773,2777],{"type":27,"tag":44,"props":2766,"children":2767},{},[2768],{"type":32,"value":416},{"type":27,"tag":44,"props":2770,"children":2771},{},[2772],{"type":32,"value":421},{"type":27,"tag":44,"props":2774,"children":2775},{},[2776],{"type":32,"value":426},{"type":27,"tag":44,"props":2778,"children":2779},{},[2780],{"type":32,"value":431},{"type":27,"tag":28,"props":2782,"children":2783},{},[2784],{"type":32,"value":436},{"type":27,"tag":100,"props":2786,"children":2787},{"id":439},[2788],{"type":32,"value":439},{"type":27,"tag":40,"props":2790,"children":2791},{},[2792,2796,2800,2804,2808,2812],{"type":27,"tag":44,"props":2793,"children":2794},{},[2795],{"type":32,"value":449},{"type":27,"tag":44,"props":2797,"children":2798},{},[2799],{"type":32,"value":454},{"type":27,"tag":44,"props":2801,"children":2802},{},[2803],{"type":32,"value":459},{"type":27,"tag":44,"props":2805,"children":2806},{},[2807],{"type":32,"value":464},{"type":27,"tag":44,"props":2809,"children":2810},{},[2811],{"type":32,"value":469},{"type":27,"tag":44,"props":2813,"children":2814},{},[2815],{"type":32,"value":474},{"type":27,"tag":100,"props":2817,"children":2818},{"id":477},[2819],{"type":32,"value":477},{"type":27,"tag":28,"props":2821,"children":2822},{},[2823],{"type":32,"value":484},{"type":27,"tag":28,"props":2825,"children":2826},{},[2827],{"type":32,"value":489},{"type":27,"tag":40,"props":2829,"children":2830},{},[2831,2838,2845],{"type":27,"tag":44,"props":2832,"children":2833},{},[2834],{"type":27,"tag":75,"props":2835,"children":2836},{"href":77},[2837],{"type":32,"value":80},{"type":27,"tag":44,"props":2839,"children":2840},{},[2841],{"type":27,"tag":75,"props":2842,"children":2843},{"href":93},[2844],{"type":32,"value":96},{"type":27,"tag":44,"props":2846,"children":2847},{},[2848],{"type":27,"tag":75,"props":2849,"children":2850},{"href":512},[2851],{"type":32,"value":515},{"title":7,"searchDepth":517,"depth":517,"links":2853},[2854,2855,2856,2857,2858,2859,2860,2861],{"id":102,"depth":520,"text":105},{"id":136,"depth":520,"text":139},{"id":203,"depth":520,"text":206},{"id":265,"depth":520,"text":265},{"id":321,"depth":520,"text":324},{"id":401,"depth":520,"text":401},{"id":439,"depth":520,"text":439},{"id":477,"depth":520,"text":477},1776916085463]