前端面试系列之工程化篇

如果对前端八股文感兴趣,可以留意公重号:码农补给站,总有你要的干货。

前端工程化

Webpack

  • 概念

    • 本质上,webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
  • 有哪些常见的Loader?你用过哪些Loader?

    • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
    • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
    • postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀
    • eslint-loader:通过 ESLint 检查 JavaScript 代码
    • tslint-loader:通过 TSLint检查 TypeScript 代码
    • vue-loader:加载 Vue.js 单文件组件
    • ts-loader: 将 TypeScript 转换成 JavaScript
    • babel-loader:把 ES6 转换成 ES5
    • ...
  • 有哪些常见的Plugin?你用过哪些Plugin?

    • html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)
    • define-plugin:定义环境变量 (Webpack4 之后指定 mode 会自动配置)
    • uglifyjs-webpack-plugin:不支持 ES6 压缩 (Webpack4 以前)
    • webpack-parallel-uglify-plugin: 多进程执行代码压缩,提升构建速度
    • mini-css-extract-plugin: 分离样式文件,CSS 提取为独立文件,支持按需加载 (替代extract-text-webpack-plugin)
    • speed-measure-webpack-plugin: 可以看到每个 Loader 和 Plugin 执行耗时 (整个打包耗时、每个 Plugin 和 Loader 耗时)
    • webpack-bundle-analyzer: 可视化 Webpack 输出文件的体积 (业务组件、依赖第三方模块)
    • happy-pack plugin
    • ...
  • Webpack构建流程简单说一下

    • 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数

    • 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译

    • 确定入口:根据配置中的 entry 找出所有的入口文件

    • 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理

    • 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系

    • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会

    • 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统

    • 总结版

      • 始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
      • 编译:从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件的内容,再找到该 Module 依赖的 Module,递归地进行编译处理
      • 输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中
  • loader 与 plugin

    • Loader 本质就是一个函数,在该函数中对接收到的内容进行转换,返回转换后的结果。因为 Webpack 只认识 JavaScript,所以 Loader 就成了翻译官,对其他类型的资源进行转译的预处理工作。

      • Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object,内部包含了 test(类型文件)、loader、options (参数)等属性。
    • Plugin 就是插件,基于事件流框架 Tapable,插件可以扩展 Webpack 的功能,在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

      • Plugin 在 plugins 中单独配置,类型为数组,每一项是一个 Plugin 的实例,参数都通过构造函数传入。
  • 热更新原理

    • Webpack 的热更新又称热替换(Hot Module Replacement),缩写为 HMR。 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。
    • HMR的核心就是客户端从服务端拉去更新后的文件,准确的说是 chunk diff (chunk 需要更新的部分),【实际上 WDS 与浏览器之间维护了一个 Websocket,当本地资源发生变化时,WDS 会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向 WDS 发起 Ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向 WDS 发起 jsonp 请求获取该chunk的增量更新。】
    • 后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由 HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。
  • Source Map 使用以及原理

    • source map 是将编译、打包、压缩后的代码映射回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试源码就需要 soucre map。

    • 线上环境一般有三种处理方案:

      • hidden-source-map:借助第三方错误监控平台 Sentry 使用
      • nosources-source-map:只会显示具体行数以及查看源代码的错误栈。安全性比 sourcemap 高
      • sourcemap:通过 nginx 设置将 .map 文件只对白名单开放(公司内网)
      • 注意:避免在生产中使用 inline- 和 eval-,因为它们会增加 bundle 体积大小,并降低整体性能。
  • 模块打包原理知道吗?

    • Webpack 实际上为每个模块创造了一个可以导出和导入的环境,本质上并没有修改 代码的执行逻辑,代码执行顺序与模块加载顺序也完全一致。
  • 文件指纹是什么?怎么用?

    • 文件指纹是打包后输出的文件名的后缀。

    • Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改

    • Chunkhash:和 Webpack 打包的 chunk 有关,不同的 entry 会生出不同的 chunkhash

    • Contenthash:根据文件内容来定义 hash,文件内容不变,则 contenthash 不变

    • 实例

      • 设置 output 的 filename,用 chunkhash。
      • 设置 MiniCssExtractPlugin 的 filename,使用 contenthash。
      • 设置file-loader的name,使用hash。
  • 如何保证各个loader按照预想方式工作?

    • 可以使用 enforce 强制执行 loader 的作用顺序,pre 代表在所有正常 loader 之前执行,post 是所有 loader 之后执行。(inline 官方不推荐使用)
  • 是否写过Loader?简单描述一下编写loader的思路?

    • Loader 支持链式调用,所以开发上需要严格遵循“单一职责”,每个 Loader 只负责自己需要负责的事情。

    • Loader 运行在 Node.js 中,我们可以调用任意 Node.js 自带的 API 或者安装第三方模块进行调用

    • Webpack 传给 Loader 的原内容都是 UTF-8 格式编码的字符串,当某些场景下 Loader 处理二进制文件时,需要通过 exports.raw = true 告诉 Webpack 该 Loader 是否需要二进制数据

    • 尽可能的异步化 Loader,如果计算量很小,同步也可以

    • Loader 是无状态的,我们不应该在 Loader 中保留状态

    • 使用 loader-utils 和 schema-utils 为我们提供的实用工具

    • 加载本地 Loader 方法

      • Npm link
      • ResolveLoader
  • 简单描述一下编写Plugin的思路?

    • webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在特定的阶段钩入想要添加的自定义功能。Webpack 的 Tapable 事件流机制保证了插件的有序性,使得整个系统扩展性良好。

      • compiler 暴露了和 Webpack 整个生命周期相关的钩子

      • compilation 暴露了与模块和依赖有关的粒度更小的事件钩子

      • 插件需要在其原型上绑定apply方法,才能访问 compiler 实例

      • 传给每个插件的 compiler 和 compilation对象都是同一个引用,若在一个插件中修改了它们身上的属性,会影响后面的插件

      • 找出合适的事件点去完成想要的功能

        • emit 事件发生时,可以读取到最终输出的资源、代码块、模块及其依赖,并进行修改(emit 事件是修改 Webpack 输出资源的最后时机)
        • watch-run 当依赖的文件发生变化时会触发
      • 异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

