webpack面试题

本文详细介绍了webpack的面试常见问题,包括常用的loader如css、图片处理、js语法检查和转换等,以及常用的plugin如html文件处理、js兼容性、清理打包目录等。还探讨了webpack的优化策略,如代码分割、热更新、缓存和多进程压缩等。同时,文章解释了Loader和Plugin的区别,并阐述了webpack的基本概念和工作原理,以及webpack4的新特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常用的loader

1、打包less、css

css-loader : 将css文件变成commonjs模块加载js中

style-loader :动态创建 style 标签,将 css 插入到 head 中.

less-loader :负责处理编译 .less 文件,将其转为 css

sass-loader:将SCSS/SASS代码转换成CSS

2、样式中的图片

file-loader :把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 (处理图片和字体)

url-loader:资源大小小于 某值 时,将资源转换为 base64,超过 某值 时,将图片拷贝到 dist 目录

3、html中的图片

html-loader

4、css兼容性处理

postcss-loader :自动生成浏览器兼容性前缀

postcss-preset-env

5、js语法检查

eslint-loader

eslint-config-airbnb-base

eslint-plugin-import

6、将JS代码向低版本转换

babel-loader

@babel/core

@babel/preset-env

7、 在一些性能开销较大的 loader 之前添加 cache-loader,将结果缓存中磁盘中

cache-loader

cacheDirectory: true

8、同一时刻处理多个任务

happypack、thread-loader

9、映射会源文件的具体位置

source-map-loader

devtool: ‘cheap-module-eval-source-map’


常用的plugin

1、html文件

html-webpack-plugin:简化 HTML 文件创建 (依赖于 html-loader)

web-webpack-plugin:可方便地为单页应用输出 HTML,比 html-webpack-plugin 好用

2、自动打包运行

webpack-dev-server

3、提取css为单独文件

mini-css-extract-plugin

4、js兼容性处理

@babel/polyfill

5、清空打包目录

clean-webpack-plugin

7、将单个文件或整个目录复制到构建目录

copy-webpack-plugin

8、热模替换

HotModuleReplacementPlugin

9、定义环境变量

DefinePlugin

10、测量各个插件和loader所花费的时间

speed-measure-webpack-plugin

11、开启 JS 多进程压缩

webpack-parallel-uglify-plugin

uglifyjs-webpack-plugin

12、为模块提供中间缓存

hard-source-webpack-plugin

13、忽略第三方包指定目录

IgnorePlugin

14、可视化 Webpack 输出文件的体积

webpack-bundle-analyzer


优化

webpack-dashboard:可以更友好的展示相关打包信息
webpack-merge:提取公共配置,减少重复配置代码
speed-measure-webpack-plugin:简称 SMP,分析出 Webpack 打包过程中 Loader 和 Plugin 的耗时,有助于找到构建过程中的性能瓶颈。
size-plugin:监控资源体积变化,尽早发现问题
HotModuleReplacementPlugin:模块热替换

-JS文件按需加载
-resolve.modules 配置 webpack 去哪些目录下寻找第三方模块
-通过 exclude、include 配置来确保转译尽可能少的文件
-在一些性能开销较大的 loader 之前添加 cache-loader,将结果缓存中磁盘中。
-thread-loader:同一时刻处理多个任务。把 thread-loader 放置在其它 loader 之前,那么放置在这个 loader 之后的 loader 就会在一个单独的 worker 池中运行
-HardSourceWebpackPlugin 为模块提供中间缓存
-IgnorePlugin:忽略第三方包指定目录
-externals:externals使用 CDN 的方式引入,剥离出webpack的打包,并且可以正常import,减少 Webpack打包出来的 js 体积
-DllPlugin:如果所有的JS文件都打成一个JS文件,会导致最终生成的JS文件很大,DllPlugin 和 DLLReferencePlugin 可以实现拆分 bundles,将一些不做修改的依赖文件,提前打包,可以大大提升构建速度
-tree-shaking:如果使用ES6的import 语法,那么在生产环境下,会自动移除没有使用到的代码。
-scope hosting:变量提升,可以减少一些变量声明。在生产环境下,默认开启。
-@babel/plugin-transform-runtime


Loader和Plugin的区别

  • Loader本质就是一个函数。因为 Webpack 只认识 JavaScript,loader是使webpack拥有加载和解析非js文件的能力
  • plugin 可以扩展webpack的功能,使得webpack更加灵活。可以在构建的过程中通过webpack的api改变输出的结果
  • Loader 在 module.rules 中配置,作为模块的解析规则,类型为数组。每一项都是一个 Object,内部包含了 test(类型文件)、loader、options (参数)等属性。
  • Plugin 在 plugins 中单独配置,需要 require 该插件,类型为数组,每一项是一个 Plugin 的实例,参数都通过构造函数传入。

什么是webpack

1.本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具
2.当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle。

webpack的基本功能和工作原理

代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等
代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

bundle,chunk,module

对于一份同逻辑的代码,当我们手写下一个一个的文件,它们无论是 ESM 还是 commonJS 或是 AMD,他们都是 module ;

当我们写的 module 源文件传到 webpack 进行打包时,webpack 会根据文件引用关系生成 chunk 文件,webpack 会对这个 chunk 文件进行一些操作;

