知蛛网
  • 首页
  • 会员
  • 活动
  • 工作台

常见问题
活动
关于我们
联系我们
隐私协议
用户协议
会员协议
© 2026 知蛛网. 保留所有权利。
首页会员工作台我的
flynn@flynn
主页wiki简历作品集
目录
全部书籍
00-路线
  • 学习路线
  • 命名与写作规范
01-计算机基础
01-计算机网络
  • 互联网是如何工作的
  • HTTP协议
  • TCP/IP协议
  • 浏览器直接打开本地html文件,请求时的协议问题
02-浏览器原理
  • 浏览器是如何渲染页面的
  • 浏览器是如何渲染页面的
  • 面试之浏览器
03-操作系统
  • 进程与线程
  • 内存管理与虚拟内存
  • IO 模型与多路复用
  • 文件系统与页缓存
04-数据结构与算法
  • 数组与链表
  • 栈与队列
  • 哈希表
  • 树与堆
  • 基础数据结构
01-基础数据结构
02-高级算法
  • 排序算法
  • 二分查找
  • 递归与回溯
  • 动态规划
  • 双指针与滑动窗口
03-leetcode刷题
02-前端核心
01-web开发
  • Web 和 Web 标准
  • web 入门
  • web 开发
  • URL
  • 域名
  • Web服务器
  • 命令行
  • 工作流程和流程
  • 超链接
  • 浏览器指纹
02-html
  • HTML基础语法
  • HTML 概述
  • HTML 发展史
  • HTML调试
  • HTML标题与段落
  • 文本格式化
  • 强调与重要性
  • 块级元素和内联元素
  • 列表
  • 区块
  • 语义元素
  • 页面结构化和语义化
  • 超链接
  • 相对路径和绝对路径
  • 图片
  • 表格
  • 表单和按钮
  • 多媒体
  • 视频/音频
  • HTML 头部
  • HTML 字符集
  • HTML颜色
  • HTML 语言代码
  • HTML 国家/地区
  • Emoji (表情符号)
  • HTML 标签简写及全称 |
  • SVG
  • Canvas 2D
  • Canvas 3D
  • 框架 `<iframe>`
  • HTML 拖放
  • HTML5 Geolocation(地理定位)
  • Web 存储
  • HTML URL 编码
  • MathML
  • 远程图片资源在自己网站中无法展示问题
03-css
  • CSS简介
  • CSS 语法
  • CSS 创建
  • CSS 发展史
  • CSS 浏览器支持
  • CSS 选择器
  • CSS `!important` 规则
  • css颜色
  • CSS 文本格式
  • CSS 盒子模型
  • CSS 尺寸
  • CSS 内边距
  • CSS 外边距
  • CSS 边框
  • CSS 轮廓
  • CSS 背景(background)
  • CSS 溢出
  • CSS 文档流
  • CSS 显示和可见性
  • CSS 浮动
  • CSS 定位
  • CSS 对齐方式
  • CSS 网页布局
  • CSS 多列布局(CSS Multi-column Layout)
  • CSS 透明度
  • CSS 响应式设计(Responsive Design)
  • CSS 媒体查询
  • CSS 列表
  • CSS 表格
  • CSS 表单
  • CSS 链接
  • CSS 用户界面
  • CSS 计数器
  • CSS 过渡
  • CSS 动画
  • CSS 2D 转换
  • CSS 3D 转换
  • CSS 变量(CSS Custom Properties)
  • CSS 原生嵌套(CSS Nesting)
  • CSS 函数(CSS Functions)
04-javascript
  • 什么是 JavaScript?
  • 编程范式(Programming Paradigm)
  • 什么是范式?
  • ECMAScript 规范
  • 什么是语法糖
  • 开发环境搭建
  • 什么是堆和栈?
  • 什么是执行上下文
  • JavaScript 垃圾回收机制
  • 作业队列与事件循环
  • 深拷贝和浅拷贝
  • 语法与类型
  • 字面量
  • 控制流与错误处理
  • 循环与迭代
  • 函数
  • 表达式与运算符
  • 数字和字符串
  • 表达日期与时间
  • 正则表达式
  • 索引集合类
  • 带键的集合
  • 对象
  • 类
  • Promise
  • async/await
  • 迭代器和生成器
  • 国际化
  • 模块
  • 资源管理
  • 属性的可枚举性和所有权
  • 闭包
  • 继承与原型链
  • 元编程
  • 内存管理
  • 内置对象
  • arguments 对象
  • BOM 对象(浏览器对象模型)
  • DOM 对象(文档对象模型)
  • bind、apply、call的区别
  • new 操作符
  • typeof 和 instanceof 的区别
  • HTML5 Web Workers
05-typescript
  • TypeScript 类型系统基础
  • 类型体操
