前端面试系列之工程化篇

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

前端工程化

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.mzph.cn/news/138302.shtml

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

相关文章

供暖系统如何实现数据远程采集?贝锐蒲公英高效实现智慧运维

山西某企业专注于暖通领域,坚持为城市集中供热行业和楼宇中央空调行业提供全面、专业的“智慧冷暖”解决方案。基于我国供热行业的管理现状,企业成功研发并推出了可将能源供应、管理与信息化、自动化相融合的ICS-DH供热节能管理系统。 但是,由…

openGauss学习笔记-119 openGauss 数据库管理-设置数据库审计-设置文件权限安全策略

文章目录 openGauss学习笔记-119 openGauss 数据库管理-设置数据库审计-设置文件权限安全策略119.1 背景信息119.2 数据库程序目录及文件权限119.3 建议 openGauss学习笔记-119 openGauss 数据库管理-设置数据库审计-设置文件权限安全策略 119.1 背景信息 数据库在安装过程中…

PLC开放式以太网通信网络状态查看工具netstat

在进行PLC的开放式以太网通信时,为了查看网络状态我们可以利用ping这个强有力的工具,还可以使用netstat这个工具。 博途PLC开放式以太网通信 UDP通信 博途PLC 1200/1500PLC开放式以太网通信TSEND_C通信(UDP)_RXXW_Dor的博客-CSDN博客文章浏览阅读1.7k次。开放式TSEND_C通信…

微信小程序和H5之间互相跳转、互相传值

微信小程序和内嵌 H5 之间来回跳转,来回交互。 1 微信小程序跳转 H5 1.2. web-view 微信小程序官方提供了 web-view 组件来实现微信小程序跳转到 H5 页面,实现的方式也很简单,具体实现方式如下: 1、新建一个页面用来单独存放 we…

SSL证书申请安全审核失败?

随着HTTPS普及,申请安装使用SSL证书成为了我们的必备项。但这个SSL证书申请过程中,遇到问题也是不少。今天我们来浅了解一下SSL证书为什么会出现安全审核失败? SSL证书申请会出现安全审核失败的情况可能是以下原因: 域名验证不通…

华为防火墙二层透明模式下双机热备主备备份配置(两端为交换机)

这种模式只能是主备备份模式,不能是负载分担,因为会有环路。 故障切换是,如果主故障,主设备所有接口全都会down状态,然后再up一次,用于改变mac转发表。 FW1 hrp enable hrp interface GigabitEthernet1/0…

python实现炒股自动化,个人账户无门槛量化交易的开始

本篇作为系列教程的引子,对股票量化程序化自动交易感兴趣的朋友可以关注我,现在只是个粗略计划,后续会根据需要重新调整,并陆续添加内容。 股票量化程序化自动交易接口 很多人在找股票个人账户实现程序化自动交易的接口&#xff0…

Coding面试题之手写线程池

原理图 JDK线程池原理 实现代码 1.线程类&#xff08;PoolThread&#xff09; 这个类用于执行任务队列中的任务。 public class PoolThread extends Thread {private final Queue<Runnable> taskQueue;private boolean isStopped false;private long lastTaskTime …

人工智能基础_机器学习022_使用正则化_曼哈顿距离_欧氏距离_提高模型鲁棒性_过拟合_欠拟合_正则化提高模型泛化能力---人工智能工作笔记0062

然后我们再来看一下,过拟合和欠拟合,现在,实际上欠拟合,出现的情况已经不多了,欠拟合是 在训练集和测试集的准确率不高,学习不到位的情况. 然后现在一般碰到的是过拟合,可以看到第二个就是,完全就把红点蓝点分开了,这种情况是不好的, 因为分开是对训练数据进行分开的,如果来…

C语言 预处理详解

目录 1.预定义符号 2.#define 2.1#define 定义标识符 2.2#define 定义宏 2.3#define 替换规则 2.4#和## 2.4.1# 的作用 2.4.2## 的作用 2.5 带有副作用的宏参数 2.6宏和函数的对比 对比 **2.7内联函数 2.8命名约定 3.#undef **4.命令行定义 5.条件编译 常…

npm install 报错 chromedriver 安装失败的解决办法

npm install chromedriver --chromedriver_cdnurlhttp://cdn.npm.taobao.org/dist/chromedriver

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:

错误描述如下所示&#xff1a; 我们将错误拉到最下面如下所示为导致异常的原因&#xff1a; Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type com.example.reviewmybatisplus.Service.UserService available: expec…

双编码器构建机器人零力拖动/导纳控制思路

前言 这篇博客主要记录昨日与实验室大佬针对UR5机器人拖动示教功能实现的思路。由于本人并非主攻力控方面。直到昨天在做实验的时候&#xff0c;与力控组的大佬讨论过后才了解UR机器人实现导纳控制的思路。 关于导纳控制/零力拖动 导纳控制与阻抗控制单从字面去理解很容易记…

PHP编写采集药品官方数据的程序

在 PHP 中编写爬虫程序&#xff0c;首先我们需要引入一些必要的库&#xff0c;如 curl 和 file_get_contents。然后&#xff0c;我们需要设置爬虫ip信息&#xff0c;以便我们可以从指定的爬虫ip服务器上获取数据。 // 引入必要的库 require_once curl.php;// 设置爬虫ip信息 $p…

CMake教程--QT项目使用CMake

CMake教程--QT项目使用CMake Chapter1 CMake教程--QT项目使用CMake1. Basic Cmake Based Project2. Executable VS Library3. Every module has its own CMakeList.txt in its folder3.1 不推荐的做法&#xff1a;3.2 推荐的做法 4. 强制以Debug, Release, RelWithDebInfo, Min…

[游戏中的图形学实时渲染技术] Part1 实时阴影技术

原理篇&#xff1a; 常见的渲染方程如下&#xff1a; &#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;) &#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;) ∫Ω&#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;)&#xf…

Hls学习(一)

1&#xff1a;CPU、DSP、GPU都算软件可编程的硬件 2&#xff1a;dsp在递归方面有所减弱&#xff0c;在递归方面有所增强&#xff0c;比如递归啊等&#xff0c;GPU可以同时处理多个进程&#xff0c;对于大块数据&#xff0c;流处理比较适用 3&#xff1a;为了提高运算量处理更多…

暖手宝+充电宝设计方案 可实现快速升温和充电 低成本充电电流可选

充电暖手宝因为它的便携性&#xff0c;既能供暖又能当充电宝使用而备受人们喜爱。是冬天暖手供暖的必备神器。 目前&#xff0c;市场常见的暖手宝大致有三个类型&#xff0c;分别是加热水的热水袋、通过化学反应放热的铁粉袋子和锂电供电的智能暖手宝。与常见的暖手宝不同&…

巨好用又实用的18款3dMax插件!

3dMax是一款功能强大的 3D 软件&#xff0c;具有建模、动画、粒子动力学等许多强大功能。但并不是每个人都能有效地利用max的每一个功能&#xff0c;例如&#xff0c;很多人发现3dmax粒子流太难使用&#xff0c;3ds max蒙皮工具也是如此。 这让我们一些专业的开发公司或个人和…

Python学习笔记--自定义类型的枚举

三、自定义类型的枚举 但有些时候我们需要控制枚举的类型&#xff0c;那么我们可以 Enum 派生出自定义类来满足这种需要。通过修改上面的例子&#xff1a; #!/usr/bin/env python3 # -*- coding: UTF-8 -*- from enum import Enum, uniqueEnum(Month, (Jan, Feb, Mar, Apr, M…