Webpack面试题总结

news2025/2/24 16:39:17

说说你对webpack的理解?解决了什么问题?

 webpack最初的目标是实现前端项目模块化,目的在于更高效的管理和维护项目中的每一个资源

模块化:

最早的时候,我们通过文件划分的形式实现模块化,也就是将每个功能及其相关状态数据各自单独放在不同的js文件中

约定每个文件就是一个独立的模块,然后把js文件引入到页面,一个script标签对应一个模块,然后调用模块化的成员,这种的弊端非常的明显,模块都在全局中工作,大量的模块成员污染了环境,模块和模块之间没有依赖关系,维护起来困难,没有私有空间

随着命名空间的出现,规定每个模块只能暴露一个全局对象,然后模块的内容都挂载在这个对象中,但是这种方式也没有解决第一种方式的依赖等问题

再后来,我们使用立即执行函数为模块提供私有空间,通过参数的形式作为依赖声明,但是仍然存在一定的问题,通过script标签引入页面,这些模块的加载不受控制,时间久了维护起来也很困难

理想的解决方案就是在页面引入一个js入口文件,其余用到的模块可以通过代码控制,按需加载起来

问题:

现代前端开发变得越来越复杂,我们在开发过程中可能会遇到的问题:

  • 需要通过模块化的方式来开发
  • 使用一些高级的特性来加快我们的开发效率或者安全性,比如通过ES6+、TypeScript开发脚本逻辑,通过sass、less等方式来编写css样式代码
  • 监听文件的变化来并且反映到浏览器上,提高开发的效率
  • JavaScript 代码需要模块化,HTML 和 CSS 这些资源文件也会面临需要被模块化的问题
  • 开发完成后我们还需要将代码进行压缩、合并以及其他相关的优化

是什么:

webpack是一个用于现代的javascript应用程序的静态模块的打包工具

静态模块:

静态模块指的是开发阶段,可以被webpack直接引用的资源,可以直接被打包进bundle.js的资源

webpack的能力:

编译代码能力,提高效率,解决浏览器兼容的问题

模块整合能力,提高性能,可维护性,解决浏览器频繁请求文件的问题

万物皆可模块,项目维护性增强,支持不同种类的前端模块类型,统一的模块化方案,所有资源文件都可以通过代码控制

说说webpack的构建流程?

webpack的运行流程是一个串行的过程,他的工作流程就是将各个插件串联起来

在运行过程中会广播时间,插件只需要监听它所关心的事件,就能加入到这条webpack机制中,去改变webpack的运作,使整个系统扩展性良好

从启动到结束会依次执行以下三大步骤:

  • 初始化流程:从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数
  • 编译构建流程:从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理
  • 输出流程:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统

 

 说说webpack中常见的Loader?解决了什么问题?

loader用于对模块的源代码进行转换,在import或加载模块是预处理文件

webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成指定的文件中

在webpack中,任何文件都是模块,不仅仅是js文件,默认情况下,在遇到import或者require加载模块的时候,webpack只支持js和json文件打包

 像csssasspng等这些类型的文件的时候,webpack则无能为力,这时候就需要配置对应的loader进行文件内容的解析、

关于配置loader的方式有三种:

  • 配置方式(推荐):在 webpack.config.js文件中指定 loader
  • 内联方式:在每个 import 语句中显式指定 loader
  • CLI 方式:在 shell 命令中指定它们

 特性:

loader支持链式调用,链中的每个loader会处理之前处理果的资源,最终变为js代码,顺序为相反的顺序执行

除此之外,loader的特性还有如下:

  • loader 可以是同步的,也可以是异步的
  • loader 运行在 Node.js 中,并且能够执行任何操作
  • 除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块
  • 插件(plugin)可以为 loader 带来更多特性
  • loader 能够产生额外的任意文件

常见的loader:

  • style-loader: 将css添加到DOM的内联样式标签style里
  • css-loader :允许将css文件通过require的方式引入,并返回css代码
  • less-loader: 处理less
  • sass-loader: 处理sass
  • postcss-loader: 用postcss来处理CSS
  • autoprefixer-loader: 处理CSS3属性前缀,已被弃用,建议直接使用postcss
  • file-loader: 分发文件到output目录并返回相对路径
  • url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
  • html-minify-loader: 压缩HTML
  • babel-loader :用babel来转换ES6文件到ES

 说说webpack中常见的Plugin?解决了什么问题?