03-框架与跨端
01-react
  • 开发环境搭建
  • JSX
  • 组件
  • 生命周期
  • Hooks
  • 组件通信
  • 状态管理
  • React 19 新特性
  • useCallback 闭包陷阱
  • 常用的性能优化操作
  • Firbe 架构
  • React 18 新特性
  • useRef
  • 基于umijs 4.0 搭建官网
  • react+vite本地开发,如何手机联调
  • React 实现谷歌登录
  • React 项目调起 WhatsApp
02-vue
  • vue 解决跨域请求
  • 在vue2使用TinyMCE富文本编辑器
  • 使用jszip 导出新闻
  • Vue 本地开发启用 https
  • 基于vue3+vite+ts+elementplus+pinia+axios搭建后台管理系统
03-react-native
  • iOS 开发环境(RN 0.72)
  • RN 原生模块(Native Module)
  • 查看Maven包的Java包名
  • 优化 APP 启动速度
  • 安全键盘
  • 启动图与 Icon 尺寸规范
  • RN如何生成/配置iOS的开发者证书和生产证书
  • 邓白氏编码
  • 微信开放平台配置Universal Link
  • 上架至Apple App Store
04-android
  • 开发环境搭建
  • Android项目目录结构
  • 认识Gradle
04-工程化
01-git
  • 如何解决已被git跟踪文件不在跟踪
  • git标签
  • Git报错: Failed to connect to github.com port 443 解决方案
  • Git 分支操作速查
02-构建工具
  • 构建工具原理与选型
02-webpack
  • webpack 核心概念与构建流程
  • webpack 性能优化
03-vite
  • vite 为什么快
  • vite 插件与生产构建
03-测试
  • 前端测试体系
04-部署
  • Nginx 反向代理解决跨域
  • SPA 刷新非首页报 404
05-docker
  • Docker 常用命令
  • docker-compose nginx配置ssl证书
  • Docker Desktop 升级后 docker-compose 命令找不到
06-性能优化
  • 前端性能优化体系
  • 背景 GIF 优化方案
07-微前端
  • 微前端实战(qiankun)
  • 微前端 · qiankun
01-qiankun
05-后端与数据
01-nodejs
  • Node 版本与依赖的 engines 冲突
  • Express 实现 Gmail 发信(邮箱验证码)
02-php
  • 浏览器保存新闻,发布到自有网站
  • [分布式] 浏览器保存新闻,发布到自有网站
  • 邮件发送,多账号轮询
  • nginx和php-fpm通信问题导致网站页面空白
03-python
  • macOS M1 芯片 如何安装 py 和 tkinter
  • tkinter 编写的程序如何打包成桌面软件
04-架构设计
  • 后台管理系统中角色管理、管理员管理、权限设置他们三者之间的关系
05-运维
  • redis启动失败
  • 实现自动备份宝塔项目及数据库到本地
  • 宝塔面板
01-宝塔
06-实战项目
  • 实战准备工作
02-项目记录
  • AI-Chat 模块技术文档
  • CRMChat 部署
07-面试专项
01-面试
  • 面试之自我介绍
  • CSS 面试
  • JS面试
  • React面试
  • Vue面试
  • RN 面试 · 题目清单
  • RN 面试 · 答案详解
  • RN 物流公司 · 题目清单
  • RN 物流公司 · 答案详解
  • Uniapp 面试
  • 带团队经验
12-react专项
  • 一个表格,某一行的某一列数据变动了,如何优化性能?
13-reactnative专项
  • RN 开发过程中,有遇到什么棘手的问题?你是如何解决的?
14-过往面试总结
  • 冷哥传媒 · 面试题
  • 沐腾科技 · 面试题
  • 字符频率排序
02-面试八股
  • 网络八股
  • 浏览器八股
  • 工程化八股
03-算法面试题
  • 前端高频手写题
  • 场景设计题
04-真实面试经历
  • 20251027 盾蓝科技 面试
  • 20251028 芝麻甜心 面试
08-工具
01-n8n
  • 初始n8n
  • 快速入门
  • 在宝塔中搭建n8n环境
  • n8n中常用节点
  • n8n和代码的区别
02-Trae
  • Figma MCP 配置指南
03-UI_UX_pro_max
  • UI_UX_pro_max的使用
04-开发环境
  • VMWare虚拟机安装
  • PowerShell 执行策略与编码设置
98-杂项
  • A股股票交易相关费用
99-手册
  • iOS 开发者账号申请流程及费用
  • 邓白氏编码申请及费用
  • App 推送通道申请及费用
  • App 开发收费项目清单
  • 注册AWS账号
  • 使用Amazon Polly实现文本转语音
  • Google 翻译 Key 申请与前端调用
  • 使用SmsForwarder转发短信