ESLint

  • 概念

    • ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具,使用它可以避免低级错误和统一代码的风格。如果每次在代码提交之前都进行一次eslint代码检查,就不会因为某个字段未定义为undefined或null这样的错误而导致服务崩溃,可以有效的控制项目代码的质量。
  • 原理

    • ESLint 使用 Espree 解析 JavaScript。
    • ESLint 使用 AST 去分析代码中的模式。
    • ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则。

Babel

  • 概念

    • Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
  • 原理

    • 大多数JavaScript Parser遵循 estree 规范,Babel 最初基于 acorn 项目(轻量级现代 JavaScript 解析器) Babel大概分为三大部分:

      • 解析:将代码转换成 AST
      • 词法分析:将代码(字符串)分割为token流,即语法单元成的数组语法分析:分析token流(上面生成的数组)并生成 AST
    • 转换:访问 AST 的节点进行变换操作生产新的 AST

      • Taro就是利用 babel 完成的小程序语法转换
    • 生成:以新的 AST 为基础生成代码

TypeScript

  • 概念
  • 原理

单元测试 Jest

  • 有没有使用过?

包管理器

  • npm run start 的整个过程?

    • 运行 npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
    • 没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx就是安装到到全局目录;
    • 如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。
  • npm/yarn/pnpm

    • pnpm 通过巧妙硬链接 + 软链接结合的方式完全实现了依赖树结构的 node_modules,并且严格遵循了 Node.js 的模块解析标准,解决了幻影依赖和 npm 分身的问题。并且通过全局只保存一份在 ~/.pnpm-store 的方式,在不同的项目中进行 install 的速度也会变得更快,也解决了磁盘空间占用的问题
  • npm install 的执行过程

    • npm 模块安装机制

      • 发出npm install命令
      • 查询 node_modules 目录之中是否已经存在指定模块
      • 若存在,不再重新安装
      • 若不存在
      • npm 向 registry 查询模块压缩包的网址
      • 下载压缩包,存放在根目录下的.npm目录里
      • 解压压缩包到当前项目的 node_modules 目录
    • npm 实现原理

Git

  • rebase 和 merge 的区别?

    • merge

      • 通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来
      • 其实是一种非破坏性的操作,对现有分支不会以任何方式被更改,但是会导致历史记录相对复杂
    • rebase

      • rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交
      • 主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge所需的不必要的合并提交