Plugin是一种计算机应用程序,他和主应用程序互相交互,提供特定的功能

是一种遵循一定规范的应用程序接口编写出来的程序,只能运行在程序规定的系统下,因为其需要调用原纯净系统提供的函数库和数据

webpack中的plugin也是如此,plugin赋予其各种灵活的功能,例如打包优化,资源管理,环境变量注入等,它们运行在webpack的不同阶段,贯穿了webpack整个编译周期

 特性:

本质是一个具有apply方法的javascript对象

关于整个编译生命周期钩子,有如下:

  • entry-option :初始化 option
  • run
  • compile: 真正开始的编译,在创建 compilation 对象之前
  • compilation :生成好了 compilation 对象
  • make 从 entry 开始递归分析依赖,准备对每个模块进行 build
  • after-compile: 编译 build 过程结束
  • emit :在将内存中 assets 内容写到磁盘文件夹之前
  • after-emit :在将内存中 assets 内容写到磁盘文件夹之后
  • done: 完成所有的编译过程
  • failed: 编译失败的时候

常见的Plugin

 HtmlWebpackPlugin:在打包结束后,⾃动生成⼀个 html ⽂文件,并把打包生成的js 模块引⼊到该 html 中

clean-webpack-plugin:删除(清理)构建目录

mini-css-extract-plugin:提取 CSS 到一个单独的文件中

DefinePlugin:允许在编译时创建配置的全局对象,是一个webpack内置的插件,不需要安装

copy-webpack-plugin:复制文件或目录到执行区域,如vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中

复制的规则在patterns属性中设置:

  • from:设置从哪一个源中开始复制

  • to:复制到的位置,可以省略,会默认复制到打包的目录下

  • globOptions:设置一些额外的选项,其中可以编写需要忽略的文件

 说说Loader和Plugin的区别?编写Loader,Plugin的思路?

区别:

  • loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
  • plugin 赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事

两者在运行时机上的区别:

  • loader 运行在打包文件之前
  • plugins 在整个编译周期都起作用

编写loader

在编写 loader 前,我们首先需要了解 loader 的本质

其本质为函数,函数中的 this 作为上下文会被 webpack 填充,因此我们不能将 loader设为一个箭头函数

函数接受一个参数,为 webpack 传递给 loader 的文件源内容

函数中 this 是由 webpack 提供的对象,能够获取当前 loader 所需要的各种信息

函数中有异步操作或同步操作,异步操作通过 this.callback 返回,返回值要求为 string 或者 Buffer

一般在编写loader的过程中,保持功能单一,避免做多种功能

less文件转换成 css文件也不是一步到位,而是 less-loadercss-loaderstyle-loader几个 loader的链式调用才能完成转换

编写plugin

如果自己要实现plugin,也需要遵循一定的规范:

  • 插件必须是一个函数或者是一个包含 apply 方法的对象,这样才能访问compiler实例
  • 传给每个插件的 compiler 和 compilation 对象都是同一个引用,因此不建议修改
  • 异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

在 emit 事件发生时,代表源文件的转换和组装已经完成,可以读取到最终将输出的资源、代码块、模块及其依赖,并且可以修改输出资源的内容

说说webpack的热更新是如何做到的?原理是什么? 

 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用

我们在应用运行过程中修改了某个模块,通过自动刷新就会导致整个应用的整体刷新,那页面中的状态信息都会丢失

如果使用的HMR,就可以实现只将修改的模块试试替换至应用中,不必完全刷新整个应用

配置热更新非常简单

const webpack = require('webpack')
module.exports = {
  // ...
  devServer: {
    // 开启 HMR 特性
    hot: true
    // hotOnly: true
  }
}

通过上述这种配置,如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中

我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热更新

所以,HMR并不像webpack的其他特性一样可以开箱即用,还需要一些额外的配置

if(module.hot){
    module.hot.accept('./util.js',()=>{
        console.log("util.js更新了")
    })
}

总结:

关于webpack热模块更新的总结如下:

  • 通过webpack-dev-server创建两个服务器:提供静态资源的服务(express)和Socket服务
  • express server 负责直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
  • socket server 是一个 websocket 的长连接,双方可以通信
  • 当 socket server 监听到对应的模块发生变化时,会生成两个文件.json(manifest文件)和.js文件(update chunk)
  • 通过长连接,socket server 可以直接将这两个文件主动发送给客户端(浏览器)
  • 浏览器拿到两个新的文件后,通过HMR runtime机制,加载这两个文件,并且针对修改的模块进行更新

 说说webpack proxy工作原理?为什么能解决跨域?

