前端八股文面试题——webpack工程化

webpack有哪些常见的loader? 你用过哪些loader?

  • raw-loader: 加载文件原始内容
  • file-loader: 把文件输出到文件夹中,在代码中通过相对url
    去引用输出的文件夹(包含图片、字体)
  • url-loader:和file-loader类似,区别是用户可以设置一个阈值。 大于阈值会交给file-loader 处理,小于阈值则返回base64编码(一般用来处理图片)
  • source-map-loader:加载额外的source-map文件,方便断点调试
  • image-loader:加载并压缩图片文件
  • json-loader:加载json文件
  • babel-loader:将es6 装换成es5
  • ts-loader:将ts 语音转换成 js
  • sass-loader、less-loader:都是转换成css
  • css-loader:加载css
  • style-loader: 把css注入到js中,通过dom操作加载css
  • postcss-loader:扩展css语法,使用下一代css
  • eslint-loader、tslint-loader:代码检查。
  • vue-loader:加载vue.js单文件组件。

webpack 有哪些常见的Plugin? 你用过哪些Plugin?

  • define-plugin:定义环境变量,
  • ignore-plugin:忽略部分文件
  • html-webpack-plugin:简化html文件创建
  • uglifyjs-webpack-plugin:压缩js
  • mini-css-extract-plugin:分离样式文件,css提取为单独的文件,支持按需加载
  • clean-webpack-plugin:目录清理(用在下次打包之前把上次打包的内容清理掉)
  • webpack-bundle-analyzer:可视化webpack输出文件的体积。用于分析当前项目依赖文件的体积大小。
  • speed-measure-webpack-plugin:分析每个loader 和 plugin 执行耗时

说说Loader 和Plugin 的区别

作用上
  • loader 本质是一个函数,对接收到的内容进行转换,返回转换后的结果,webpack只认识js,所以loader就相当于翻译官。对其他类型资源进行转译和预处理。
  • plugin:是插件,它基于事件流框架 Tabable,可以扩展webpack功能,在webpack运行的生命周期中会广播很多事件。plugin可以监听这些事件,在适合的时机通过webpackapi 改变输出的结果。
结构上
  • loader :在module.rules 中进行配置,类型是数组,每项都是对象,对象包含(test 文件类型,loader 对应的模块加载器,option 对应的参数)
  • plugin:每个plugin都需要单独配置,类型是数组,每项plugin是一个plugin实例,参数通过构造函数传入。

webpack 构建流程简单说一下

它的运行流程是一个串行的过程。
1、初始化参数:从配置文件和shell语句中读取并且合并参数,得到最终的参数。
2、开始编译:初始化Compiler 对象,加载所有的配置插件。执行对象run方法,开始编译。
3、确定入口:根据配置的entry找到所有入口
4、翻译模块:调用所有的loader 对模块进行编译,找出模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过处理。
5、完成模块编译:经过loader翻译完所有模块后的最终内容以及它们之间的依赖关系。
6、输出资源:根据入口以及它们依赖关系组装成一个个包含多个模块的chunk,再把每个chunk 转换成单独的文件加入到输出列表中。(这里可以修改输出内容,并且是修改的最后一个机会)
7、输出完成:根据配置确定输出的路径和文件名,把文件内容写到文件中,

在上面流程中,webpack 会在特定的时间点广播特定事件,插件在监听到事件后调用webpack 提供的API 改变输出结果

使用webpack开发时,使用过哪些可以提高效率的插件?

  • webpack-dashboard:更友好的展示的展示相关包信息。
  • webpack-merge:提取公共配置,可以将多个配置文件合并,减少代码重复。
  • speed-measure-webpack-plugin:分析 loader 和 plugin 的耗时,从而分析构建过程中的性能瓶颈。
  • size-plugin:监控资源体积变化,尽早发现问题。
  • HotModuleReplacementPlugin:模块热替换。

如何优化webpack 的构建速度?

  1. 使用高版本webpack 和 node.js
  2. 多进程 / 多实例构建 thread-loader
  3. 压缩代码 、多进程并行压缩‘

1)webpack-paralle-uglify-plugin :可以并行运行 UglifyJS 插件,从而更加充分、合理的使用 CPU
资源,从而大大减少构建时间 2)terser-webpack-plugin :它使用 Terser 库来执行压缩,Terser
是一个用于压缩 JavaScript 代码的工具,可以对代码进行简单的混淆,以及删除未使用的代码和注释等优化。 3)
mini-css-extract-plugin : 可以避免将 CSS 代码打包到 JavaScript 文件中,减少 JavaScript
的体积,同时也可以使得 CSS 文件可以被浏览器缓存,提高页面加载速度。

  1. 图片压缩 (imagemin、image-webpack-plugin)
  2. 缩小打包作用域
    1)、通过exclude / include 来确定loader 规则范围。
    2)、设置resolve.extensions.
    3)、resolve.modules
  3. 提取页面公共的资源
    1)、基础包分离
    2)、使用html-webpack-externals-plugin 基础包通过cdn引入,不打入bundle 中。
    3)、使用splitchunksplugin 将代码拆分成多个块,以便在不同的环境中按需加载。
  4. 充分利用缓存提升二次构建速度。
    1)、使用 babel-loader 开启缓存
    2)、terser-webpack-plugin 开启缓存
    3)、cache-loader 或者 hard-source-webpack-plugin
  5. tree shaking (没有用过的模块代码进行标记,从最终bundle 中去掉)

