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