webpack proxy,是webpack提供的代理服务

基本的行为就是接收客户端发送的请求后转发给其他服务器,目的就是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制)

想要实现代理首先需要一个中间服务器,webpack中提供服务器的工具为webpack-dev-server

目的是为了提高开发者日常的开发效率,只适用在开发阶段

devServetr里面的proxy是关于代理的配置,该属性为对象的形式,对象中的每一个属性就是一个代理的规则匹配

属性的名称是需要被代理的请求路径前缀,一般是为了辨别都会设置前缀为api,值为对应的代理匹配规则

  • target:表示的是代理到的目标地址
  • pathRewrite:默认情况下,我们的 /api-hy 也会被写入到URL中,如果希望删除,可以使用pathRewrite
  • secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false
  • changeOrigin:它表示是否更新代理后请求的 headers 中host地址

工作原理:

 proxy工作原理实质上是利用http-proxy-middleware这个http代理中间件,实现请求转发给其他服务器

跨域:

在开发阶段,webpack-dev-server会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在location的一个端口上,而后端服务又是运行在另一个地址上

所以在开发阶段中,由于浏览器同样策略的原因,当本地访问后端就会出现跨域请求的问题

通过设置webpack proxy实现代理请求后,相当于浏览器与服务端中添加一个代理者

当本地发送请求的时候,代理服务器响应该请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地

再代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常的接收数据

注意:服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制

 说说如何借助webpack来优化前端性能?

随着前端的项目逐渐扩大,必然会带来一个问题就是性能

尤其在大型复杂的项目中,前端业务可能因为一个小小的依赖,导致整个页面卡顿甚至崩溃

一般在项目完成后,会通过webpack进行打包,利用webpack对前端项目性能优化是一个十分重要的环节

优化方法:

  • JS代码压缩:压缩可以丑化我们的代码,使打包内存更小
  • CSS代码压缩:css压缩通常是去除无用的空格,因为很难去修改选择器,属性的名称值
  • Html文件代码压缩:
  • 文件大小压缩
  • 图片压缩:有些图片文件比js或css文件更大
  • Tree Shaking
  • 代码分离:实现按需加载
  • 内联 chunk:chunk的模块关联到html

总结

关于webpack对前端性能的优化,可以通过文件体积大小入手,其次还可通过分包的形式、减少http请求次数等方式,实现对前端性能的优化

 如何提高webpack的构建速度?

 随着我们的项目涉及到的页面越来越多,功能和业务代码也会随着越多,相应的webpack的构建时间也会越来越久

构建时间与我们日常开发效率密切相关,当我们本地启动devserver或者build的时候,如果时间过长,会大大的降低我们的工作效率

如何优化

  • 优化 loader 配置
  • 合理使用 resolve.extensions
  • 优化 resolve.modules
  • 优化 resolve.alias
  • 使用 DLLPlugin 插件
  • 使用 cache-loader
  • terser 启动多线程
  • 合理使用 sourceMap

总结:

 优化webpack构建的方式有很多,主要可以从优化搜索时间、缩小文件搜索范围、减少不必要的编译等方面入手

与webpack类似的工具还有哪些?区别?

模块化工具:

模块化是一种处理复杂系统分解为更好的可管理模块的方式

可以用来分割,组织和打包应用。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体

通过这些模块打包工具,能够提高我们的开发效率,减少成本

rollup

 Rollup 是一款 ES Modules 打包器,从作用上来看,Rollup 与 Webpack 非常类似。不过相比于 WebpackRollup要小巧的多

Parcel

Parcel ,是一款完全零配置的前端打包器,它提供了 “傻瓜式” 的使用体验,只需了解简单的命令,就能构建前端应用程序

 Parcel 跟 Webpack 一样都支持以任意类型文件作为打包入口,但建议使用HTML文件作为入口,该HTML文件像平时一样正常编写代码、引用资源

Snowpack

Snowpack,是一种闪电般快速的前端构建工具,专为现代Web设计,较复杂的打包工具(如WebpackParcel)的替代方案,利用JavaScript的本机模块系统,避免不必要的工作并保持流畅的开发体验

