webpack 是什么?

webpack 是一个静态模块打包器, 当webpack 处理应用程序时, 会递归构建一个依赖图, 其中包含应用程序需要用到的每个模块, 然后将这些模块打包成一个或多个bundle
webpack 就像一条生产线, 要经过一系列处理流程(loader) 后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系, 只有完成当前处理后才能交给下一个流程去处理。
插件就像是一个插入到生产线中的一个功能, 在特定的时机对生产线上的资源做处理。webpack 在运行过程中会广播事件, 插件只需要监听他所关心的事件,就能加入到这条生产线中,去改变生产线的运作。

webpack 的打包过程/打包原理/构建流程?

image.png
webpack 的运行流程是一个串行的过程, 它的工作流程就是将各个插件串联起来
命令行执行 npx webpack 打包命令开始

  1. 初始化编译参数: 从配置文件到shell 命令中读取与合并参数
  2. 开始编译:根据上一步得到的参数初始化Compiler 对象, 加载所有配置的Plugin, 执行对象的 run 方法开始执行编译
  3. 确定入口: 根据配置中的 entry 找出所有的入口文件
  4. 编译模块:从入口文件出发,调用所有配置的Loader 对模块进行翻译, 再找出该模块依赖的模块, 然后递归本步骤直到所有入口依赖的文件都进行翻译
  5. 完成模块编译: 在经过第 4 步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及他们之间的依赖关系图
  6. 输出资源: 根据依赖关系图, 组装成一个个包含多个模块的Chunk, 再把每个Chunk 转化成一个单独的文件加入到输出列表, 根据配置确定输出的路径和文件名,输出

在以上过程中, webpack 会在特定的时间点广播出特定的事件, 插件在监听到感兴趣的事件后会执行特定的逻辑

webapck 中loader 的作用/ loader 是什么

Loader 是 webpack 中提供了一种处理多种文件格式的机制, 因为webpack 只认识 JS 和 JSON, 所以 Loader 相当于翻译官, 将其他类型资源进行预处理
用于对模块的“源代码”进行转换
可以通过 loader 的预处理函数, 为 JavaScript 生态系统提供更多的能力

常见的 loader ?

  1. less-loader: 将less 文件便衣成 css 文件
  2. css-loader: 将css文件变成 commonjs模块加载到 js 中, 模块内容是样式字符串
  3. style-loader: 创建 style 标签, 将 js 中的样式资源插入标签内, 并将标签添加到 head 中生效
  4. ts-loader: 打包编译typeScript 文件

    Plugin 有什么作用? Plugin 是什么?

    Plugin 功能更强大, 主要目的是解决 loader 无法实现的事情, 比如打包优化和代码压缩等等
    Plugin 加载后,在webpack 构建的某个时间节点就会触发 plugin 定义的功能, 帮助 webpack 做一些事情。 实现对 webpack 的功能扩展

    常见的 Plugin 有哪些?

  • html-webpack-plugin 处理 html 资源, 默认会创建一个空的 HTML, 自动引入打包输出的所有资源(js/ css)
  • min-css-extract-plugin 打包过后的 css 在 js 文件里, 该插件可以把 css 单独抽出来
  • clean-webpack-plugin 每次打包的时候, CleanWebpackPlugin 插件就会自动把上一次打的包删除

webpack 中Loader 和 Plugin 的区别?

webpack 就像一条生产线, 要经过一系列处理流程(loader)后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的, 多个流程之间有存在依赖关系, 只有完成当前处理后才能交给下一个流程去处理。
插件就像是一个插入到生产线中的一个功能, 在特定的时机对生产线上的资源做处理。 webpack 在运行过程中会广播事件, 插件只需要监听他所关心的事件, 就能加入到这条生产线中, 去改变生产线的运作

运行时机

  • loader 运行在编译阶段
  • plugins 在整个周期都起作用

image.png

使用方式

Loader: 1、下载 2、 使用
Plugin: 1、下载 2、引用 3、使用

webpack 有哪些优化手段?

tree-shaking 删除没有使用的代码、优化前端性能/提高构建速度

tree-shaking 是一种基于 ES Module 规范的 Dead Code Elimination 技术打包, 在打包过程中检测工程中有没有引用过的模块并进行标记, 删除没有引用过的模块, 提高构建速度, 减少程序运行时间

使用 tree-shaking 需要注意什么?

  • 默认 mode = production, webpack5生产环境默认开启 tree-shaking 功能
  • 需要是使用 ES6 规范编写模块代码, ES6 的模块依赖关系时确定的,和运行时状态无关
  • 尽量不写带有副作用的代码。

    利用webpack 来优化前端性能

  • 代码压缩

按需加载

  • 代码分割 splitChunks- 在 optimization 配置项中配置
    • 可以将mode__modules 中代码单独打包成一个 chunk 输出
    • 会自动分析多入口chunk中, 有没有公共的文件, 如果有会打包成单独的一个chunk 不会重复打包
  • 使用DII 进行分包
    • 正常情况下 node_module 会被打包成一个文件
    • 使用dll 技术, 对可以将那些不常更新的框架和库进行单独打包, 生成一个chunk
  • 使用路由懒加载
    • 在代码中所有被 import() 函数应用的模块, 都将打包成一个单独的包, 放在chunk 存储的目录下。 在浏览器运行到这一行代码时, 就会自动请求这个资源, 实现一步加载

webpack 配置压缩代码

  1. 在 optimization 配置项中来配置该插件作为压缩器进行压缩
  2. 在 plugins 里使用该插件进行压缩

js 压缩: 利用terser-webpack-plugin
css压缩: 利用 optimize-css-asserts-webpack-plugin 插件
删除了 console、 注释、 空格、 换行、 没有使用的 css 代码等

提高 webpack 构建速度

思路1: 减少需要构建的文件或代码

  • HMR(Hot Module Replacement) 模块热替换只重新构建发生变化的模块- 开发环境中
  • 缩小处理范围: 合理利用这两个属性
    • exculde: 不需要处理的文件
    • indlude: 需要处理的文件
  • babel 缓存, 第二次构建时, 会读取之前的缓存,只重新构建变化的文件
  • 使用DII 进行分包 —> 分包方便按需加载

    思路2: 多进行构建

  • 多进程打包 thread-loader , 将其放在费时的loader 之前

进程启动和进程通信都有开销, 工作时间比较长,才需要多进程打包

转载:

webpack 面试题整理nuise的博客-CSDN博客_webpack面试题