面试题名词解析一

第一部分

这些问题都是前端工程化的核心知识。咱们不用那些晦涩的术语,我用最通俗的大白话来给你讲明白,并帮你建立起它们之间的联系。

1. Webpack 插件自定义:就像给"流水线"加个"机器人"

​核心思想:​​ Webpack 就像一个产品打包流水线。源代码(零件)从入口进去,经过一系列处理(组装、加工),最后变成打包好的文件(成品)从出口出来。

  • ​Loader(加载器)​ ​:流水线上的​​工人​ ​。他只会干一种活儿,比如把 .less文件加工成 .css文件。他处理的是"单个产品"。

  • ​Plugin(插件)​ ​:流水线上的​​智能机器人​ ​。它不直接加工产品,而是在​​特定的时机​​干预整个流水线。比如,在流水线启动时清空仓库(输出目录),或者在所有产品打包好后,自动把它们压缩一下。

​如何自定义一个 Plugin?​

很简单,就是一个​​能监听流水线"事件"的 JavaScript 函数​​。

复制代码
// 1. 定义一个"机器人"(插件类)
class MyCleanPlugin {
  // 2. 给它一个"工作手册"(apply方法)
  apply(compiler) {
    // 3. 告诉它监听"流水线启动"这个事件
    compiler.hooks.run.tap('MyCleanPlugin', (compilation) => {
      // 4. 当事件发生时,执行它的任务,比如清空输出目录
      console.log('流水线要开始啦!我先去打扫一下仓库!');
      // ... 实际删除文件的代码
    });
  }
}

// 在 webpack.config.js 里引入这个"机器人"
module.exports = {
  plugins: [
    new MyCleanPlugin()
  ]
};

​一句话总结:​​ 自定义 Plugin 就是写一个能监听 Webpack 打包过程中各种"事件"(比如开始、结束、生成资源时),并在这些时间点执行自定义任务的程序。


2. Vite 编译原理:从"预制菜"到"即点即做"

​核心思想:​​ 对比 Webpack 和 Vite 的启动速度。

  • ​Webpack("预制菜"模式)​ ​:你请客吃饭,​​必须等所有菜都做好、打包成盒饭​​,客人才能开始吃。所以项目越大,启动越慢。

  • ​Vite("即点即做"模式)​​:你请客吃饭,告诉客人"随便点"。客人点一个菜(请求一个文件),厨房(Vite 开发服务器)才立刻做一份,马上端上来。没点的菜就不做。

​Vite 怎么做到的?​

  1. ​依赖(node_modules)​ ​:这些是"凉菜",基本不变。Vite 用 ​​Esbuild​​(一个超快的 Go 语言打包工具)提前把它们做好放冰箱,客人一点,立马就能上。

  2. ​源码(你的代码)​ ​:这些是"热炒",经常变。浏览器不能直接跑 import Vue from 'vue'这种语法。Vite 的服务器会在你请求时,​​按需把代码转换一下​ ​(比如把 import转换成浏览器认识的路径),再返回给浏览器。

​一句话总结:​​ Vite 利用浏览器原生支持 ES 模块的能力,在开发环境下"按需编译",只编译你当前页面需要的文件,所以启动速度和热更新极快。


3. AST 转换:给代码做"X光+外科手术"

​核心思想:​​ 想象一下,你要把一本中文小说翻译成英文。

  • ​普通查找替换​​:就像用 Word 的查找替换功能。你只能找固定的词,比如把"苹果"换成"apple"。但如果"苹果"指的是公司名,你就换错了,很不精确。

  • ​AST 转换​ ​:就像先让一个语言专家把整本小说的​​语法结构​​分析出来(做 X 光)。他会告诉你:"看,这里是一个主语'我',这里是一个谓语'吃',这里是一个宾语'苹果(指水果)'。" 有了这个结构树(AST),你就可以非常精确地操作了,比如"把所有'吃水果'的宾语换成'香蕉'"。

​在前端领域的应用:​

  • ​Babel​ ​:把新的 JS 语法(如 ES6)转换成旧浏览器能识别的语法。它就是先解析成 AST,然后修改 AST 树(比如把 箭头函数节点改成 function节点),最后再生成新的代码。

  • ​Eslint / Prettier​​:检查代码风格、格式化。也是通过 AST 来理解你的代码结构。

  • ​TypeScript 编译器​​:也是基于 AST。

​一句话总结:​​ AST 是把代码从一串"文本"转换成有结构的"树",让我们能精准地分析和修改代码,而不是用原始的字符串替换那种笨办法。


4. Tree Shaking(摇树优化):摘掉"枯树叶"

