webpack 部分知识

68 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

webpack是前端的重要知识体系,也是一个前端必备的技能,为了面试做好准备,还是得来学习学习它。

什么是webpack?

webpack 是代码编译工具,有入口、出口、loader 和插件。webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle

前端代码为何要进行构建和打包?

  1. 代码方面

    1. 体积更小,加载更快(tree-shaking,压缩合并)
    2. 编译高级语言和语法(ts,es6,模块化)
    3. 兼容性和错误提示(polyfill,postcss,eslint)
  2. 研发流程

    1. 统一、高效的开发环境
    2. 统一的构建流程和产出标准
    3. 集成公司构建规范(提测,上线)

module chunk bundle分别是什么意思,有何区别?

bundle
bundle由许多不同的模块生成,包含已经经过加载和编译过程的源文件的最终版本

chunk
chunk主要是在内部用于管理捆绑过程。输出是由bundle由chunk组成。通常,chunk直接与bundle对应,但是有些配置不会产生一对一的关系,例如MiniCssExtractPlugin可从chunk中抽离出css文件,单独生成bundle。生成chunk有三种方式,entry、动态加载、splitChunks抽取共有代码

Module
module是离散功能块,相对于完整程序提供了更小的接触面。一般是module可提供抽象和封装界限,使得应用程序中每个模块都具有明确的目的

module,chunk 和 bundle 其实就是同一份逻辑代码在不同转换场景下的取了三个名字:

  • 我们直接写出来的是 module
  • webpack 处理时是 chunk
  • 最后生成浏览器可以直接运行的 bundle。

webpack如何实现懒加载?

懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。

通俗来说就是,如果每次加载页面的时候都会某些代码块,会重复的请求,造成资源的浪费,影响网站性能。所以提出了懒加载的解决办法:按需加载,初始化不需要加载此代码块,等到具体的执行需要时候,再加载,从而优化性能。

Loader和Plugin的区别?

loader是webpack的加载器,可以帮我们处理各种非js文件。如css样式,vue、jsx、weex等后缀的代码,JPG、PNG图片等。操作的是文件,将文件A通过loader转换成文件B,是一个单纯的文件转化过程。

plugin即为插件,是一个扩展器,丰富webpack本身,增强功能 ,针对的是在loader结束之后,webpack打包的整个过程,他并不直接操作文件,而是基于事件机制工作,监听webpack打包过程中的某些节点,执行广泛的任务。

plugin可以处理一些loader不能完成的功能

常见的loader

  • style-loader: 将css添加到DOM的内联样式标签style里
  • css-loader :允许将css文件通过require的方式引入,并返回css代码
  • less-loader: 处理less
  • sass-loader: 处理sass
  • file-loader: 分发文件到output目录并返回相对路径
  • url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
  • html-minify-loader: 压缩HTML
  • babel-loader :用babel来转换ES6文件到ES
  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件 (处理图片和字体)

常见的plugin

  • Html-Webpack-Plugin:在打包结束后,⾃动生成⼀个 html ⽂文件,并把打包生成的js 模块引⼊到该 html 中
  • clean-webpack-plugin:删除(清理)构建目录
  • ignore-plugin:忽略部分文件

Webpack 的热更新

  1. Webpack 的热更新又称热替换(Hot Module Replacement),缩写为 HMR。 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。
  2. HMR的核心就是客户端从服务端拉去更新后的文件,准确的说是 chunk diff (chunk 需要更新的部分),实际上 WDS 与浏览器之间维护了一个 Websocket,当本地资源发生变化时,WDS 会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向 WDS 发起 Ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向 WDS 发起 jsonp 请求获取该chunk的增量更新。
  3. 后续的部分(拿到增量更新之后如何处理?哪些状态该保留?哪些又需要更新?)由 HotModulePlugin 来完成,提供了相关 API 以供开发者针对自身场景进行处理,像react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。

借助webpack来优化前端性能?

主要借助插件

  • JS代码压缩

    terser

  • CSS代码压缩

    css-minimizer-webpack-plugin

  • Html文件代码压缩

    HtmlWebpackPlugin

  • 文件大小压缩

  • 图片压缩

  • Tree Shaking

  • 代码分离

    将代码分离到不同的bundle中,之后我们可以按需加载,或者并行加载这些文件

  • 内联 chunk