文件指纹是什么?怎么用?

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

  • hash:和整个项目构建相关的,只有项目文件改变、项目的hash值就会改变。
  • chunkHash:和webpack打包的chunk 相关,不同的entry产生不同的chunkHash,
  • contentHash:根据文件内容定义hash,文件内容不变contentHash就不会变。
js的文件指纹设置。

主要设置output 的 fllename 使用 chunkhash.

module.exports = {
	entry: {spp: './src/app.js', search: './src/search.js'},
	output: {filename: '[name][chunkhash:8].js',path:_dirname + '/dist'}
	// chunkhash:8 是设置对应的长度
}
css 文件指纹设置

设置MiniCssExtractPlugin

module.exports = {
	entry: {spp: './src/app.js', search: './src/search.js'},
	output: {filename: '[name][chunkhash:8].js',path:_dirname + '/dist'},
	plugin: [
		new MinCssExtractPlugin({ filename:'[name][contenthash:8].css'}),
	]
}
图片相关文件指纹设置

设置 file-loader 中的name

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    }, 
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
					{
					  loader: 'file-loader',
					  option: {name: 'img/[name][hash:8].[ext]'},
					}
				],
			}
		]
	}
}

是否写过loader?简单描写一下编写loader 的思路?

  • loader是支持链式调用的,所有在开发中需要严格遵守单一职责。每个loader负责自己所需要负责的事情。
  • loader是运行在nodejs中的,可以调用nodejs api 或者安装第三方模块调用。 传给loader 的原内容是 utf-8
  • 编码的字符串 尽可能异步化loader ,如果计算量小的化同步也可以
  • loader 是无状态的,不应该在loader 中保留状态
  • 开发loader 时可以使用 loader-utils schema-utils 工具 还可以(通过npm link 和
    resolveloader 这两种方式)加载本地的loader 方法

是否写过Plugin?简单描写一下编写Plugin的思路?

  • webpack运行生命周期中会广播出很多事件,让plugin 监听事件,特定阶段钩入想要添加的自定义插件内容
  • webpack通过tapable 事件流机制保证插件有序性,使系统的扩张性很好

compiler 暴露整个生命周期相关钩子
compliation 暴雷与模块和依赖有关的颗粒度更小的事件钩子
plugin 需要再原型上绑定apply方法,才能访问compiler 实例。
插件接收 compiler 、compliation 都是同一个引用。
找到合适的事件点完成想要执行的内容,

说说Babel 原理

在 webpack 中,Babel 主要用于将 ECMAScript 2015+版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其它环境中。Babel 的转化过程如下:

  1. Parse:使用 babylon 将原始代码转换为抽象语法树。
  2. Transform:通过 babel-traverse 对前面的抽象语法树进行遍历修改,并获得新的抽象语法树。
  3. Generator:使用 babel-generator 将抽象语法树转换为代码。

这三个操作通过 babel-core 合成一个对外的 API 供外界使用。

source map 是什么?生产环境怎么用?

Source Map 用于将编译、打包、压缩后的代码映射回源代码。

在生产环境中使用 Source Map 有以下几个步骤:

  1. 在构建过程中生成 Source Map:确保你的构建工具(如 webpack)配置为生成 Source Map。
  2. 部署包含 Source Map 的构建产物:将生成的 Source Map 与构建后的代码一起部署到生产环境。
  3. 在开发工具中启用 Source Map:这样可以在浏览器中查看原始源代码,并在调试时将错误和堆栈跟踪映射回原始代码。

使用 Source Map 的好处包括:

  1. 更好的调试体验:可以在生产环境中查看和调试原始代码。
  2. 提高开发效率:更容易找到和解决问题。

然而,需要注意的是,使用 Source Map 会增加构建产物的大小,可能会对性能产生一定影响。因此,在生产环境中应谨慎使用,并在必要时进行优化。

文件监听原理

Webpack 文件监听的原理是通过轮询判断文件的最后编辑时间是否发生变化。Webpack 首先存储文件的修改时间,下次再有修改时会与上次修改时间进行比对。如果发现不一致,Webpack 不会立即告诉监听者,而是将文件修改缓存起来,等待一段时间。在等待期间,如果有其他文件发生变化,Webpack 会将变化列表一起构建,并生成到 bundle 文件夹。