​核心思想:​​ 你的项目像一棵树,上面结满了各种功能的"果子"(模块、函数)。但最后打包时,你其实只吃了其中一部分,很多果子是烂的或者没用的。

  • ​没有 Tree Shaking​​:把整棵树(包括所有枯枝烂叶)都打包进篮子里,最终文件很大。

  • ​有 Tree Shaking​ ​:打包工具(Webpack / Vite / Rollup)会用力"摇一摇"这棵树,把那些​​明确定义了导出,但却没有被任何地方导入​​的"死代码"(枯树叶)摇下来扔掉。

​关键条件(ES Module 语法):​

  • 你必须使用 import/export这种模块语法,因为它是​​静态的​​,打包工具在打包前就能分析出依赖关系。

  • 如果你用 module.exports(CommonJS),它是​​动态的​​(比如可以在条件语句里 require),工具分析起来很困难,所以很难摇掉。

​一句话总结:​​ Tree Shaking 是生产环境打包时,自动移除你项目中那些没有被使用到的代码,以减少打包体积的优化技术。


它们之间的联系(非常重要!)

现在,我们把它们串起来看一个完整的流程:

  1. 你用 Vite 创建一个项目,它利用​​按需编译​​原理,让你获得闪电般的启动速度。

  2. 你写代码时,Vite 底层可能用 ​​AST 转换​ ​(通过 Esbuild 或 SWC)来快速处理你的 .ts.jsx文件。

  3. 当你用 npm run build打包时,Vite 底层切换到 Rollup(和 Webpack 是同类工具)。

  4. Rollup 会进行 ​​Tree Shaking​​,摇掉所有没用到的代码。

  5. 在打包过程中,你可以通过自定义 ​​Webpack/Rollup 插件​​(原理相通)来干预打包过程,比如在打包完成后生成一个打包报告。

它们不是孤立的知识点,而是一个现代前端构建流水线上的不同环节,共同协作来提升你的开发体验和产出的代码质量。

第二部分

这些都是现代前端工程化和团队协作的核心概念。我用最生活化的比喻帮你把它们讲清楚,并串联起来。

1. MonoRepo(单体仓库):像是一个"大商场"

​通俗理解:​

  • ​传统方式(MultiRepo)​ ​:你家附近有10家独立的​​专卖店​​。买衣服去A店,买电器去B店,每家店都有自己的会员卡、营业时间,管理很分散。

  • ​MonoRepo方式​ ​:所有这些店都开在一个​​大型购物中心​​里。共享停车场、安保系统、中央空调,你可以一口气逛完所有店。

​在前端中的体现:​

  • 把公司所有相关的前端项目(主站、后台、组件库、工具函数)都放在​​同一个Git仓库​​里管理。

  • ​好处​​:

    • ​共享配置​​:一套ESLint、TypeScript配置所有项目都用。

    • ​代码复用​​:改一个公共组件,所有用到它的项目立即生效。

    • ​依赖统一​​:避免不同项目用了不同版本的React导致奇怪bug。

​常用工具:​​ pnpm workspace、Turborepo、Lerna。


2. CI/CD(持续集成/持续部署):像是"全自动智能厨房"

​通俗理解:​

想象你要开一家餐馆:

  • ​传统开发​​:厨师(开发者)做好菜,自己尝一口就端给客人。容易出错。

  • ​CI/CD​ ​:你建了一个​​全自动智能厨房​​:

    • ​CI(持续集成)​ ​:厨师每切好一道菜,就有​​自动化机器​​自动检查:咸淡是否合适?有没有头发?摆盘好看吗?(相当于代码检查、测试)

    • ​CD(持续部署)​ ​:检查通过后,​​机器人服务员​​自动把菜端到客人桌上(自动部署到服务器)。

​在前端中的流程:​

  1. 你写完代码,push到GitHub

  2. ​CI阶段​​:自动安装依赖 → 运行代码检查 → 跑测试用例 → 打包构建

  3. ​CD阶段​​:如果CI通过,自动部署到测试环境/生产环境

​好处​​:避免"在我电脑上是好的"这种问题,交付又快又稳。


3. 依赖分析:像是"给行李箱做减肥"

​通俗理解:​

你要去旅行,行李箱塞得太满:

  • ​依赖分析工具​ ​就像个​​智能秤​​,告诉你:

    • 哪件衣服最占地方?(哪个依赖包体积最大)

    • 有没有带根本不会穿的衣服?(未使用的代码)

    • 能不能用更轻便的替代品?(更小的替代库)

​在前端中的体现:​

  • webpack-bundle-analyzer等工具生成一张图,清楚看到:

    • React占了多少体积

    • 某个组件库是不是太大了

    • 有没有不小心把整个Lodash都打包进来了

