前端工程化面试题
前端面试题 - 工程化篇
工程化是前端开发的核心竞争力之一,掌握构建工具、代码规范、CI/CD等工程化知识,是高级工程师的必备技能。
📊 文档概览
| 项目 | 数据 |
|---|---|
| 题目总数 | 120 道 |
| 基础题 | 48 道 (40%) ⭐ |
| 中级题 | 54 道 (45%) ⭐⭐ |
| 高级题 | 18 道 (15%) ⭐⭐⭐ |
| 覆盖范围 | 11 个核心领域 |
难度说明
- ⭐ 基础:必会知识点,面试高频出现
- ⭐⭐ 中级:进阶知识,体现专业深度
- ⭐⭐⭐ 高级:架构层面,展现技术广度
📑 目录
一、构建工具
1.1 Webpack
1. Webpack的核心原理是什么?
难度:⭐
标签:#Webpack #核心原理 #构建工具
问题描述:
请解释Webpack是如何工作的,它的核心机制包括哪些?
参考答案要点:
- 模块化依赖分析:从入口文件递归构建依赖图,识别所有模块的依赖关系
- Loader处理:通过Loader链式处理非JS资源(如CSS、图片)
- 插件系统:基于Tapable的插件架构,在编译生命周期(compile、emit等)注入扩展逻辑
- Chunk生成:根据代码分割规则生成多个Bundle,支持按需加载
2. Loader与Plugin的区别是什么?
难度:⭐
标签:#Webpack #Loader #Plugin
问题描述:
Webpack中的Loader和Plugin有什么区别?分别在什么场景下使用?
参考答案要点:
- Loader:文件加载器,处理单个文件(如转译SCSS为CSS),链式调用
- Plugin:扩展Webpack功能,作用于整个构建流程(如生成HTML文件、提取CSS)
- Loader在
module.rules中配置,Plugin在plugins数组中配置
代码示例:
// webpack.config.js
module.exports = {
module: {
rules: [
// Loader配置
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
],
},
plugins: [
// Plugin配置
new HtmlWebpackPlugin({ template: "./index.html" }),
],
}3. Webpack的构建流程是怎样的?
难度:⭐⭐
标签:#Webpack #构建流程
问题描述:
请描述Webpack从入口到输出的完整构建流程。
参考答案要点:
- 初始化:读取配置文件,初始化Compiler对象
- 编译:从入口文件开始,递归解析依赖,生成依赖图
- 构建:根据依赖图,调用loader处理模块,生成chunk
- 输出:将chunk写入文件系统,生成最终的bundle文件
4. 如何提高Webpack的打包速度?
难度:⭐⭐
标签:#Webpack #性能优化 #构建速度
问题描述:
项目构建速度变慢时,有哪些优化Webpack打包速度的方法?
参考答案要点:
- 缓存:使用
cache-loader或Webpack 5的persistent caching - 多线程:使用
thread-loader或HappyPack开启多进程编译 - 减少构建范围:配置
exclude和include,使用resolve.alias - DLL预构建:使用
DllPlugin预编译不常变化的依赖 - 使用esbuild-loader:替换Babel-loader提升转译速度
代码示例:
// webpack.config.js - Webpack 5 持久化缓存
module.exports = {
cache: {
type: "filesystem",
buildDependencies: {
config: [__filename],
},
},
}5. 如何减少Webpack打包体积?
难度:⭐⭐
标签:#Webpack #体积优化 #TreeShaking
问题描述:
如何优化Webpack打包后的文件体积?
参考答案要点:
- Tree Shaking:移除未使用的ES Module导出
- Code Splitting:使用
SplitChunksPlugin分离公共代码 - 资源压缩:
TerserPlugin压缩JS,CssMinimizerPlugin压缩CSS - 按需引入:避免全量导入第三方库(如lodash)
- externals:排除CDN加载的库
6. Webpack5有哪些重要更新?
难度:⭐⭐
标签:#Webpack #Webpack5 #新特性
问题描述:
Webpack 5相比Webpack 4有哪些重要的更新和改进?
参考答案要点:
- 持久化缓存:
cache: { type: 'filesystem' }显著提升构建速度 - 模块联邦(Module Federation):实现微前端架构,跨应用共享模块
- 资源处理优化:内置Asset Modules(替代file-loader/url-loader)
- Tree Shaking增强:支持嵌套模块的未使用代码消除
7. chunkhash和contenthash有什么区别?
难度:⭐⭐
标签:#Webpack #缓存 #Hash
问题描述:
Webpack中的chunkhash和contenthash有什么区别?如何选择?
参考答案要点:
- chunkhash:基于chunk内容生成,同一chunk内所有文件共享相同hash
- contenthash:基于文件内容生成,文件内容不变则hash不变,适用于独立缓存CSS文件
代码示例:
// webpack.config.js
module.exports = {
output: {
filename: "[name].[contenthash:8].js",
chunkFilename: "[name].[chunkhash:8].js",
},
}8. 什么是Source Map?如何配置?
难度:⭐
标签:#Webpack #SourceMap #调试
问题描述:
什么是Source Map?在Webpack中如何配置?
参考答案要点:
- Source Map是压缩/打包后代码和源代码的映射表
- Webpack通过
devtool配置生成:开发用eval-source-map,生产用source-map或hidden-source-map - 作用:方便调试和追踪错误到源代码位置
代码示例:
// webpack.config.js
module.exports = {
// 开发环境
devtool: "eval-source-map",
// 生产环境
devtool: "hidden-source-map",
}9. Webpack热更新(HMR)原理是什么?
难度:⭐⭐⭐
标签:#Webpack #HMR #热更新
问题描述:
请解释Webpack热更新(HMR)的工作原理。
参考答案要点:
- 通过WebSocket建立开发服务器与浏览器的连接
- 文件变化时,Webpack重新编译变更模块
- 通过HMR Runtime将更新模块推送到浏览器
- 浏览器替换旧模块,不刷新页面保持应用状态
10. 如何优化Webpack的模块解析速度?
难度:⭐⭐
标签:#Webpack #性能优化 #模块解析
问题描述:
如何优化Webpack的模块解析速度?
参考答案要点:
- 配置
resolve.extensions指定扩展名顺序,减少查找次数 - 使用
resolve.alias创建模块别名,缩短路径解析 - 配置
module.noParse跳过编译已知库(如jQuery) - 限制
resolve.modules的搜索范围
代码示例:
// webpack.config.js
module.exports = {
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx"],
alias: {
"@": path.resolve(__dirname, "src"),
"@components": path.resolve(__dirname, "src/components"),
},
modules: [path.resolve(__dirname, "node_modules")],
},
module: {
noParse: /jquery|lodash/,
},
}1.2 Vite
11. Vite和Webpack的核心区别是什么?
难度:⭐
标签:#Vite #Webpack #构建工具对比
问题描述:
Vite和Webpack有哪些核心区别?
参考答案要点:
- 构建方式:Webpack先打包所有模块;Vite开发模式下基于ES Module按需加载
- 启动速度:Webpack随项目增大变慢;Vite启动速度极快,与项目大小无关
- 热更新:Webpack需重新构建chunk;Vite只编译修改的文件,毫秒级更新
- 生产构建:Webpack自研打包;Vite使用Rollup
12. Vite为什么这么快?
难度:⭐⭐
标签:#Vite #性能 #esbuild
问题描述:
Vite的启动速度和热更新速度为什么比Webpack快很多?
参考答案要点:
- 基于原生ES Module,开发环境无需打包
- 使用esbuild(Go语言编写)进行依赖预构建,比JS解析快10-100倍
- 按需编译,只处理浏览器请求的模块
- 利用浏览器原生模块加载能力
13. Vite如何处理CommonJS模块?
难度:⭐⭐
标签:#Vite #CommonJS #ESM
问题描述:
Vite原生支持ES Module,那它是如何处理CommonJS模块的?
参考答案要点:
- 开发模式:使用esbuild把CommonJS转成ESM
- 生产模式:使用Rollup + @rollup/plugin-commonjs打包
- 依赖预构建时将CJS模块转换为ESM格式
14. Vite的插件机制是怎样的?
难度:⭐⭐
标签:#Vite #插件 #Rollup
问题描述:
Vite的插件机制是如何设计的?与Webpack插件有什么区别?
参考答案要点:
- 基于Rollup插件系统扩展
- 支持Rollup插件,同时提供Vite特有钩子(如configureServer、transformIndexHtml)
- 插件可以拦截请求、修改模块、注入环境变量
15. Vite生产构建为什么使用Rollup?
难度:⭐⭐⭐
标签:#Vite #Rollup #生产构建
问题描述:
为什么Vite在生产构建时选择Rollup而不是esbuild?
参考答案要点:
- Rollup更适合库打包,Tree Shaking更彻底
- 生成更高效的代码,打包体积更小
- 支持代码分割和高级优化
- esbuild虽然快,但针对应用级打包优化不如Rollup成熟
1.3 其他构建工具
16. Rollup和Webpack有什么区别?
难度:⭐⭐
标签:#Rollup #Webpack #构建工具对比
问题描述:
Rollup和Webpack各有什么特点?分别适合什么场景?
参考答案要点:
- Rollup:专注于库的打包,输出更简洁的代码,Tree Shaking更彻底,默认生成ESM格式
- Webpack:适合应用级打包,支持代码分割、动态导入、复杂资源处理,插件生态更丰富
17. esbuild的特点和适用场景是什么?
难度:⭐⭐
标签:#esbuild #构建工具 #性能
问题描述:
esbuild有什么特点?适合什么场景使用?
参考答案要点:
- 特点:Go语言编写,构建速度极快(比Webpack快10-100倍)
- 适用场景:依赖预构建、开发环境快速转译、简单项目打包
- 局限性:插件生态简单,一些高级特性需要第三方支持
18. Turbopack是什么?有什么优势?
难度:⭐⭐
标签:#Turbopack #Next.js #Rust
问题描述:
Turbopack是什么?相比Webpack有什么优势?
参考答案要点:
- Webpack作者用Rust开发的高性能打包工具
- 目标:提供更快的增量构建时间和更小的输出文件
- 与Webpack兼容性好,是Webpack的后继者
- 适用于使用Vercel部署的项目
19. Rspack是什么?与Webpack有什么关系?
难度:⭐⭐
标签:#Rspack #字节跳动 #Rust
问题描述:
Rspack是什么?它与Webpack有什么关系?
参考答案要点:
- 字节跳动开发的JavaScript打包工具
- 用Rust重写,兼容Webpack生态系统
- 构建速度比Webpack快,尤其在大型项目中表现更好
- 易于从Webpack迁移
20. 如何选择构建工具?
难度:⭐⭐⭐
标签:#构建工具 #技术选型
问题描述:
在实际项目中,如何选择合适的构建工具?
参考答案要点:
- Webpack:复杂应用、需要高度定制、兼容旧浏览器
- Vite:现代前端项目、追求开发体验、中小型项目
- Rollup:构建JavaScript库、组件库
- Rspack/Turbopack:需要极致构建性能的大型项目
对比表格:
| 工具 | 开发启动 | 生产构建 | 适用场景 |
|---|---|---|---|
| Webpack | 慢 | 慢 | 复杂项目、高度定制 |
| Vite | 极快 | 快 | 现代项目、快速开发 |
| Rollup | - | 快 | 库打包 |
| Rspack | 快 | 更快 | 大型项目、Webpack迁移 |
| Turbopack | 极快 | 快 | Vercel生态 |
二、包管理器
21. npm、yarn、pnpm有什么区别?
难度:⭐
标签:#npm #yarn #pnpm #包管理器
问题描述:
npm、yarn、pnpm这三款包管理器各有什么特点?
参考答案要点:
- npm:Node.js自带,v5+引入lock文件,v7+支持workspaces
- yarn:Facebook开发,并行安装、离线缓存、确定性安装
- pnpm:硬链接+符号链接机制,节省磁盘空间,严格的依赖隔离
22. pnpm为什么能节省磁盘空间?
难度:⭐⭐
标签:#pnpm #硬链接 #磁盘空间
问题描述:
pnpm为什么能显著节省磁盘空间?它的工作原理是什么?
参考答案要点:
- 使用硬链接(hard link)机制,全局只存储一份依赖
- 通过符号链接(symlink)组织node_modules结构
- 不同项目共享相同版本的依赖,不重复下载
23. 什么是幽灵依赖(Phantom Dependencies)?如何解决?
难度:⭐⭐
标签:#幽灵依赖 #npm #pnpm #依赖管理
问题描述:
什么是幽灵依赖?它会导致什么问题?如何解决?
参考答案要点:
- 定义:项目直接使用了未在package.json中声明的依赖
- 原因:npm/yarn的扁平化node_modules结构导致
- 解决:使用pnpm的严格依赖隔离,或使用 ESLint插件检测
24. 依赖版本号前的^和~有什么区别?
难度:⭐
标签:#semver #版本控制 #package.json
问题描述:
package.json中依赖版本号前的^和~有什么区别?
参考答案要点:
- ^:兼容次要版本和补丁版本更新,如^1.2.3允许1.x.x但不允许2.0.0
- ~:只兼容补丁版本更新,如~1.2.3允许1.2.x但不允许1.3.0
- 无符号:固定版本,如1.2.3
25. package-lock.json和yarn.lock有什么区别?
难度:⭐⭐
标签:#lock文件 #npm #yarn
问题描述:
package-lock.json和yarn.lock有什么区别?它们的作用是什么?
参考答案要点:
- package-lock.json:npm生成,锁定整个依赖树的具体版本和下载地址
- yarn.lock:yarn生成,同样锁定依赖版本,格式更简洁
- 作用:确保团队成员安装相同版本的依赖,保证构建一致性
26. 如何解决依赖冲突?
难度:⭐⭐⭐
标签:#依赖冲突 #依赖管理 #高级
问题描述:
项目中出现依赖冲突时,有哪些解决方法?
参考答案要点:
- 使用
npm ls或yarn why分析依赖树 - 使用
resolutions(yarn)或overrides(npm)强制指定版本 - 使用pnpm的依赖提升策略控制
- 考虑升级或替换冲突的依赖包
27. npx的作用是什么?
难度:⭐
标签:#npx #npm #命令执行
问题描述:
npx有什么作用?与npm有什么区别?
参考答案要点:
- 执行node_modules中的二进制命令
- 如果包未安装,会先临时下载执行,执行后删除
- 避免全局安装工具,如
npx create-react-app my-app
28. 什么是peerDependencies?
难度:⭐⭐
标签:#peerDependencies #插件开发 #依赖
问题描述:
package.json中的peerDependencies是什么?有什么作用?
参考答案要点:
- 声明宿主项目需要提供的依赖
- 常用于插件开发,如React组件库要求宿主项目提供React
- 不会自动安装,需要宿主项目自行声明
29. 如何清理node_modules并重新安装?
难度:⭐
标签:#node_modules #缓存清理 #npm
问题描述:
如何彻底清理node_modules并重新安装依赖?
参考答案要点:
- 删除node_modules和lock文件:
rm -rf node_modules package-lock.json - 清除npm缓存:
npm cache clean --force - 重新安装:
npm install - pnpm可使用
pnpm store prune清理存储
30. 什么是workspace?如何使用?
难度:⭐⭐
标签:#workspace #Monorepo #多包管理
问题描述:
什么是workspace?如何配置和使用?
参考答案要点:
- 允许在单个仓库中管理多个包
- npm/yarn/pnpm都支持workspaces
- 配置:package.json中添加
"workspaces": ["packages/*"] - 用于Monorepo架构,共享依赖和配置
代码示例:
// package.json
{
"workspaces": ["packages/*", "apps/*"]
}三、代码规范
31. ESLint和Prettier的区别是什么?
难度:⭐
标签:#ESLint #Prettier #代码规范
问题描述:
ESLint和Prettier有什么区别?它们各自的作用是什么?
参考答案要点:
- ESLint:静态代码分析,检查代码质量和潜在问题(如==和===)
- Prettier:代码格式化工具,统一代码风格(如缩进、引号、换行)
- 两者配合使用,ESLint负责质量,Prettier负责风格
32. 如何实现团队代码风格统一?
难度:⭐⭐
标签:#ESLint #Prettier #Husky #团队协作
问题描述:
如何在团队中实现代码风格的统一?
参考答案要点:
- ESLint:配置Airbnb/Standard规范,检测代码质量问题
- Prettier:自动格式化代码,统一风格
- Husky:Git hooks工具,在提交前执行检查
- lint-staged:只检查暂存区的文件,提高效率
33. Husky和lint-staged的作用是什么?
难度:⭐⭐
标签:#Husky #lint-staged #GitHooks
问题描述:
Husky和lint-staged分别有什么作用?如何配合使用?
参考答案要点:
- Husky:配置Git钩子(如pre-commit、commit-msg),在特定时机执行命令
- lint-staged:只对git暂存区的文件运行lint检查,避免检查整个项目
- 配合使用:在pre-commit钩子中运行
lint-staged,实现提交前自动格式化
34. 什么是Conventional Commits规范?
难度:⭐⭐
标签:#ConventionalCommits #Git提交 #规范
问题描述:
什么是Conventional Commits规范?它有什么作用?
参考答案要点:
- 提交信息格式:
<type>(<scope>): <subject> - type类型:feat(新功能)、fix(修复)、docs(文档)、style(格式)、refactor(重构)、test(测试)、chore(构建)
- 用于自动生成CHANGELOG和语义化版本
代码示例:
feat(user): 添加用户登录功能
fix(api): 修复接口请求超时问题
docs(readme): 更新项目说明
test(utils): 添加工具函数单元测试35. 如何配置ESLint + Prettier + Husky + lint-staged?
难度:⭐⭐⭐
标签:#ESLint #Prettier #Husky #工程化配置
问题描述:
如何在项目中完整配置ESLint + Prettier + Husky + lint-staged?
参考答案要点:
- 安装依赖:
npm install -D eslint prettier husky lint-staged eslint-config-prettier eslint-plugin-prettier - 配置.eslintrc:
extends: ['prettier'],避免与Prettier冲突 - 配置.prettierrc:定义格式化规则
- 配置lint-staged:在package.json中添加
"lint-staged": { "*.{js,jsx}": ["eslint --fix", "prettier --write"] } - 配置Husky:
npx husky install,添加pre-commit钩子执行npx lint-staged
代码示例:
// package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,scss}": ["stylelint --fix"]
}
}36. ESLint的extends和plugins有什么区别?
难度:⭐⭐
标签:#ESLint #配置 #extends #plugins
问题描述:
ESLint配置中的extends和plugins有什么区别?
参考答案要点:
- extends:继承已有的配置规则集合(如eslint:recommended、airbnb)
- plugins:引入第三方插件,提供额外的规则(如react、@typescript-eslint)
- extends可直接使用插件的规则,plugins需要先引入再配置规则
37. 如何处理ESLint和Prettier的规则冲突?
难度:⭐⭐
标签:#ESLint #Prettier #规则冲突
问题描述:
ESLint和Prettier的规则冲突时,如何解决?
参考答案要点:
- 安装
eslint-config-prettier关闭与Prettier冲突的ESLint规则 - 安装
eslint-plugin-prettier将Prettier作为ESLint规则运行 - 在.eslintrc中配置:
extends: ['plugin:prettier/recommended']
代码示例:
// .eslintrc.js
module.exports = {
extends: [
"eslint:recommended",
"plugin:prettier/recommended", // 放在最后,覆盖冲突规则
],
plugins: ["prettier"],
}38. 什么是pre-commit钩子?有哪些常见用法?
难度:⭐⭐
标签:#GitHooks #pre-commit #自动化
问题描述:
什么是pre-commit钩子?有哪些常见的使用场景?
参考答案要点:
- 在git commit执行前触发的钩子
- 常见用法:
- 运行代码检查(ESLint、Stylelint)
- 运行单元测试
- 检查提交信息格式
- 自动格式化代码
39. 如何自定义ESLint规则?
难度:⭐⭐⭐
标签:#ESLint #自定义规则 #AST
问题描述:
如何在ESLint中自定义规则?
参考答案要点:
- 创建规则文件,导出包含
meta和create方法的对象 meta定义规则元数据(文档、可修复性、schema)create返回visitor对象,在AST遍历到特定节点时执行- 发布为npm包或本地引入
40. Stylelint的作用是什么?如何配置?
难度:⭐⭐
标签:#Stylelint #CSS #代码规范
问题描述:
Stylelint有什么作用?如何配置?
参考答案要点:
- CSS/SCSS/Less的静态检查工具
- 配置方式与ESLint类似,使用.stylelintrc
- 可配置规则:属性顺序、单位限制、选择器规范等
- 可与Prettier配合,统一CSS代码风格
四、Git工作流
41. Git的rebase和merge有什么区别?
难度:⭐
标签:#Git #rebase #merge #分支合并
问题描述:
Git中的rebase和merge有什么区别?
参考答案要点:
- merge:创建一个新的合并提交,保留分支历史,形成分叉图
- rebase:将当前分支的提交移到目标分支顶部,形成线性历史
- merge保留完整上下文,rebase历史更简洁
42. 什么时候用rebase,什么时候用merge?
难度:⭐⭐
标签:#Git #rebase #merge #最佳实践
问题描述:
在实际开发中,什么时候应该使用rebase,什么时候应该使用merge?
参考答案要点:
- rebase适用:个人开发分支、保持提交历史整洁、合并前同步主分支
- merge适用:公共分支、需要保留完整上下文、已推送到远程的分支
- 原则:不要对已经push到远程的公共分支执行rebase
43. 什么是Git Flow工作流?
难度:⭐⭐
标签:#GitFlow #分支策略 #工作流
问题描述:
什么是Git Flow工作流?它包含哪些分支类型?
参考答案要点:
- 经典Git分支模型
- 分支类型:
- master/main:生产分支
- develop:开发分支
- feature/*:功能分支
- release/*:发布分支
- hotfix/*:热修复分支
- 适合有明确发布周期的项目
44. 什么是GitHub Flow工作流?
难度:⭐⭐
标签:#GitHubFlow #分支策略 #持续部署
问题描述:
什么是GitHub Flow工作流?它适合什么场景?
参考答案要点:
- 简化版Git工作流
- 只有main分支和feature分支
- 流程:从main创建feature分支 → 开发 → 提交PR → 代码审查 → 合并到main
- 适合持续部署的项目
45. git cherry-pick的作用是什么?
难度:⭐⭐
标签:#Git #cherry-pick #提交移植
问题描述:
git cherry-pick有什么作用?使用场景是什么?
参考答案要点:
- 将指定提交应用到当前分支
- 用于将特定commit从一个分支移植到另一个分支
- 不合并整个分支,只选取特定提交
46. git stash的作用和使用场景?
难度:⭐
标签:#Git #stash #临时保存
问题描述:
git stash有什么作用?常见的使用场景有哪些?
参考答案要点:
- 临时保存工作区的修改
- 使用场景:
- 需要临时切换到其他分支处理紧急问题
- 拉取远程更新但本地有未提交修改
- 暂时不想提交但需要保存当前进度
- 常用命令:
git stash、git stash pop、git stash list
47. git reset和git revert有什么区别?
难度:⭐⭐
标签:#Git #reset #revert #版本回退
问题描述:
git reset和git revert有什么区别?分别适用于什么场景?
参考答案要点:
- git reset:回退到指定版本,丢弃后续提交(会改变历史)
- --soft:保留工作区和暂存区
- --mixed:保留工作区,清空暂存区(默认)
- --hard:丢弃所有修改
- git revert:创建一个新的提交,撤销指定提交的修改(不改变历史)
- reset用于本地分支,revert用于公共分支
48. 如何解决Git合并冲突?
难度:⭐
标签:#Git #冲突解决 #merge
问题描述:
遇到Git合并冲突时,如何解决?
参考答案要点:
- 执行merge/rebase时遇到冲突,Git会标记冲突文件
- 打开冲突文件,查找
<<<<<<<、=======、>>>>>>>标记 - 手动编辑文件,保留需要的代码
- 使用
git add标记冲突已解决 - 完成merge/rebase操作
49. 什么是git hooks?有哪些常用钩子?
难度:⭐⭐
标签:#Git #GitHooks #自动化
问题描述:
什么是git hooks?有哪些常用的钩子?
参考答案要点:
- Git在特定事件发生时自动执行的脚本
- 客户端钩子:pre-commit、prepare-commit-msg、commit-msg、post-commit、pre-rebase
- 服务端钩子:pre-receive、update、post-receive
- 用于自动化代码检查、提交信息验证等
50. 如何保护主分支,防止直接推送?
难度:⭐⭐
标签:#Git #分支保护 #代码审查
问题描述:
如何保护主分支(main/master),防止开发者直接推送代码?
参考答案要点:
- GitHub/GitLab设置分支保护规则
- 禁止直接push到main/master分支
- 要求所有代码通过Pull Request/Merge Request合并
- 设置CI检查通过才能合并
- 要求代码审查(Code Review)批准
五、CI/CD
51. 什么是CI/CD?
难度:⭐
标签:#CI/CD #持续集成 #持续部署
问题描述:
什么是CI/CD?它们的核心目标是什么?
参考答案要点:
- CI(Continuous Integration):持续集成,频繁将代码合并到主干,通过自动化测试快速发现问题
- CD(Continuous Delivery/Deployment):持续交付/部署,代码通过测试后自动部署到生产环境
- 核心目标:快速发现和修复缺陷、减少手动操作、确保代码质量
52. GitHub Actions的工作原理是什么?
难度:⭐⭐
标签:#GitHubActions #CI/CD #自动化
问题描述:
GitHub Actions是如何工作的?它的核心概念有哪些?
参考答案要点:
- 基于事件触发的工作流自动化工具
- 工作流(Workflow)由作业(Job)组成,作业由步骤(Step)组成
- 配置文件:
.github/workflows/*.yml - 触发事件:push、pull_request、schedule等
- 使用Action市场中的预制动作或自定义脚本
代码示例:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "18"
- run: npm ci
- run: npm run build53. GitLab CI/CD如何配置?
难度:⭐⭐
标签:#GitLabCI #CI/CD #配置
问题描述:
GitLab CI/CD如何配置?它的核心概念是什么?
参考答案要点:
- 配置文件:
.gitlab-ci.yml - 概念:Pipeline(流水线)→ Stage(阶段)→ Job(任务)
- 使用Runner执行构建任务
- 支持Docker容器化构建
- 可配置缓存、制品(artifacts)、环境变量
54. Jenkins与GitHub Actions/GitLab CI有什么区别?
难度:⭐⭐
标签:#Jenkins #GitHubActions #GitLabCI #对比
问题描述:
Jenkins与GitHub Actions、GitLab CI有什么区别?
参考答案要点:
- Jenkins:自托管、高度可定制、插件丰富、适合复杂场景
- GitHub Actions:与GitHub深度集成、云原生、市场丰富
- GitLab CI/CD:与GitLab一体化、内置容器注册表、安全扫描
55. 如何设计一个前端CI/CD流水线?
难度:⭐⭐⭐
标签:#CI/CD #流水线设计 #前端工程化
问题描述:
如何设计一个完整的前端CI/CD流水线?
参考答案要点:
- 代码检查阶段:ESLint、Prettier、TypeScript类型检查
- 单元测试阶段:Jest/Vitest运行单元测试
- 构建阶段:Webpack/Vite构建生产包
- E2E测试阶段:Cypress/Playwright运行端到端测试
- 部署阶段:部署到测试环境/生产环境
- 通知阶段:发送构建结果通知
56. 什么是主分支保护策略?
难度:⭐⭐
标签:#分支保护 #CI/CD #代码质量
问题描述:
什么是主分支保护策略?为什么要实施?
参考答案要点:
- 禁止直接push到main/master分支
- 代码必须通过PR/MR合并
- CI检查通过才能合并
- 代码审查批准要求
- 分支必须是最新的才能合并
57. 如何在CI/CD中实现前端性能门禁?
难度:⭐⭐⭐
标签:#CI/CD #性能监控 #Lighthouse #门禁
问题描述:
如何在CI/CD流水线中实现前端性能门禁?
参考答案要点:
- 集成Lighthouse CI,设置性能阈值
- 配置性能预算(Performance Budget)
- 监控Core Web Vitals指标
- 指标不达标禁止代码合并
- 使用
@lhci/cli在CI中运行Lighthouse
58. Docker在前端CI/CD中的作用?
难度:⭐⭐
标签:#Docker #CI/CD #容器化
问题描述:
Docker在前端CI/CD中有什么作用?
参考答案要点:
- 容器化构建环境,保证环境一致性
- 隔离不同项目的依赖环境
- 快速部署和扩展
- 多阶段构建优化镜像体积
- 与Kubernetes配合实现自动化部署
59. 什么是蓝绿部署和金丝雀发布?
难度:⭐⭐⭐
标签:#部署策略 #蓝绿部署 #金丝雀发布
问题描述:
什么是蓝绿部署和金丝雀发布?它们有什么区别?
参考答案要点:
- 蓝绿部署:同时运行两个相同环境,切换流量实现零停机部署
- 金丝雀发布:先向小部分用户发布新版本,逐步扩大范围
- 两者都支持快速回滚
- 需要配合负载均衡和流量控制
60. 如何在CI/CD中管理环境变量和密钥?
难度:⭐⭐
标签:#CI/CD #密钥管理 #安全
问题描述:
如何在CI/CD流水线中安全管理环境变量和密钥?
参考答案要点:
- 使用CI/CD平台提供的Secrets管理功能
- 不在代码仓库中提交敏感信息
- 区分不同环境(开发、测试、生产)的配置
- 使用密钥管理服务(如AWS KMS、Azure Key Vault)
六、模块化
61. CommonJS和ES Module有什么区别?
难度:⭐
标签:#CommonJS #ESModule #模块化
问题描述:
CommonJS和ES Module有什么区别?
参考答案要点:
| 特性 | CommonJS | ES Module |
|---|---|---|
| 语法 | require/module.exports | import/export |
| 加载时机 | 运行时同步加载 | 编译时静态分析 |
| 加载方式 | 值拷贝 | 引用绑定 |
| 动态导入 | 支持 | import() |
| 使用环境 | Node.js | 浏览器/Node.js |
62. 什么是Tree Shaking?如何生效?
难度:⭐⭐
标签:#TreeShaking #优化 #ESModule
问题描述:
什么是Tree Shaking?如何让它生效?
参考答案要点:
- 消除未使用代码的优化技术
- 依赖ES Module的静态结构
- 需要:
- 使用ES Module语法
- 配置sideEffects字段
- 生产模式构建
- Webpack/Rollup都支持
63. UMD模块规范是什么?
难度:⭐⭐
标签:#UMD #模块规范 #通用模块
问题描述:
什么是UMD模块规范?它解决了什么问题?
参考答案要点:
- Universal Module Definition,通用模块定义
- 同时兼容CommonJS、AMD和全局变量
- 通过条件判断当前环境,使用对应的模块方式
- 适合需要跨环境运行的库
64. 什么是动态导入(Dynamic Import)?
难度:⭐
标签:#DynamicImport #懒加载 #代码分割
问题描述:
什么是动态导入(Dynamic Import)?有什么作用?
参考答案要点:
- ES2020引入的import()语法
- 运行时异步加载模块
- 返回Promise
- 用于代码分割和懒加载
代码示例:
// 动态导入
const module = await import("./module.js")
// 配合路由懒加载
const Home = () => import("./views/Home.vue")65. 循环依赖是什么?如何解决?
难度:⭐⭐⭐
标签:#循环依赖 #模块化 #高级
问题描述:
什么是循环依赖?它会导致什么问题?如何解决?
参考答案要点:
- 模块A依赖模块B,模块B又依赖模块A
- 可能导致未定义或部分初始化的导出
- 解决方案:
- 重构代码,提取公共逻辑
- 延迟导入(在函数内部require/import)
- 使用依赖注入
- 事件驱动解耦
66. 如何编写一个支持多种模块规范的库?
难度:⭐⭐⭐
标签:#模块规范 #库开发 #Rollup
问题描述:
如何编写一个同时支持CommonJS、ESM、UMD等多种模块规范的库?
参考答案要点:
- 使用Rollup打包,配置多格式输出
- 输出格式:ESM、CJS、UMD、IIFE
- package.json配置:
main: CJS入口module: ESM入口unpkg/jsdelivr: UMD入口exports: 条件导出
67. package.json中的exports字段有什么作用?
难度:⭐⭐
标签:#package.json #exports #条件导出
问题描述:
package.json中的exports字段有什么作用?
参考答案要点:
- 定义包的入口点映射
- 支持条件导出(根据导入方式返回不同文件)
代码示例:
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./utils": {
"import": "./dist/utils.mjs",
"require": "./dist/utils.cjs"
}
}
}68. 什么是sideEffects?如何配置?
难度:⭐⭐
标签:#sideEffects #TreeShaking #package.json
问题描述:
package.json中的sideEffects字段是什么?如何配置?
参考答案要点:
- 标记模块是否有副作用
- 用于Tree Shaking优化
- 配置:
"sideEffects": false:无副作用,可安全删除未使用代码"sideEffects": ["*.css", "*.scss"]:指定有副作用的文件
69. AMD和CMD有什么区别?
难度:⭐⭐
标签:#AMD #CMD #模块规范 #历史
问题描述:
AMD和CMD有什么区别?
参考答案要点:
- AMD(Asynchronous Module Definition):异步模块定义,RequireJS实现
- 依赖前置,提前执行
define(['dep'], function(dep) {})
- CMD(Common Module Definition):通用模块定义,SeaJS实现
- 依赖就近,延迟执行
define(function(require, exports, module) { var dep = require('dep') })
70. 如何在Node.js中使用ES Module?
难度:⭐⭐
标签:#Node.js #ESModule #模块化
问题描述:
如何在Node.js中使用ES Module?
参考答案要点:
- 文件后缀改为.mjs
- 或在package.json中设置
"type": "module" - 使用--experimental-modules标志(Node.js 12+)
- 注意:ESM中不能使用**dirname、**filename,需用import.meta.url替代
代码示例:
// package.json
{
"type": "module"
}// 替代 __dirname
import { fileURLToPath } from "url"
import { dirname } from "path"
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)七、微前端
71. 什么是微前端?它解决了什么问题?
难度:⭐
标签:#微前端 #架构 #前端工程化
问题描述:
什么是微前端?它主要解决了什么问题?
参考答案要点:
- 将前端应用拆分为独立模块的架构模式
- 核心价值:
- 技术栈无关性:支持React、Vue、Angular共存
- 独立部署:子应用可独立更新
- 团队自治:跨团队协作减少耦合
- 渐进式升级:老系统逐步替换
72. 微前端有哪些常见实现方案?
难度:⭐⭐
标签:#微前端 #方案对比 #架构
问题描述:
微前端有哪些常见的实现方案?各有什么优缺点?
参考答案要点:
| 方案 | 优点 | 缺点 |
|---|---|---|
| iframe | 天然隔离 | 通信复杂、性能差、SEO不友好 |
| Web Components | 浏览器原生、Shadow DOM隔离 | 生态较弱 |
| qiankun | 开箱即用、JS/CSS隔离、预加载 | 主子应用耦合 |
| single-spa | 轻量级、灵活 | 需统一生命周期管理 |
| Module Federation | 动态加载、共享依赖 | 版本管理复杂 |
73. qiankun的工作原理是什么?
难度:⭐⭐
标签:#qiankun #微前端 #single-spa
问题描述:
qiankun的工作原理是什么?它是如何实现JS和CSS隔离的?
参考答案要点:
- 基于single-spa封装
- 注册微应用:配置name、entry、container、activeRule
- 生命周期管理:load、bootstrap、mount、unmount
- JS隔离:Proxy沙箱
- CSS隔离:Shadow DOM或严格样式隔离
74. 如何在微前端中实现JS隔离?
难度:⭐⭐⭐
标签:#微前端 #JS隔离 #沙箱
问题描述:
在微前端架构中,如何实现JS隔离?
参考答案要点:
- Snapshot沙箱:记录和恢复window对象状态
- Proxy沙箱:使用Proxy代理window对象
- VM沙箱:使用with + Proxy创建独立作用域
- qiankun使用Proxy沙箱实现JS隔离
75. 如何在微前端中实现CSS隔离?
难度:⭐⭐⭐
标签:#微前端 #CSS隔离 #样式隔离
问题描述:
在微前端架构中,如何实现CSS隔离?
参考答案要点:
- Shadow DOM:真正的样式隔离
- CSS Modules:局部化类名
- BEM命名规范:通过命名约定避免冲突
- qiankun的严格样式隔离:给子应用样式添加前缀
76. Module Federation在微前端中的作用是什么?
难度:⭐⭐
标签:#ModuleFederation #Webpack5 #微前端
问题描述:
Module Federation在微前端中有什么作用?
参考答案要点:
- Webpack 5的模块联邦功能
- 支持动态加载远程模块
- 共享依赖:多个子应用共享React等库
- 去中心化:无需主应用即可集成
77. 微前端中的通信机制有哪些?
难度:⭐⭐
标签:#微前端 #通信机制 #架构
问题描述:
微前端架构中,子应用之间有哪些通信方式?
参考答案要点:
- Props传递:主应用向子应用传递数据
- CustomEvent:自定义事件通信
- 全局状态管理:Redux、MobX等
- 发布订阅模式:EventBus
- URL参数:通过路由传递信息
78. 微前端如何处理路由?
难度:⭐⭐
标签:#微前端 #路由 #单页应用
问题描述:
微前端架构中,路由是如何处理的?
参考答案要点:
- 主应用路由:监听URL变化,匹配激活对应子应用
- 子应用路由:使用history模式,与主应用路由同步
- 路由同步:主应用通过props向子应用传递路由信息
- qiankun路由:自动处理路由切换和子应用激活
79. 微前端如何处理依赖冲突?
难度:⭐⭐⭐
标签:#微前端 #依赖冲突 #版本管理
问题描述:
微前端架构中,如何处理不同子应用之间的依赖冲突?
参考答案要点:
- 版本隔离:每个子应用使用独立依赖版本
- 共享依赖:通过Module Federation或externals指定单一版本
- 沙箱隔离:避免依赖污染全局环境
- 依赖分析:使用工具分析依赖树,识别冲突
80. 微前端如何实现子应用预加载?
难度:⭐⭐
标签:#微前端 #预加载 #性能优化
问题描述:
微前端架构中,如何实现子应用的预加载?
参考答案要点:
- 手动预加载:提前加载子应用脚本
- qiankun预加载:配置prefetch属性
- 懒加载:结合路由动态加载
- 预加载策略:空闲时预加载、可见时预加载
微前端方案对比表:
| 方案 | 隔离性 | 性能 | 适用场景 |
|---|---|---|---|
| iframe | ⭐⭐⭐⭐⭐ | 差 | 强隔离需求 |
| qiankun | ⭐⭐⭐⭐ | 好 | 存量系统迁移 |
| Module Federation | ⭐⭐ | 极好 | 技术栈统一、性能优先 |
八、Monorepo
81. 什么是Monorepo?有什么优缺点?
难度:⭐
标签:#Monorepo #代码组织 #多包管理
问题描述:
什么是Monorepo?它有什么优缺点?
参考答案要点:
- 单仓库管理多个包/项目的代码组织方式
- 优点:
- 代码共享和复用
- 统一构建和发布流程
- 跨项目重构方便
- 依赖管理统一
- 缺点:
- 仓库体积大
- 权限管理复杂
- CI/CD配置复杂
82. pnpm workspace如何配置和使用?
难度:⭐⭐
标签:#pnpm #workspace #Monorepo
问题描述:
pnpm workspace如何配置和使用?
参考答案要点:
- 创建
pnpm-workspace.yaml:
代码示例:
# pnpm-workspace.yaml
packages:
- "packages/*"
- "apps/*"- 在package.json中配置
"workspaces": ["packages/*"] - 使用
pnpm add --workspace添加workspace依赖 - 使用
pnpm -r递归执行命令
83. Turborepo是什么?有什么优势?
难度:⭐⭐
标签:#Turborepo #Monorepo #构建优化
问题描述:
Turborepo是什么?相比其他Monorepo工具有什么优势?
参考答案要点:
- Vercel推出的Monorepo构建工具
- 优势:
- 任务管道:定义任务依赖关系
- 本地和远程缓存:加速构建
- 并行执行:提高构建效率
- 增量构建:只构建变更的部分
- 配置:turbo.json定义pipeline
84. Changesets的作用是什么?
难度:⭐⭐
标签:#Changesets #版本管理 #CHANGELOG
问题描述:
Changesets有什么作用?如何使用?
参考答案要点:
- 管理版本和生成变更日志的工具
- 适合多包管理的Monorepo
- 功能:
- 记录变更描述和版本影响(major/minor/patch)
- 自动生成CHANGELOG
- 自动更新版本号
- 命令:
changeset add、changeset version、changeset publish
85. Lerna和Changesets有什么区别?
难度:⭐⭐
标签:#Lerna #Changesets #版本管理
问题描述:
Lerna和Changesets有什么区别?
参考答案要点:
- Lerna:早期Monorepo工具,管理包版本和发布
- 自动根据提交历史确定版本
- 支持fixed和independent模式
- Changesets:更灵活,客制化更高
- 手动记录变更
- CI/CD更友好
- 与pnpm workspace配合更好
86. 如何保证Monorepo的Git提交清晰?
难度:⭐⭐⭐
标签:#Monorepo #Git #提交规范
问题描述:
在Monorepo中,如何保证Git提交的清晰和规范?
参考答案要点:
- 使用Conventional Commits规范
- 模块化提交(原子性提交)
- 使用scope指定变更范围
- 配置CODEOWNERS文件
- 使用Changesets记录变更
- 功能分支 + Squash Merge
87. Monorepo中的依赖管理最佳实践?
难度:⭐⭐⭐
标签:#Monorepo #依赖管理 #最佳实践
问题描述:
Monorepo中的依赖管理有哪些最佳实践?
参考答案要点:
- 公共依赖提升到根目录
- 使用workspace协议引用内部包
- 统一依赖版本
- 使用pnpm的严格依赖隔离
- 定期清理未使用的依赖
88. 如何在Monorepo中实现增量构建?
难度:⭐⭐⭐
标签:#Monorepo #增量构建 #Turborepo
问题描述:
如何在Monorepo中实现增量构建,提高构建效率?
参考答案要点:
- 使用Turborepo的缓存机制
- 配置任务依赖关系(dependsOn)
- 使用
nx affected只构建受影响的包 - 配置远程缓存(Vercel Remote Cache)
- CI中利用缓存加速构建
89. Monorepo如何配置CI/CD流水线?
难度:⭐⭐⭐
标签:#Monorepo #CI/CD #流水线
问题描述:
Monorepo项目如何配置CI/CD流水线?
参考答案要点:
- 使用
pnpm -r或turbo run执行命令 - 配置缓存策略(node_modules、构建产物)
- 并行执行独立的任务
- 使用Changesets自动化版本发布
- 配置GitHub Actions/GitLab CI的workflow
90. 如何在Monorepo中共享配置(ESLint、TypeScript)?
难度:⭐⭐
标签:#Monorepo #共享配置 #ESLint #TypeScript
问题描述:
如何在Monorepo中共享ESLint、TypeScript等配置?
参考答案要点:
- 创建配置包(如
@monorepo/eslint-config) - 使用extends继承共享配置
- TypeScript配置使用
extends和references - 在根目录统一管理配置
- 各项目引入并扩展共享配置
代码示例:
// packages/eslint-config/package.json
{
"name": "@monorepo/eslint-config",
"main": "index.js"
}
// 使用配置的项目
{
"devDependencies": {
"@monorepo/eslint-config": "workspace:*"
}
}九、容器化
91. Docker的核心概念有哪些?
难度:⭐
标签:#Docker #容器化 #基础概念
问题描述:
Docker有哪些核心概念?
参考答案要点:
- 镜像(Image):只读模板,包含运行应用所需的所有内容
- 容器(Container):镜像的运行实例
- Dockerfile:定义镜像构建步骤的脚本
- 仓库(Registry):存储和分发镜像的服务
92. 如何编写前端项目的Dockerfile?
难度:⭐⭐
标签:#Docker #Dockerfile #前端部署
问题描述:
如何为前端项目编写Dockerfile?
参考答案要点:
- 使用多阶段构建优化镜像体积
- 第一阶段:构建应用
- 第二阶段:使用Nginx提供静态文件服务
代码示例:
# 多阶段构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 8093. 什么是Docker多阶段构建?有什么优势?
难度:⭐⭐
标签:#Docker #多阶段构建 #优化
问题描述:
什么是Docker多阶段构建?有什么优势?
参考答案要点:
- 在一个Dockerfile中使用多个FROM指令
- 优势:
- 减小最终镜像体积
- 分离构建环境和运行环境
- 提高构建效率
- 增强安全性(不包含构建工具)
94. 如何优化Docker镜像体积?
难度:⭐⭐
标签:#Docker #镜像优化 #体积
问题描述:
如何优化Docker镜像的体积?
参考答案要点:
- 使用多阶段构建
- 选择轻量级基础镜像(alpine、slim)
- 清理缓存和临时文件
- 合并RUN指令减少层数
- 使用.dockerignore排除不需要的文件
95. Docker的网络模式有哪些?
难度:⭐⭐
标签:#Docker #网络 #容器通信
问题描述:
Docker有哪些网络模式?
参考答案要点:
- bridge:默认模式,容器使用独立网络栈
- host:与宿主机共享网络
- none:无网络配置
- container:与指定容器共享网络
96. 如何将本地镜像推送到镜像仓库?
难度:⭐
标签:#Docker #镜像仓库 #推送
问题描述:
如何将本地构建的Docker镜像推送到镜像仓库?
参考答案要点:
- 登录仓库:
docker login - 给镜像打标签:
docker tag local-image:tag registry/image:tag - 推送镜像:
docker push registry/image:tag
97. 如何进入运行中的Docker容器?
难度:⭐
标签:#Docker #容器操作 #调试
问题描述:
如何进入运行中的Docker容器进行调试?
参考答案要点:
docker exec -it <container_id> /bin/bashdocker exec -it <container_id> /bin/sh(alpine镜像)- 使用
docker attach附加到容器主进程
98. 什么是Docker Compose?如何使用?
难度:⭐⭐
标签:#DockerCompose #多容器 #编排
问题描述:
什么是Docker Compose?如何使用?
参考答案要点:
- 定义和运行多容器应用的工具
- 使用docker-compose.yml配置服务
- 常用命令:
docker-compose up:启动服务docker-compose down:停止服务docker-compose build:构建镜像
99. 如何在Docker中实现前端热更新?
难度:⭐⭐⭐
标签:#Docker #热更新 #开发环境
问题描述:
如何在Docker容器中实现前端开发热更新?
参考答案要点:
- 使用volume挂载本地代码到容器
- 配置webpack/vite的poll模式
- 使用docker-compose的volumes配置
代码示例:
# docker-compose.yml
version: "3"
services:
app:
build: .
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"100. Docker与虚拟机的区别是什么?
难度:⭐⭐
标签:#Docker #虚拟机 #容器化
问题描述:
Docker与虚拟机有什么区别?
参考答案要点:
| 特性 | Docker | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 轻量(共享内核) | 重量级(完整OS) |
| 性能 | 接近原生 | 有性能损耗 |
| 隔离性 | 进程级隔离 | 系统级隔离 |
| 体积 | MB级 | GB级 |
十、性能监控
101. Core Web Vitals包含哪些指标?
难度:⭐
标签:#CoreWebVitals #性能指标 #Web性能
问题描述:
Core Web Vitals包含哪些核心指标?各自的目标值是多少?
参考答案要点:
- LCP(Largest Contentful Paint):最大内容绘制,目标<2.5s
- FID(First Input Delay):首次输入延迟,目标<100ms
- CLS(Cumulative Layout Shift):累积布局偏移,目标<0.1
- 2024年新增:INP(Interaction to Next Paint)替代FID
Core Web Vitals目标值表:
| 指标 | 优秀 | 需改进 | 差 |
|---|---|---|---|
| LCP | ≤2.5s | 2.5-4s | >4s |
| FID/INP | ≤100ms | 100-300ms | >300ms |
| CLS | ≤0.1 | 0.1-0.25 | >0.25 |
102. 如何监控前端性能指标?
难度:⭐⭐
标签:#性能监控 #PerformanceAPI #web-vitals
问题描述:
如何监控前端性能指标?有哪些方法和工具?
参考答案要点:
- 实验室数据:Lighthouse、Chrome DevTools Performance面板
- 真实用户数据:
- Performance API
- web-vitals库
- PerformanceObserver
- 上报到监控平台,统计P75/P90/P95分位值
103. Lighthouse评分如何计算?
难度:⭐⭐
标签:#Lighthouse #性能评分 #性能优化
问题描述:
Lighthouse的评分是如何计算的?
参考答案要点:
- 基于性能、可访问性、最佳实践、SEO、PWA五个维度
- 性能评分权重:LCP(25%)、TBT(30%)、CLS(25%)、Speed Index(10%)、FCP(10%)
- 分数范围:0-100分
- 90-100为优秀,50-89需要改进,0-49较差
104. 如何实现前端错误监控?
难度:⭐⭐
标签:#错误监控 #异常捕获 #监控SDK
问题描述:
如何实现前端错误监控?
参考答案要点:
- 全局错误捕获:
window.onerror、window.addEventListener('error') - Promise错误:
window.addEventListener('unhandledrejection') - 框架错误:React Error Boundary、Vue errorHandler
- 上报方式:
navigator.sendBeacon、Fetch、图片ping - 工具:Sentry、Fundebug
代码示例:
// 全局错误捕获
window.onerror = function (msg, url, line, col, error) {
reportError({ msg, url, line, col, stack: error?.stack })
}
// Promise错误捕获
window.addEventListener("unhandledrejection", (event) => {
reportError({ type: "unhandledrejection", reason: event.reason })
})105. 什么是前端埋点?有哪些埋点方式?
难度:⭐⭐
标签:#埋点 #数据采集 #用户行为
问题描述:
什么是前端埋点?有哪些埋点方式?
参考答案要点:
- 代码埋点:手动在代码中插入埋点代码
- 可视化埋点:通过可视化工具配置埋点
- 全埋点:自动采集所有用户行为
- 数据类型:页面浏览、点击事件、性能指标、错误信息
106. 如何设计前端监控SDK?
难度:⭐⭐⭐
标签:#监控SDK #架构设计 #前端监控
问题描述:
如何设计一个前端监控SDK?
参考答案要点:
- 错误监控:捕获JS错误、Promise错误、资源加载错误
- 性能监控:采集Core Web Vitals、资源加载时间
- 行为监控:页面PV/UV、点击热力图、用户路径
- 数据上报:批量上报、延迟上报、失败重试
- 采样策略:控制数据量,降低成本
107. 如何优化LCP指标?
难度:⭐⭐
标签:#LCP #性能优化 #CoreWebVitals
问题描述:
如何优化LCP(最大内容绘制)指标?
参考答案要点:
- 优化服务器响应时间(TTFB)
- 预加载关键资源(
<link rel="preload">) - 优化图片:压缩、WebP格式、响应式图片
- 使用CDN加速
- 内联关键CSS
108. 如何优化CLS指标?
难度:⭐⭐
标签:#CLS #性能优化 #布局偏移
问题描述:
如何优化CLS(累积布局偏移)指标?
参考答案要点:
- 为图片和视频预留尺寸空间
- 避免在已有内容上方插入内容
- 谨慎使用会改变布局的动画
- 字体加载优化(font-display: swap)
- 预留广告位尺寸
109. Sentry的工作原理是什么?
难度:⭐⭐
标签:#Sentry #错误监控 #SourceMap
问题描述:
Sentry是如何工作的?
参考答案要点:
- 通过
window.onerror和unhandledrejection捕获错误 - 收集错误信息、堆栈跟踪、用户环境
- Source Map映射到源码位置
- 支持面包屑(Breadcrumbs)记录用户操作
- 提供性能监控和会话回放功能
110. 如何在CI/CD中集成性能测试?
难度:⭐⭐⭐
标签:#CI/CD #性能测试 #LighthouseCI
问题描述:
如何在CI/CD流水线中集成性能测试?
参考答案要点:
- 集成Lighthouse CI
- 配置性能预算(Performance Budget)
- 设置性能阈值门禁
- 对比每次构建的性能变化
- 生成性能报告并通知团队
十一、前端安全
111. 什么是XSS攻击?有哪些类型?
难度:⭐
标签:#XSS #安全 #攻击类型
问题描述:
什么是XSS攻击?有哪些类型?
参考答案要点:
- 定义:攻击者向页面注入恶意脚本,在用户浏览器中执行
- 类型:
- 存储型:恶意脚本存入数据库
- 反射型:恶意脚本在URL参数中
- DOM型:前端JS操作DOM导致执行恶意代码
112. 如何防范XSS攻击?
难度:⭐⭐
标签:#XSS #安全防范 #CSP
问题描述:
如何防范XSS攻击?
参考答案要点:
- 输入过滤:对用户输入进行验证和过滤
- 输出编码:HTML实体编码,转义特殊字符
- CSP(内容安全策略):限制可执行的脚本来源
- HttpOnly Cookie:禁止JS读取敏感Cookie
- 纯前端渲染:代码和数据分离
代码示例:
// HTML实体编码
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// CSP配置
Content-Security-Policy: default-src 'self'; script-src 'self'113. 什么是CSRF攻击?如何防范?
难度:⭐
标签:#CSRF #安全 #攻击防范
问题描述:
什么是CSRF攻击?如何防范?
参考答案要点:
- 定义:攻击者诱导已登录用户向目标网站发送非本意的请求
- 防范措施:
- CSRF Token:服务端生成,请求时验证
- SameSite Cookie:设置Cookie的SameSite属性
- Referer/Origin校验:验证请求来源
- 双重Cookie验证
114. CSP(内容安全策略)是什么?如何配置?
难度:⭐⭐
标签:#CSP #安全 #内容安全策略
问题描述:
什么是CSP(内容安全策略)?如何配置?
参考答案要点:
- 定义页面可以加载哪些资源的策略
- 通过HTTP头或meta标签配置
- 常用指令:
default-src:默认资源策略script-src:脚本来源style-src:样式来源img-src:图片来源
代码示例:
Content-Security-Policy: default-src 'self';
script-src 'self' 'unsafe-inline' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:115. 什么是点击劫持(Clickjacking)?如何防范?
难度:⭐⭐
标签:#点击劫持 #安全 #X-Frame-Options
问题描述:
什么是点击劫持?如何防范?
参考答案要点:
- 攻击者通过iframe嵌套目标页面,诱导用户点击
- 防范措施:
X-Frame-Options头:DENY、SAMEORIGIN- CSP的
frame-ancestors指令 - JavaScript检测(frame busting)
116. HTTPS为什么安全?
难度:⭐⭐
标签:#HTTPS #TLS #安全传输
问题描述:
HTTPS为什么比HTTP安全?
参考答案要点:
- 加密:TLS/SSL加密传输数据,防止窃听
- 身份认证:数字证书验证服务器身份
- 完整性:防止数据被篡改
- 握手过程:密钥交换、证书验证、加密通信
117. 什么是中间人攻击(MITM)?如何防范?
难度:⭐⭐⭐
标签:#MITM #中间人攻击 #安全
问题描述:
什么是中间人攻击?如何防范?
参考答案要点:
- 攻击者拦截并可能修改通信双方的数据
- 防范措施:
- 使用HTTPS
- 证书固定(Certificate Pinning)
- HSTS(HTTP Strict Transport Security)
- 警惕不安全的WiFi网络
118. 前端如何安全地存储敏感数据?
难度:⭐⭐
标签:#安全存储 #Cookie #Token
问题描述:
前端如何安全地存储敏感数据(如Token)?
参考答案要点:
- 避免:localStorage、sessionStorage存储敏感信息(可被XSS窃取)
- 推荐:
- HttpOnly Cookie存储Token
- 内存中存储临时敏感数据
- 使用Web Crypto API加密
- Token过期策略:短有效期 + 刷新机制
119. 什么是SQL注入?前端如何配合防范?
难度:⭐
标签:#SQL注入 #安全 #输入验证
问题描述:
什么是SQL注入?前端如何配合防范?
参考答案要点:
- 攻击者在输入中拼接SQL语句,操控数据库
- 前端配合:
- 输入验证和过滤
- 参数化查询(后端实现)
- 最小权限原则
- 永远不要信任用户输入
120. 如何防范前端代码被反编译或篡改?
难度:⭐⭐⭐
标签:#代码保护 #混淆 #安全
问题描述:
如何防范前端代码被反编译或篡改?
参考答案要点:
- 代码混淆:使用UglifyJS、Terser压缩混淆
- Source Map保护:生产环境不暴露Source Map
- 完整性校验:SRI(Subresource Integrity)验证资源完整性
- 服务端渲染:关键逻辑放在服务端
- 法律手段:版权声明、使用协议
附录:复习建议
📚 复习策略
1. 按难度分层复习
| 难度 | 题目数量 | 建议时间 | 目标 |
|---|---|---|---|
| ⭐ 基础 | 48道 | 1-2天 | 必须全部掌握 |
| ⭐⭐ 中级 | 54道 | 2-3天 | 理解原理,能举例说明 |
| ⭐⭐⭐ 高级 | 18道 | 2-3天 | 了解概念,能参与讨论 |
2. 重点题目推荐(面试高频)
必会题目(Top 20):
- Webpack的核心原理(Q1)
- Loader与Plugin的区别(Q2)
- 如何提高Webpack打包速度(Q4)
- Vite为什么这么快(Q12)
- npm/yarn/pnpm区别(Q21)
- ESLint和Prettier的区别(Q31)
- Husky和lint-staged的作用(Q33)
- Git的rebase和merge区别(Q41)
- 什么是CI/CD(Q51)
- CommonJS和ES Module区别(Q61)
- 什么是Tree Shaking(Q62)
- 什么是微前端(Q71)
- qiankun的工作原理(Q73)
- 什么是Monorepo(Q81)
- Docker多阶段构建(Q93)
- Core Web Vitals指标(Q101)
- 如何实现前端错误监控(Q104)
- 什么是XSS攻击(Q111)
- 如何防范XSS攻击(Q112)
- 什么是CSRF攻击(Q113)
3. 学习路径建议
第一阶段:基础夯实(1-2周)
├── 构建工具(Webpack/Vite基础)
├── 包管理器(npm/yarn/pnpm)
├── 代码规范(ESLint/Prettier)
└── Git基础操作
第二阶段:进阶提升(2-3周)
├── Webpack优化技巧
├── CI/CD流水线设计
├── 模块化规范深入
└── Git工作流实践
第三阶段:架构视野(持续学习)
├── 微前端架构
├── Monorepo管理
├── 性能监控体系
└── 前端安全防护💡 面试技巧
- 原理先行:理解底层原理比记住配置更重要
- 结合实践:用实际项目经验支撑你的回答
- 对比分析:善于对比不同技术的优缺点
- 关注性能:性能优化是工程化的核心话题
- 安全意识:前端安全越来越受重视