摘要(Auto)
- 生成时间:2025-12-20
- 简历中出现的项目标题(提取):大疆用户中心重构 / 大疆售后 RMS 系统重构 / 跨平台公告插件系统 / 大疆 DevOps 平台维护 / XDR 系统 - 魔方大屏 + 报表
- 面试大纲关键词(提取 Top10):1)大疆用户中心重构:性能优化 + HTTP 原理 + Webpack 架构 / 性能指标与方法论 / 简历可落地点(结合你的“优化四板斧”) / HTTP 常考点(从“为什么变快”倒推) / Webpack 架构(工程化面试常考) / 按优化顺序,把方案“串起来”(排查 → 定位 → 选择 → 验证) / 0. 排查与基线(先把问题“量化”) / 1. 先保“可见”——骨架屏预渲染(直接拉低 LCP) / 2. 再减“阻塞”——关键渲染路径(CRP)梳理:CSS/字体/首图优先级 / 3. 再降“下载与解析成本”——更小的包体与更少的无效代码
建议追问(Auto)
- 你为什么在该项目/场景里选择这个方案?替代方案为何不选?
- 最大一次事故/踩坑是什么?如何定位与回滚?
- 如果重做:架构/边界/工程化会怎么调整?
关联卡片
在我项目中的角色与使用场景
- 典型场景:做“跨平台公告插件/SDK/组件库”这类要被外部系统集成的产物。
- 目标:产物要小、格式要全(esm/cjs/umd)、tree-shaking 友好、外部依赖可控(external)。
- 我在项目里的落地:
- 设计多产物输出(ESM + CJS + UMD),并约定
exports字段与类型声明输出。 - 控制 breaking change:版本化、变更记录、以及验证“被集成方”的兼容性矩阵。
- 设计多产物输出(ESM + CJS + UMD),并约定
原理简述
Rollup 的核心优势是:以 ESM 为中心做静态分析,天然适合 tree-shaking 与高质量库产物。
- 模块解析:对 ESM import/export 做静态分析,构建依赖图。
- tree-shaking:
- 能删除“未被引用的导出”,前提是代码可静态分析且无副作用(side effects)。
- 关键开关:
treeshake、moduleSideEffects、以及package.json的sideEffects声明。
- external:库构建常把
react这类依赖标记为外部,避免打进产物导致重复依赖与体积膨胀。 - 插件体系:同样有 transform/resolve/load/generateBundle 等生命周期,生态成熟。
权衡点:
- Rollup 不以 Dev Server/HMR 为核心;做应用构建往往需要更多配套。
- 对 CJS/动态 require 的处理,需要插件与约束(尽量写成 ESM)。
对比表格
| 维度 | Rollup | Webpack | Vite |
|---|---|---|---|
| 最适合 | 库/SDK | 应用(全能) | 应用(DX 优先) |
| tree-shaking | 强(ESM 优先) | 依赖配置与写法 | 生产同 Rollup |
| external 控制 | 强(库场景友好) | 也可做,但更偏应用 | 可做 |
| 多格式输出 | 一等公民 | 可做但较繁琐 | 生产可做(Rollup) |
我的选型口径:
- “被别人引入”的库:优先 Rollup(产物质量、体积、格式完整)。
- “自己运行”的应用:Webpack/Vite 更合适。
模拟问答
- [ ] Q1:tree-shaking 为什么有时不生效?
- 常见原因:
- 产物是 CJS(静态分析弱),或混用了动态
require。 - 包声明有副作用(未正确配置
sideEffects),Rollup 不敢删。 - 写法导致引用不可静态确定(比如
export *+ 动态访问)。
- 产物是 CJS(静态分析弱),或混用了动态
- 解决:保持 ESM、配置
moduleSideEffects、把副作用代码(polyfill/全局注入)显式隔离。
- 常见原因:
- [ ] Q2:为什么库构建要 external?
- 避免把
react/lodash打进包导致重复依赖、版本冲突与体积膨胀; - 让使用方用自己的依赖版本,符合生态预期。
- 避免把
手写代码区
一个“ESM + CJS 双产物 + external + d.ts”思路示例:
import typescript from '@rollup/plugin-typescript'
/** @type {import('rollup').RollupOptions} */
export default {
input: 'src/index.ts',
external: ['react', 'react-dom'],
plugins: [
typescript({
tsconfig: './tsconfig.json',
declaration: true,
declarationDir: 'dist/types',
rootDir: 'src'
})
],
output: [
{ file: 'dist/index.mjs', format: 'esm', sourcemap: true },
{ file: 'dist/index.cjs', format: 'cjs', sourcemap: true, exports: 'named' }
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
我的补充(Manual)
(不会被脚本覆盖:踩坑、细节、反例、排查路径)
复盘与反思(Learnings)
- 如果重做会怎么改?
面试官追问(面试官视角)
- [ ] 为什么选这个方案?替代方案为什么不选?
- [!] 最大一次事故/踩坑是什么?如何定位与回滚?
- [ ] 如果重做会怎么改?
