前端工程化
1 打包工具
Webpack 核心概念?Loader 和 Plugin 的区别?
Entry:入口文件。Output:打包输出。Loader:转换非 JS 文件(如 babel-loader 转 ES6、css-loader 处理 CSS)。Plugin:扩展 Webpack 功能(如 HtmlWebpackPlugin 生成 HTML、MiniCssExtractPlugin 提取 CSS)。
区别:Loader 是文件级的转换器(管"翻译"),Plugin 是构建流程的钩子(管"整体")。Loader 在 module.rules 中配置,Plugin 在 plugins 数组中实例化。
Vite 为什么比 Webpack 快?
开发阶段:Vite 不打包,利用浏览器原生 ESM(
HMR:Vite 的热更新只需更新变化的模块,不受项目规模影响。
生产构建:Vite 底层用 Rollup 打包(基于 ESM,Tree Shaking 更高效)+ esbuild 做预构建(Go 编写,比 JS 快 10-100 倍)。
import),按需编译请求的模块。Webpack 需要先把所有模块打成 bundle 才能启动。HMR:Vite 的热更新只需更新变化的模块,不受项目规模影响。
生产构建:Vite 底层用 Rollup 打包(基于 ESM,Tree Shaking 更高效)+ esbuild 做预构建(Go 编写,比 JS 快 10-100 倍)。
Tree Shaking 原理?
基于 ESM 的静态结构(import/export 在编译时确定),分析哪些导出没被使用,在打包时移除"死代码"。
前提条件:① 必须用 ESM(import/export),CommonJS 无法 Tree Shaking ② 无副作用(或用 sideEffects: false 标记)③ 生产模式(mode: production)。
Webpack 的 Module / Chunk / Bundle 是什么?
Module:源代码中的每个文件(JS、CSS、图片等经 Loader 处理后)。
Chunk:Webpack 根据入口 + 依赖 + 分割规则,把 Module 分组后的中间产物。
Bundle:Chunk 经过 Plugin 处理后的最终输出文件。
Chunk:Webpack 根据入口 + 依赖 + 分割规则,把 Module 分组后的中间产物。
Bundle:Chunk 经过 Plugin 处理后的最终输出文件。
简单理解:Module 是原材料 → Chunk 是半成品 → Bundle 是成品。
2 模块化
CommonJS vs ESM 的区别?
CommonJS:
ESM:
require/module.exports,运行时加载,同步,输出值的拷贝(修改不影响原始模块)。Node.js 默认。ESM:
import/export,编译时确定依赖,异步,输出值的引用(实时绑定)。浏览器原生支持。
关键差异:ESM 的静态分析能力使 Tree Shaking 成为可能;CJS 的动态特性(可以在 if 里 require)使其无法 Tree Shaking。
循环依赖怎么处理?
CJS:遇到循环依赖时返回未完成的模块导出(可能拿到 undefined)。
ESM:使用实时绑定,导入的变量在执行时才求值,但如果在初始化前访问也会报错。
最佳方案:重构代码结构,将共享部分提取到独立模块,避免循环。
ESM:使用实时绑定,导入的变量在执行时才求值,但如果在初始化前访问也会报错。
最佳方案:重构代码结构,将共享部分提取到独立模块,避免循环。
3 CI/CD
前端 CI/CD 流程?
CI(持续集成):代码提交 → 自动执行 lint + 单元测试 + 构建 → 失败即阻止合并。
CD(持续部署):代码合并到主分支 → 自动构建 → 上传到 CDN / 部署到服务器。
CD(持续部署):代码合并到主分支 → 自动构建 → 上传到 CDN / 部署到服务器。
典型工具链:GitHub Actions / GitLab CI / Jenkins → ESLint + Prettier → Jest/Vitest → Docker → Nginx/CDN
4 代码质量
ESLint / Prettier / Husky 各自作用?
ESLint:静态代码分析,检查语法错误和潜在问题(如未使用变量、危险 API)。可自定义规则。
Prettier:代码格式化(缩进、引号、分号等),保证团队风格统一。
Husky:Git hooks 管理工具,在 commit 前自动运行 lint/format/test。
Prettier:代码格式化(缩进、引号、分号等),保证团队风格统一。
Husky:Git hooks 管理工具,在 commit 前自动运行 lint/format/test。
典型配合:Husky 配置 pre-commit hook → lint-staged 只检查暂存文件 → ESLint 检查 + Prettier 格式化。
5 包管理
npm / yarn / pnpm 区别?为什么推荐 pnpm?
npm:Node 自带,v3+ 扁平化 node_modules,但有幽灵依赖问题。
yarn:Facebook 出品,并行安装更快,yarn.lock 确保确定性。
pnpm:用硬链接 + 符号链接共享全局 store 中的包,节省磁盘空间 50%+,安装速度最快,且严格的 node_modules 结构杜绝了幽灵依赖。
yarn:Facebook 出品,并行安装更快,yarn.lock 确保确定性。
pnpm:用硬链接 + 符号链接共享全局 store 中的包,节省磁盘空间 50%+,安装速度最快,且严格的 node_modules 结构杜绝了幽灵依赖。
幽灵依赖:项目中能 import 自己没有在 package.json 中声明的包(因为 npm 扁平化后它存在于 node_modules 根目录)。pnpm 的非扁平结构直接避免这个问题。