工程化八股

02-面试八股2026/11/14

工程化题的分水岭在于能否说清"这个配置解决了什么真实问题"。这份清单把每个考点压成结论、机制和踩坑后果三段。

面试怎么答

工程化没有标准答案,只有取舍。回答时按四步走:

步骤说法示例
定位问题先说它在解决什么痛点浏览器不认识 TS/JSX
给出机制说清工具在哪个阶段做了什么编译期转译,不是运行时
说明代价主动提成本和副作用构建变慢、sourcemap 变大
给出判据什么场景选哪个大型老项目 vs 新项目

只报配置名不报版本约束、只讲优点不讲代价,是这一块最常见的失分方式。

一、构建工具为什么需要

一句话:浏览器只认有限的 HTML/CSS/JS,构建工具负责把开发态的代码翻译成可部署、可缓存、体积合理的产物。

职责具体问题
模块化浏览器原生 ESM 之外还有 CJS、CSS @import、图片引用
语法兼容TS、JSX、新语法要按 browserslist 降级
资源处理CSS 预处理、图片压缩、字体、静态资源指纹
产物优化压缩、tree shaking、代码分割、chunk 拆分、hash
开发体验HMR、sourcemap、代理、环境变量注入

webpack 与 vite 的模型差异

维度webpackvite
开发态先打包出 bundle 再起服务原生 ESM 按需编译,依赖用 esbuild 预构建
启动速度随项目规模线性增长近乎常数,只编译当前请求的模块
热更新重新构建受影响 chunk精确到模块,边界清晰时只失效该模块
生产构建自身完成交给 Rollup
代价配置复杂、冷启动慢首屏请求数多、CJS 依赖需预构建、生态插件不如 webpack 全

追问:vite 生产为什么不用原生 ESM——请求数太多、没有 tree shaking 与 chunk 拆分,HTTP/2 也扛不住深层依赖瀑布。

二、Tree shaking

一句话:靠 ESM 的静态结构,在打包时删掉没有被引用的导出。

三个前提

  1. 代码是 ESM:import/export 在顶层,模块路径是字面量,能被静态分析。CJS 的 require 可写在条件里,做不到。
  2. 模块无副作用,或已被正确标注:package.json 的 sideEffects 字段让打包器知道哪些文件不能删。
  3. 生产模式且开启压缩:webpack 标记 usedExports,最终由 Terser/esbuild 删除死代码;开发模式为了调试一般不删。
上一篇浏览器八股
下一篇已经是最后一篇
本页目录
面试怎么答一、构建工具为什么需要二、Tree shaking三、CommonJS 与 ESM四、包管理与依赖五、前端监控六、灰度与发布七、规范与协作关联阅读

sideEffects 写错的后果

  • 写成 false:打包器认为所有文件都无副作用,import './polyfill'、import './global.css'、注册自定义元素的模块会被整段删掉,运行时报 xxx is not defined。
  • 正确写法是数组精确声明:"sideEffects": ["*.css", "./src/polyfill.ts"],其余文件按无副作用处理。
  • 另一个隐形坑:库把 module 指向 ESM、main 指向 CJS,打包器优先 module 才能摇;只提供 CJS 时只能靠 usedExports 做有限删除。

追问:为什么 import { a } from './utils' 有时整包都进不来——utils 里有顶层副作用,或 babel 把 ESM 转成了 CJS,导致静态分析失效。

三、CommonJS 与 ESM

一句话:CJS 是运行时同步加载、值拷贝;ESM 是编译时静态解析、实时绑定。

维度CommonJSESM
加载时机运行时,require 执行到才加载编译时解析依赖图,再执行
静态分析难,路径可动态拼接易,支持 tree shaking
导出本质module.exports 对象的属性,值拷贝实时绑定(live binding),只读
顶层 thismodule.exportsundefined
循环依赖返回未完成的 exports,可能拿到 undefined提升声明可用,但访问未初始化变量会命中 TDZ
异步能力无支持 import() 与 top-level await

循环依赖的差异要能举例

// a.js
exports.done = false;
const b = require('./b');   // b 此时拿到的是 { done: false }
exports.done = true;

// b.js
const a = require('./a');   // 拿到 a 的半成品 exports
console.log(a.done);        // false

ESM 下 b 看到的是 live binding,值会随 a 的执行更新,但若在初始化前读取仍会报 "Cannot access before initialization"。

追问:为什么打包后 this 变了——Babel 把 ESM 转 CJS 时会给顶层 this 补 void 0,行为是对齐规范的。

四、包管理与依赖