​目的​​:优化打包体积,让网站加载更快。


4. 分支策略:像是"交通规则"

​通俗理解:​

团队协作开发就像多人一起开车:

  • ​没有规则​​:大家都随便开,肯定撞车(代码冲突)。

  • ​好的分支策略​​:制定清晰的交通规则:

    • ​主干道(main/master)​​:永远稳定可通行的代码

    • ​辅路(develop)​​:正在开发的功能汇集地

    • ​临时车道(feature/xxx)​​:每个人开发新功能的路

​常见策略:Git Flow​

  • main分支:永远是可上线的稳定版本

  • develop分支:日常开发集成

  • feature/登录页分支:张三开发登录功能

  • feature/支付页分支:李四开发支付功能

  • 功能完成后,合并到develop,测试OK再合并到main

​好处​​:井井有条,减少冲突,随时可上线。


5. GitHub Actions:像是"你的私人自动化助理"

​通俗理解:​

GitHub Actions就是GitHub提供的​​机器人助理​​,你可以对它说:

"小G,以后只要有人往main分支推代码,你就自动:

  1. 安装依赖

  2. 运行测试

  3. 打包项目

  4. 部署到服务器"

​实际例子:​

你在项目根目录放个 .github/workflows/deploy.yml文件:

复制代码
name: 自动部署
on:
  push:
    branches: [ main ] # 监听main分支的push

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 拉取代码
        uses: actions/checkout@v3
        
      - name: 安装Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          
      - name: 安装依赖
        run: npm ci
        
      - name: 运行测试
        run: npm test
        
      - name: 打包构建
        run: npm run build
        
      - name: 部署到服务器
        run: echo "这里写部署脚本"

它们如何协同工作?(完整故事线)

现在,我们把这些概念串成一个完整的工作流:

  1. ​环境设置​ ​:你们团队决定用 ​​MonoRepo​​(大商场模式)管理所有前端项目。

  2. ​日常开发​ ​:你从main分支拉出一个 ​​feature/新首页​​ 分支(遵守交通规则),开始 coding。

  3. ​提交代码​ ​:你完成开发后,发起Pull Request,想把代码合并回main分支。

  4. ​自动化触发​ ​:​​GitHub Actions​​(你的机器人助理)检测到PR创建,立即开始工作:

    • 运行 ​​CI流程​​:安装依赖、检查代码、跑测试

    • 执行 ​​依赖分析​​:检查打包体积,确保没有引入过大的依赖

    • 如果全部通过,自动部署到测试环境(​​CD流程​​)

  5. ​代码合并​ ​:同事review通过后,合并到main分支,自动部署到生产环境。

​最终效果​​:你们团队能够高效、安全、自动化地交付前端功能。

这些都是现代前端工程师需要掌握的重要工程化概念,掌握了它们,你就能在团队中发挥更大的价值!

第三部分

这些都是前端性能优化和现代渲染架构的核心概念。我继续用最生活化的比喻帮你理解。

1. Long Task(长任务)分析:像是"结账排长队"

​通俗理解:​

想象你在超市购物:

  • ​正常情况​​:收银台处理每个顾客很快,队伍一直在移动,你很满意。

  • ​Long Task​ ​:突然有个顾客推了满满三大车商品,在收银台慢慢结账(一个Long Task)。​​后面所有人都得等着​​,队伍完全不动,你很烦躁。

​在前端中的体现:​

  • 浏览器的主线程就像​​只有一个收银台​​。

  • 任何执行超过 ​​50毫秒​​ 的JavaScript任务就是"Long Task"。

  • 在这期间,页面会​​卡顿​​:点击没反应、动画掉帧、滚动不流畅。

​如何优化:​

  • ​拆分大任务​​:让"三大车商品"分成小批结账。

  • ​Web Worker​​:开个"专用结账通道"处理重计算。

  • 用Chrome Performance工具找到是哪个函数执行太久。

​一句话总结:​​ Long Task是会阻塞页面响应的长JavaScript任务,需要找到并优化它们。


2. 懒加载(Lazy Load):像是"自助餐按需上菜"

​通俗理解:​

传统网站加载像​​中式桌餐​​:不管你能不能吃完,所有菜一次性上齐,等菜上齐才能开饭(首屏慢)。

懒加载像​​自助餐​​:先上几个主菜(首屏内容),其他菜放在后厨。只有当你走到相应区域想看新菜时,才现场制作端上来。

​在前端中的体现:​

  • ​图片懒加载​ ​:页面滚动到附近时,才加载图片的src

  • ​代码分割​​:只有用户点击某个功能时,才下载对应的JavaScript代码。

  • ​路由懒加载​​:切换到某个页面时,才加载该页面的资源。