文件监听的目的是在发现文件发生变化时,自动重新构建出新的输出文件。开启监听模式有两种方式,在启动 Webpack 命令时带上 --watch 参数,或在配置 webpack.config.js 中设置 watch: true。构建完成后,输出的文件会被放入磁盘中。

webpack 热更新原理

Webpack 的热更新(Hot Module Replacement,简称 HMR)是一种在开发时提供实时更新的功能,它使得在修改代码后,不需要完全刷新页面就能立即看到更新的效果。HMR 的原理涉及以下几个主要步骤:

  1. 启动时建立 WebSocket 连接:在项目启动时,Webpack 会创建与开发服务器的 WebSocket 连接,用于在构建完成后接收更新的模块。

  2. 构建编译阶段:Webpack 在编译时会在每个模块中注入 HMR 运行时代码。该代码会监听源代码的变化,并通知 HMR runtime 进行处理。

  3. 文件监控:Webpack 会监控所有入口文件及其依赖的文件,一旦检测到文件发生变化,会触发重新编译。

  4. 构建完成:当编译完成后,Webpack 会将编译结果发送给开发服务器,并通过 WebSocket 通知客户端有新的资源可用。

webpack 事件机制了解吗?

常见事件

  • before-run:开始执行构建之前触发,可以用于清理上一次构建的临时文件或状态
  • run:开始执行构建触发
  • before-compile:开始编译代码前触发,可以用于添加一些额外的编辑配置或者预处理代码
  • compile:开始编译,可用于监听编译过程或编译处理错误
  • this-compilation:创建新的 Compilation 对象触发,Compilation 对象代表当前编辑过程中的所有状态和信息。
  • compilataion:编辑代码期间触发,可用于监听编译过程或编译处理错误
  • emit:输出文件之前触发,修改输出文件或者生成一些附件文件。
  • after-emit:输出文件后触发,用于清理中间文件
  • done:构建完成时触发,用于生成构建报告。

事件机制
Webpack采用事件驱动的方式打包web应用,其事件机制主要依靠一个很小的核心库tapable来实现。封装了事件订阅发布机制。compile、compilataion 都是tapable类的实例对象,

webpack5 相比于 webpack4 有哪些提升?

  • 更快的构建速度,尤其是开发模式下构建速度明显的提升
  • Tree Shaking:优化算法。更准确哪些代码无用,更好的优化构建输出的文件大小
  • 内置的持久化缓存:可以缓存每个模块编译结果,加速后续构建,
  • 支持 WebAssmbly
  • 模块联班:Module federation 解决模块共享、远程加载。为微前端架构提供支持。

对模块联班的理解

模块联邦(Module Federation)是 Webpack 5 推出的一个新特性。它是一种模块共用机制,允许本地调用远程的模块。通过模块联邦可以解决微前端依赖问题,对比 npm 库具有实时性的优势。

Webpack 中有哪些核心概念?

Webpack 中有以下几个核心概念:

  1. 模块:Webpack 会将各种资源(如 JavaScript、CSS、图像等)视为模块。
  2. 入口:指定 Webpack 开始构建的起点。
  3. 输出:定义了最终生成的文件。
  4. 加载器:用于处理特定类型的文件。
  5. 插件:扩展 Webpack 的功能。
  6. 依赖关系:模块之间的依赖关系。
  7. 模块解析:确定如何查找和加载模块。
  8. 代码分割:将代码分割成多个块,按需加载。
  9. 优化:例如压缩、合并等,提高性能。
  10. 热更新:在运行时自动更新变更的模块。

webpack 的mode是什么?

Webpack 的 mode 提供了 mode 配置选项,告知 Webpack 使用相应模式的内置优化。mode 的值可以是 development、production 或 none,分别代表开发模式、生产模式和无预设模式(需要从头开始配置)。如果 mode 没有被设置,系统会默认使用 production 模式。

  1. development(开发模式):提供了一些有助于开发和调试的特性,更详细的错误信息和警告。实时重新加载。 未压缩的代码以提高调试效率。
  2. production(生产模式):用于准备上线的构建,强调优化和性能:代码压缩和混淆。 资源优化。
  3. none (无预设模式) 关闭任何默认优化选项,只执行基本打包功能,不做任何额外处理。

什么是代码分割(code Splitting),如何在webpack中实现?

代码分割是将一个应用程序的代码拆分成多个独立的块,以便可以按需加载。可以减少初始加载时间提高页面性能,在 Webpack 中配置实现代码分割,有以下多种方式:
1、入口起点配置:配置多个入口起点,不同部分打包成独立的代码块。
2、动态导入 (Dynamic import):可以将模块作为单独的代码块按需加载,这样模块需要时才会下载执行,
3、使用 SplitChunksPlugin 插件来自动分割代码。自动拆分公共模块,并创建独立代码块,避免重启加载,提高缓存利用率。
4、使用 CommonsChunkPlugin 插件来提取公共模块。

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值