一句话:版本号决定"能升到哪",lock 文件决定"这次装到哪",peerDependencies 决定"和谁共用一份"。

  • ^1.2.3:允许 >=1.2.3 <2.0.0,锁 major。
  • ~1.2.3:允许 >=1.2.3 <1.3.0,锁 minor。
  • 精确版本 1.2.3:依赖方最省心,库作者最常被抱怨。

lock 文件的作用:记录完整依赖树、解析地址与 integrity 校验值,保证不同机器、不同时间装出同一棵树;CI 用 npm ci 严格按 lock 安装,npm install 则可能更新 lock。

peerDependencies 解决什么

插件(如 eslint-plugin-react、react-dom)声明"我需要宿主项目的 React 17–19"。包管理器据此提示版本不匹配,并在 pnpm/npm 7+ 中避免装第二份 React——两份 React 会导致 hooks 报 "Invalid hook call"、Context 读不到。

幽灵依赖

代码里 import _ from 'lodash',但 package.json 里没写,只是恰好被别的包依赖并被 npm/yarn 扁平化提升到顶层 node_modules。换包管理器、上游删依赖、版本变化都会突然报错。pnpm 用"只暴露声明过的依赖"的 node_modules 结构从根上消除,代价是要处理一些老库的软链接兼容问题。

五、前端监控

一句话:错误、性能、行为三条线采集,采样上报,再用 sourcemap 把压缩后的堆栈还原。

错误捕获

类型方式注意
运行时错误window.onerror 或 addEventListener('error')能拿到 message/source/line/col/error
Promise 未捕获unhandledrejection拿到 reason,建议序列化兜底
资源加载失败addEventListener('error', fn, true)资源错误不冒泡,必须捕获阶段
框架内Vue errorHandler、React ErrorBoundaryErrorBoundary 只捕渲染期,不捕事件与异步
接口异常请求库拦截器区分业务码与 HTTP 码

资源错误必须用捕获阶段:error 事件在资源元素上触发且不冒泡,冒泡阶段监听不到;回调里 event.target 是元素本身,需要判断 tagName 再取 src/href。

跨域脚本报 "Script error." 时,需要 <script crossorigin="anonymous"> 且 CDN 返回 Access-Control-Allow-Origin。

性能上报:PerformanceObserver 订阅 paint、largest-contentful-paint、layout-shift、longtask,导航数据取 performance.getEntriesByType('navigation');上报用 navigator.sendBeacon,避免阻塞卸载。

sourcemap 还原:构建产出 .map,上传到监控平台而不公开发布,平台用 source-map 库按 stack 里的行列号反查原始文件、函数名与源码片段;hidden-source-map 只生成不写 sourceMappingURL。

追问:监控 SDK 自己报错怎么办——加开关与 try/catch 包裹,限制单页上报条数,避免死循环。

六、灰度与发布

一句话:资源用内容 hash 长缓存,入口 HTML 不缓存,回滚就是切回上一份入口。

  • 静态资源:app.[contenthash].js + Cache-Control: public, max-age=31536000, immutable,内容变则文件名变,天然失效。
  • 入口 HTML:Cache-Control: no-cache(可缓存但每次校验)或极短 max-age,保证拿到最新的资源引用。
  • 发版顺序:先传静态资源,再更新 HTML,避免用户拿到引用了不存在文件的 HTML。
  • 灰度:按用户 ID 哈希、地域、设备分流;CDN/边缘计算按 Cookie 返回不同 HTML,或服务端渲染时注入不同资源地址。
  • 回滚:保留历史版本目录与 HTML 快照,切 nginx 指向或回退 HTML,再刷新 CDN;因为资源文件名带 hash,旧 HTML 一定还能找到旧资源。
  • 数据库与接口要向前兼容,前端回滚才不会因字段缺失而崩。

追问:为什么不能只刷新 CDN 缓存——用户浏览器里可能还存着旧 HTML,只能靠短缓存加版本对比。

七、规范与协作

一句话:ESLint 管"对不对",Prettier 管"好不好看",git hooks 把检查卡在提交前。

工具职责边界
ESLint潜在 bug、未使用变量、hooks 依赖、导入顺序不负责换行缩进的美观
Prettier统一格式化,不做语义判断不理解业务规则
eslint-config-prettier关掉与 Prettier 冲突的格式规则必须放在 extends 末尾
  • husky 挂 pre-commit,配合 lint-staged 只处理暂存文件,避免全量检查拖慢提交。
  • commit-msg 用 commitlint 校验 Conventional Commits:type(scope): subject,便于生成 changelog 与语义化版本。
  • CI 再跑一次全量 lint + 类型检查,防止 --no-verify 绕过本地钩子。
  • 编辑器统一 .editorconfig 与 .vscode/settings.json,减少无意义 diff。

关联阅读

  • 构建工具原理与选型
  • HTTP 协议
  • 面试专项总览