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