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