CSS 工程化

  • Sass、Less 是什么?为什么要使用他们?

    • 它们都是 CSS 预处理器,是 CSS 上的一种抽象层。它们是一种特殊的语法/语言,最终编译成 CSS。
    • 例如 Less 是一种动态样式语言,将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数。
    • 为什么要使用它们?
    • 结构清晰,便于扩展。 可以方便地屏蔽浏览器私有语法差异。封装对浏览器语法差异的重复处理, 减少无意义的机械劳动。
    • 可以轻松实现多重继承。 完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。
  • CSS预处理器/后处理器是什么?为什么要使用它们?

    • 预处理器, 如:less,sass,stylus,用来预编译sass或者less,增加了css代码的复用性。层级,mixin, 变量,循环, 函数等对编写以及开发UI组件都极为方便。

    • 后处理器, 如: postCss,通常是在完成的样式表中根据css规范处理css,让其更加有效。目前最常做的是给css属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。

    • css预处理器为css增加一些编程特性,无需考虑浏览器的兼容问题,可以在CSS中使用变量,简单的逻辑程序,函数等在编程语言中的一些基本的性能,可以让css更加的简洁,增加适应性以及可读性,可维护性等。

    • 使用原因:

      • 结构清晰, 便于扩展
      • 可以很方便的屏蔽浏览器私有语法的差异
      • 可以轻松实现多重继承
      • 完美的兼容了CSS代码,可以应用到老项目中
  • 对 CSS 工程化的理解

    • 解决的问题

      • 宏观设计:CSS 代码如何组织、如何拆分、模块结构怎样设计?
      • 编码优化:怎样写出更好的 CSS?
      • 构建:如何处理我的 CSS,才能让它的打包结果最优?
      • 可维护性:代码写完了,如何最小化它后续的变更成本?如何确保任何一个同事都能轻松接手?
    • 三个方向

      • 预处理器:Less、 Sass 等;
      • 重要的工程化插件: PostCss;
      • Webpack loader 等 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/190762.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 反射工具箱:带你领略不一样的反射设计思路

反射是 Java 世界中非常强大、非常灵活的一种机制。在面向对象的 Java 语言中,我们只能按照 public、private 等关键字的规范去访问一个 Java 对象的属性和方法,但反射机制可以让我们在运行时拿到任何 Java 对象的属性或方法。 有人说反射打破了类的封装…

企业微信开发教程一:添加企微应用流程图解以及常见问题图文说明

