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