Vite 

 vite ,是一种新型前端构建工具,能够显著提升前端开发体验

它主要由两部分组成:

  • 一个开发服务器,它基于 原生 ES 模块 提供了丰富的内建功能,如速度快到惊人的 [模块热更新HMR
  • 一套构建指令,它使用 Rollup打包你的代码,并且它是预配置的,可以输出用于生产环境的优化过的静态资源

其作用类似webpackwebpack-dev-server,其特点如下:

  • 快速的冷启动
  • 即时的模块热更新
  • 真正的按需编译

vite会直接启动开发服务器,不需要进行打包操作,也就意味着不需要分析模块的依赖、不需要编译,因此启动速度非常快

webpack 

相比上述的模块化工具,webpack大而全,很多常用的功能做到开箱即用。有两大最核心的特点:一切皆模块按需加载

与其他构建工具相比,有如下优势:

  • 智能解析:对 CommonJS 、 AMD 、ES6 的语法做了兼容
  • 万物模块:对 js、css、图片等资源文件都支持打包
  • 开箱即用:HRM、Tree-shaking等功能
  • 代码分割:可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间
  • 插件系统,具有强大的 Plugin 接口,具有更好的灵活性和扩展性
  • 易于调试:支持 SourceUrls 和 SourceMaps
  • 快速运行:webpack 使用异步 IO 并具有多级缓存,这使得 webpack 很快且在增量编译上更加快
  • 生态环境好:社区更丰富,出现的问题更容易解决

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

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

相关文章

JVM性能——开启回收日志和实时查看GC信息

JVM性能——开启回收日志和实时查看GC信息 JDK版本:OpenJDK 1.8.0_352-b08 操作系统:CentOS 7 如果文章内出现测试数据测试代码 depth:23 关于JVM的其他文章 JVM性能——垃圾回收器的优化策略 JVM性能——垃圾回收器的介绍 JVM性能——开启回收日…

网络赚钱项目 - 虚拟项目如何选择产品

今日一个老粉找我,他去年3月份就重视我跟我互动了,他上来并不是索取什么,而是给我信息,比如他最近测验了什么产品,什么产品好卖,都会把测验的数据告诉我,当然作为回报,我也会告诉他一…

Centos7宝塔部署python

前言:宝塔本身有python项目管理器,但是有些依赖安装会存在问题,比如paddlehub安装总是失败,本文在宝塔安装了anaconda基础上配合python项目管理器去部署项目,保障依赖隔离不混乱。 centos7宝塔安装conda流程地址&…

Linux使用YUM安装程序

目录 前言 什么是YUM? 1.本地源:系统安装光盘 目的 1)观察YUM核心配置目录 2)删除官方YUM库 3)编写本地YUM库配置文件 4)挂载安装光盘 保证把光盘放到服务器上,通电 挂载 5&#xff0…

np中的normalize/histogram/cumsum/interp函数

一、normalize函数 void normalize(InputArray src,OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray() ) 归一化就是要把需要处理的数据经过处理后 (通过某种算法)限制在你需要的一定范围内。首先归一…

深入注册表监控

前言 注册表是windows的重要数据库,存放了很多重要的信息以及一些应用的设置,对注册表进行监控并防止篡改是十分有必要的。在64位系统下微软提供了CmRegisterCallback这个回调函数来实时监控注册表的操作,那么既然这里微软提供了这么一个方便…

用红黑树封装map和set

文章目录:红黑树模拟实现完整代码红黑树参数适配改造仿函数正向迭代器反向迭代器红黑树封装后的代码map完整代码set完整代码红黑树模拟实现完整代码 如下是红黑树kv模型的模拟实现完整代码,现在我们需要基于此代码封装出map和set基本的接口实现。 #pragma once #i…

音视频开发风潮 | 聊聊为啥从事音视频开发

音视频开发风潮 聊聊为啥从事音视频技术,未来会很赚钱 核心竞争力:音视频是程序界的皇冠,掌握音视频意味着拿到通往未来的船票,不用担心会被其他人替代。因为音视频是有一定门槛的,所以也是与其他人拉开差距的分水岭…

基于Linux的Spark安装与环境配置