​好处:​​ 首屏加载飞快,节省带宽。

复制代码
// 图片懒加载示例
<img loading="lazy" src="placeholder.jpg" data-src="real-image.jpg">
// 当图片进入视口时,才把data-src换成真正的src

3. SSR Hydration(注水):像是"泡面变现煮"

​通俗理解:​

  • ​传统SPA(客户端渲染)​ ​:端上来一碗"方便面饼+调料包"(原始的JS+数据),客人要自己加水泡3分钟才能吃。​​首屏白屏时间长​​。

  • ​SSR(服务端渲染)​ ​:在后厨就把面泡好,直接端一碗​​热腾腾的泡面​​给客人。客人立即能吃到(首屏快)。

  • ​Hydration(注水)​ ​:但这碗泡面还不能加辣酱、换配料(没交互性)。Hydration就是当着客人的面,​​给这碗面"注入灵魂"​​:加上筷子、辣酱包,让它变成可以随意定制的一碗面(可交互的SPA)。

​技术流程:​

  1. 服务端渲染出完整的HTML(热泡面)

  2. 浏览器直接展示(立即能吃)

  3. JavaScript加载完成后,将事件绑定等"注入"到现有HTML上(加辣酱、加互动)

​挑战:​​ 如果注水过程太慢(Hydration Long Task),页面会有一段"可看不可点"的尴尬期。


4. 首屏时间优化:像是"外卖送达的完整体验"

​通俗理解:​

点外卖时,你关心的是:

  • ​多久能先吃上点东西​​(首屏内容)

  • ​外卖小哥的态度​​(加载过程中的体验)

  • ​最后是不是所有菜都齐了​​(完全可交互)

​核心优化手段:​

  1. ​减少"打包体积"​​:让外卖盒子小一点,送得快一点

    • Tree Shaking去掉没用的代码

    • 图片压缩、代码压缩

  2. ​建立"配送前置仓"(CDN)​​:把资源放在离用户近的地方

  3. ​"预加载"技巧​​:

    • ​预连接​ ​:提前跟餐厅打好电话(<link rel="preconnect">

    • ​预加载​ ​:让厨师先做复杂的菜(<link rel="preload">

  4. ​优化"关键渲染路径"​​:

    • 优先加载首屏需要的CSS/JS

    • 非关键的CSS/JS延后加载

  5. ​使用"更快的烹饪方式"​​:

    • SSR服务端渲染(提前做好)

    • 静态站点生成(预制菜)


它们如何协同工作?(完整性能优化故事)

假设你要优化一个电商网站:

  1. ​首要目标​ ​:优化​​首屏时间​​,让用户尽快看到商品列表。

  2. ​采用SSR​​:服务端直接渲染出商品HTML,避免白屏。

  3. ​但SSR有代价​​:服务端渲染的HTML很大,需要优化:

    • 图片使用​​懒加载​​,首屏只加载可见区域的图片。

    • 代码分割,只发送首屏需要的JS。

  4. ​SSR Hydration时​ ​:密切关注​​Long Task​​,确保注水过程不卡顿。

    • 如果发现商品列表渲染是Long Task,就拆分渲染或使用虚拟滚动。
  5. ​持续监控​​:用Lighthouse等工具测量首屏时间,用Performance面板分析Long Task。

​最终效果​​:用户打开网页立即看到内容(SSR),滚动时图片渐次加载(懒加载),整个页面交互流畅无卡顿(无Long Task)。

这些概念都是现代前端性能优化的核心武器,掌握了它们,你就能打造出体验极佳的Web应用!

相关推荐
会跑的葫芦怪2 小时前
Web3开发中的前端、后端与合约:角色定位与协作逻辑
前端·web3·区块链
江城开朗的豌豆2 小时前
TypeScript泛型:让类型也"通用"的魔法
前端·javascript
江城开朗的豌豆2 小时前
TypeScript函数:给JavaScript函数加上"类型安全带"
前端·javascript
凌览2 小时前
Node.js + Python 爬虫界的黄金搭档
前端·javascript·后端
Java 码农2 小时前
vue 使用vueCli 搭建vue2.x开发环境,并且指定ts 和less
前端·vue.js·less
欧阳码农2 小时前
AI提效这么多,为什么不试试自己开发N个产品呢?
前端·人工智能·后端
chenbin___2 小时前
Omit<>的用法
开发语言·前端·javascript
嫂子的姐夫2 小时前
21-webpack介绍
前端·爬虫·webpack·node.js
IT_陈寒2 小时前
SpringBoot 3.x 中被低估的10个隐藏特性,让你的开发效率提升50%
前端·人工智能·后端