最近在前辈的基础上新添加了一个企微应用,过程中遇到了一些卡点,这里一一通过图片标注与注释的方式记录一下,希望能给后来人提供一些清晰明了的帮助,话不多说,大家直接看图吧。 (文中包括一些本项目独有的配…

matlab背景部分最小化算法人脸检测

1、内容简介 略 18-可以交流、咨询、答疑 matlab背景部分最小化算法人脸检测 2、内容说明 matlab人脸检测 matlab人脸检测,背景部分最小化算法 3、仿真分析 略. 4、参考论文 略 链接:https://pan.baidu.com/s/1yQ1yDfk-_Qnq7tGpa23L7g 提取码&…

双H桥直流马达步进电机驱动芯片SS8833E

由工采网代理的率能SS8833E是一款适用于有刷直流或双极步进电机的集成电机驱动芯片;采用eTSSOP16封装;该器件集成了两个PNMOS H桥和电流调节电路;电机输出电流可以由外部脉宽调制器(PWM)或内部PWM电流控制器控制。 工…

家庭安全计划 挑战赛| 溺水预防

溺水预防 从了解到行动 家庭安全计划 | 少年急救官 地震避险逃生该怎么做? 起火了该如何应对? 哪些行为容易导致溺水? 家庭风险隐患有哪些? 家庭逃生演练四步骤你会吗? 国际救助儿童会(英国&#xff…

虚拟化服务器+华为防火墙+kiwi_syslog访问留痕

一、适用场景 1、大中型企业需要对接入用户的访问进行记录时,以前用3CDaemon时,只能用于小型网络当中,记录的数据量太大时,本例采用破解版的kiwi_syslog。 2、当网监、公安查到有非法访问时,可提供基于五元组的外网访…

kubernetes--Pod进阶

目录 一、资源限制: 1. 资源限制的两种规范: 2. Pod 和 容器 的资源请求和限制: 3. CPU 资源单位: 4. 内存资源单位 : 5. 资源限制示例: 二、健康检查:探针(Probe) 1. 探…

Git Gui的使用及ssh协议-IEDA使用git

目录 一.Git Gui的使用 二.ssh协议 2.1 什么是ssh key 2.2 配置用户名和邮箱(如果已经配置,就跳过) 2.3 生成(或删除)秘钥 ​编辑 2.4 远程仓库绑定公钥 三.IEDA使用git 3.1 idea配置Git 3.2 项目上传Git 3.3 演示 一.Git Gu…

python打包部署脚本

linux可使用expect来实现自动交互,windows想要写出同样的功能脚本,只能使用python或者安装ActiveTcl 1、安装python Microsoft Store搜索python直接安装,默认会直接添加到环境变量https://www.python.org/官网下载,点击安装时会提…

lua 时间差功能概略

简介 在进行程序设计过程中,经常需要对某些函数、某些程序片断从开始运行到运行结束所耗费的时间进行一些量化。这种量化实际上就是计算时间差。 获取函数耗时情景如下: function time_used() --开始计时-- do something at here. --结束计时--时间差&…

tomcat下载与使用教程

1. tomcat下载 官网:https://tomcat.apache.org/ 镜像地址:https://mirrors.huaweicloud.com/apache/tomcat/ 1、选择一个版本下载,官网下载速度缓慢,推荐镜像 2、对压缩包进行解压,无需进行安装,解压放…

Java 算法篇-深入了解单链表的反转(实现:用 5 种方式来具体实现)

🔥博客主页: 小扳_-CSDN博客 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 单链表的反转说明 2.0 单链表的创建 3.0 实现单链表反转的五种方法 3.1 实现单链表反转 - 循环复制(迭代法) 3.2 实现单链表反转 - 头插法 3…

OpenGL_Learn10(颜色)

1. 颜色 我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的(Reflected)颜色。换句话说,那些不能被物体所吸收(Absorb)的颜色(被拒绝的颜色)就是我们能够感知到的物体的颜色。例如,太阳光…

计算机提示“找不到emp.dll,无法继续执行代码”,这几种解决办法都可以解决

在计算机使用过程中,我们可能会遇到各种问题,其中之一就是系统文件丢失。emp.dll文件是Windows操作系统中的一个重要组件,如果丢失或损坏,可能会导致系统运行不稳定甚至无法正常启动。本文将详细介绍emp.dll文件丢失恢复的4个方法…

【中间件篇-Redis缓存数据库04】Redis底层原理持久化、分布式锁

Redis底层原理 持久化 Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。 RDB RDB持久化是把当…

C语言--1,5,10人民币若干,现在需要18元,一共有多少种?

今天小编给大家分享一下穷举法的一道典型例题 一.题目描述 1,5,10人民币若干,现在需要18元,一共有多少种? 二.思路分析 总共有18块钱,设1元有x张,5元有y张,10元有z张,则有表达式:x5y10z18,穷举法最重要的…

模型部署:量化中的Post-Training-Quantization(PTQ)和Quantization-Aware-Training(QAT)

模型部署:量化中的Post-Training-Quantization(PTQ)和Quantization-Aware-Training(QAT) 前言量化Post-Training-Quantization(PTQ)Quantization-Aware-Training(QAT) 参…

AIGC|如何将Milvus集成到LangFlow中?详细代码演示!

目录 一、基本介绍 二、修改langflow代码使其支持milvus 三、效果演示 langflow是一个LangChain UI,它提供了一种交互界面来使用LangChain,通过简单的拖拽即可搭建自己的实验、原型流。通过在langflow中引入Milvus,用户可以更方便地存储和…

【Java 进阶篇】JQuery DOM操作:通用属性操作的绝妙魔法

在前端的舞台上,JQuery犹如一位魔法师,为我们展现了操纵HTML元素的奇妙技巧。而在这个技巧的精妙组成中,通用属性操作是一门绝妙的魔法。在本篇博客中,我们将深入研究JQuery DOM操作中的通用属性操作,揭示这段魔法的神…

业务出海之服务器探秘

这几年随着国内互联网市场的逐渐饱和,越来越多的公司加入到出海的行列,很多领域都取得了很不错的成就。虽然出海可以获得更加广阔的市场,但也需要面对很多之前在国内可能没有重视的一些问题。集中在海外服务器的选择维度上就有很大的变化。例…