文章目录基于Linux的Spark安装与环境配置1、Hadoop测试1.1 启动hadoop1.2 再次启动hadoop1.3 查看是否成功2、Scala安装与配置2.1 下载scala2.2 解压并重命名2.3 配置环境2.4 测试3、Spark安装与配置3.1 下载Spark3.2 解压并重命名3.3 配置环境3.4 配置spark-env.sh3.5 配置sla…

RabbitMQ中VirtualHost相关设置、SpringBoot中集成常见问题总结

wshanshi:总结记录…便于回顾… 一、VirtualHost相关设置 1.1、创建VirtualHost rabbitmqctl add_vhost 虚拟服务器名称如:rabbitmqctl add_vhost test 1.2、用户、权限相关设置 1.2.1、创建用户 rabbitmqctl add_user 用户名 密码如:ra…

Baklib经验分享 | 一些搭建帮助中心的攻略

作为一家企业,既要为用户提供优质的产品,又要为用户提供良好的售后服务。 很多企业在建立网站的时候可能低估了帮助中心的价值,但是实际上,一家好的在线帮助中心可以帮助企业留住用户,而且用户还可以通过自助查询来解…

【Redis系列】Linux查看Redis版本信息

目录 一、详细介绍 1.redis-server -v 1.1 进入容器 1.2 查询redis-server 目录 1.3 进入对应目录 1.4 执行命令 2.redis-cli -v 1.1 进入容器 1.2 查询redis-cli 目录 1.3 进入对应目录 1.4 执行命令 一般是有两种方式 redis-server -vredis-cli -v一、详细介绍 1.…

【数据库系列】如何查看MongoDB版本信息

目录 一、方法介绍 1 mongo --version 2 使用mongod 3 db.version() 二、总结 三种方式可以查看,依次如下: 一、方法介绍 首先要找到mongo的路径,如果不知道在哪,可以输入 whereis mongo 如下图,找到对应的目录…

VMWare安装CentOS7操作系统的虚拟机

【原文链接】VMWare安装CentOS7操作系统的虚拟机 (1)可以从 清华大学镜像源 下载centos7的镜像,比如下载如下这个版本 (2)打开VMWare后,点击【创建虚拟机】 (3)选择【自定义高级…

OAuth 2.0 (第三方登录)前端流程实现

目录 一、OAuth是什么 二、OAuth 实现,前端需要做什么 (一)数据收集表单 (二)获取后端返回值 (三)重定向地址及后续处理 三、项目地址 一、OAuth是什么 OAuth就是让"客户端"安全…

vue-router入门学习3

命名路由 使用命名路由实现声明式导航 要在路由规则里加上name属性,相对于给这个地址取别名,当地址非常长时可以充分体现它的好用之处。 这里的to属性前面要加个冒号噢 调用push函数期间指定一个配置对象,name是要跳转到的路由规则、params是…

真题集P127---2018年真题

真题集P127---2018年真题第一题思路辗转相除法代码第三题思路代码第六题思路代码第一题 思路 就是在考学生&#xff0c;如何快速求解最大公约数问题 <1>从mn中选较小的数开始向下枚举&#xff0c;一直到2为止&#xff0c;第一个能同时整除m,n的即为所求(暴力枚举不推荐)…

Java这些最基础的知识,你还记得多少?

目录 【一】前言 【二】基础数据类型 【三】修饰符 【四】集合 【五】总结 【一】前言 作为一名CS本专业的程序员来说&#xff0c;大学学过的计算机课程&#xff0c;如&#xff1a;编程语言基本语法、数据结构、算法、计算机网络、计算机组成原理、数据库、汇编都是计算机…

nodejs基于微信小程序的书籍销售系统--(ssm+uinapp+Mysql)

伴随着社会以及科学技术的发展,互联网已经渗透在人们的身边,网络慢慢的变成了人们的生活必不可少的一部分,随着互联网的飞速发展,系统这一名词已不陌生,越来越多的书店都会使用系统来定制一款属于自己个性化的系统。书籍销售系统采用nodejs技术, mysql数据库进行开发,实现了首页…

人脑能否重启?

1.重启是什么 “人脑能否重启”这个问题还不简单&#xff0c;人睡眠后清醒就是重启。 事实真的是如此简单吗&#xff1f;我们先不急着给出结论&#xff0c;前面提到“人睡眠后清醒就是重启”&#xff0c;这句话中有两概念&#xff1a; 1、睡眠和觉醒&#xff0c;这是两种人脑…