webpack 处理好 chunk 文件后,最后会输出 bundle 文件,这个 bundle 文件包含了经过加载和编译的最终源文件,所以它可以直接在浏览器中运行。

hash、chunkhash、contenthash

通过webpack构建之后,生成对应文件名自动带上对应的MD5值
(1)hash整体打包内容的md5值
(2)chunkhash当前chunk内容的md5值
(3)contenthash当前bundle内容的md5值

用hash有什么问题?
如果都使用hash的话,因为这是工程级别的,即每次修改任何一个文件,所有文件名的hash至都将改变。所以一旦修改了任何一个文件,整个项目的文件缓存都将失效。
每个压缩后的文件的hash值是一样的,所以对于没有改变的模块而言,这样做显然不恰当,因为缓存失效了嘛。此时,chunkhash的用途随之而来。

用chunkhash有什么问题?
每个chunk模块的hash是不一样的
但是这样又有一个问题,因为我们是将样式作为模块import到JavaScript文件中的,所以它们的chunkhash是一致的,如test1.js和test1.css

contenthash是针对文件内容级别的,只有你自己模块的内容变了,那么hash值才改变

webpack构建过程

  • 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler
  • 编译: 从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,递归地进行编译处理
  • 输出:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,将 Chunk 转换成最终的bundle文件,写入bundle.js中

模块打包原理

将所有依赖打包成一个bundle.js,通过代码分割成单元片段按需加载。

热更新原理

首先对本地文件代码进行编译打包,也就是webpack的一系列编译流程。

其次编译结束后,开启对本地文件的监听,当文件发生变化,重新编译,编译完成之后继续监听。(监听本地文件的变化主要是通过文件的生成时间是否有变化)

当监听到一次webpack编译结束,server 端与浏览器之间维护了一个 Websocket,当本地资源发生变化时,server 端会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向server 端发起 Ajax 请求来获取更改内容(文件列表、hash),获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。HotModulePlugin在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引用。

当 HMP 失败后,进行浏览器刷新来获取最新打包代码。


首先是建立起浏览器端和服务器端之间的通信,浏览器会接收服务器端推送的消息,如果需要热更新,浏览器发起Ajax 请求去服务器端获取打包好的资源解析并局部刷新页面。

Babel原理

  • 解析:使用babylon这个解析器,它会根据输入的javascript代码字符串根据ESTree规范生成AST(抽象语法树)。
  • 转换:plugin用babel-traverse对AST树进行遍历转译,得到新的AST树
  • 生成:用babel-generator通过AST树生成ES5代码
    在这里插入图片描述

文件指纹

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

Hash:和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改
Chunkhash:和 Webpack 打包的 chunk 有关,不同的 entry 会生出不同的 chunkhash
Contenthash:根据文件内容来定义 hash,文件内容不变,则 contenthash 不变

代码分割的本质是什么?有什么意义呢?

在最开始使用Webpack的时候, 都是将所有的js文件全部打包到一个build.js文件中(文件名取决与在webpack.config.js文件中output.filename), 但是在大型项目中, build.js可能过大, 导致页面加载时间过长. 这个时候就需要code splitting, code splitting就是将文件分割成块(chunk), 我们可以定义一些分割点(split point), 根据这些分割点对文件进行分块, 并实现按需加载。

entry,output

entry 入口,告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js

output 出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist

与gulp、grunt的区别

grunt和gulp是基于任务和流(Task、Stream)的。类似jQuery,找到一个(或一类)文件,对其做一系列链式操作,更新流上的数据, 整条链式操作构成了一个任务,多个任务就构成了整个web的构建流程。
webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的Loader来处理不同的文件,用Plugin来扩展webpack功能。

npm打包时需要注意哪些?如何利用webpack来更好的构建?

完善基本信息;
定义依赖;
忽略文件;
打标签;

webpack规范

webpack默认遵循commonjs规范 module.exports

使用webpack进行打包时有两种模式:
开发模式:主要是用于测试,代码调试等;
生产模式:要考虑性能问题,要压缩 如果没有插件 就不会压缩;

默认情况下webpack的配置文件叫webpack.config.js,可以通过--config指定webpack的配置文件名

webpack4的新特性

1.mode

webpack增加了一个mode配置,只有两种值development | production。对不同的环境他会启用不同的配置。

2、optimization
webpack4删除了CommonsChunkPlugin(提取第三方库和公共模块)插件,它使用内置API optimization.splitChunks 和 optimization.runtimeChunk,这意味着webpack会默认为你生成共享的代码块。其它插件变化如下:

NoEmitOnErrorsPlugin (遇到错误代码将不会退出)废弃,使用optimization.noEmitOnErrors替代,在生产环境中默认开启该插件。

ModuleConcatenationPlugin (启用作用域提升)废弃,使用optimization.concatenateModules替代,在生产环境默认开启该插件。

NamedModulesPlugin (显示模块的相对路径)废弃,使用optimization.namedModules替代,在生产环境默认开启。

uglifyjs-webpack-plugin(缩小\压缩优化js文件)升级到了v1.0版本, 默认开启缓存和并行功能。

3、开箱即用WebAssembly

4.代码分割。

使用动态import,而不是用system.import或者require.ensure

5.vue-loader。

使用vue-loader插件为.vue文件中的各部分使用相对应的loader,比如css-loader等


「吐血整理」再来一打Webpack面试题
前端面试-webpack篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值