webpack中常用的 Loader和Plugin

154 阅读6分钟

Webpack 是一个静态资源打包工具。 它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。Webpack 本身功能比较少,只能处理 js 资源,一旦遇到 css 等其他资源就会报错。需要通过loaderplugin来扩展其功能,帮助我们打包各种类型的文件以及在打包过程中做一些其他的事情。

常用的loader

处理样式文件

  1. css-loader: 负责将 Css 文件编译成commonjs模块 (Webpack 能识别的模块)到js中。将css资源打包到js中。
  2. style-loader:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容,将标签添加到html文件中生效。
  3. less-loader:负责将 Less 文件编译成 css 文件
  4. sass-loader:负责将 Sass 文件编译成 css 文件
  5. stylus-loader:负责将 Styl 文件编译成 css 文件

执行顺序:less-loader(sass-loader,stylus-loader),css-loader先执行,style-loader后执行。

  1. file-loader、url-loader:Webpack4 时,图片资源通过这两个loader进行处理。Webpack5 已经将两个 loader 功能内置到 Webpack 里。 file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL去引⽤输出的⽂件。 url-loader:和 file-loader 类似,但是能在⽂件很⼩的情况下以base64 的⽅式把⽂件内容注⼊到代码中去。
  2. babel-loader:把 ES6 转换成 ES5。
  3. postcss-loader:解决样式兼容性问题。

常用的plugin

  1. eslint-webpack-plugin:检查是否符合eslint规范。
  2. html-webpack-plugin:创建html文件并自动引入打包生成的js等资源。
  3. mini-css-extract-plugin:会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,在html中通过link标签加载。并且支持 CSS 和 SourceMaps 的按需加载。(production
  4. css-minimizer-webpack-plugin: css压缩。(production

webpack优化

1. 提升开发体验

SourceMap

SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。

它会生成一个 xxx.map 文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后代码出错了,会通过 xxx.map 文件,从构建后代码出错位置找到映射后源代码出错位置,从而让浏览器提示源代码文件出错位置,帮助我们更快的找到错误根源。

  • cheap-module-source-map: 打包编译速度快,只包含行映射 (development)
  • source-map:包含行/列映射 (production)

2. 提升打包构建速度

HMR

HotModuleReplacement(HMR/热模块替换):在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。可以做到修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模块不变,这样打包速度就能很快。(在webpack5 dev-server中默认配置开启)

  • style-loader
  • vue-loader
  • react-hot-loader

OneOf

打包时每个文件都会经过所有 loader 处理,配置OneOf可以让文件 匹配上一个 loader后, 剩下的就不匹配了。

Include/Exclude

第三方的库或插件,不需要编译可以直接使用。可以配置loader和plugin的exclude和include来排除一些文件。

Cache

配置loader和plugin对 Eslint 检查 和 Babel 编译结果进行缓存。这样第二次打包时速度就会更快了。

Thread

提升打包速度,其实就是要提升 js 的打包速度,因为其他文件都比较少。 而对 js 文件处理主要就是 eslint 、babel、Terser(压缩jsvascript) 三个工具,所以我们要提升它们的运行速度。 多进程打包:开启电脑的多个进程同时干一件事,速度更快。

需要注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为 600ms 左右开销。

  • thread-loader
  • terser-webpack-plugin(webpack5 自带)

3. 减少代码体积

Tree Shaking

Tree Shaking 是一个术语,通常用于描述移除 JavaScript 中的没有使用上的代码。 例如引用第三方工具函数库或组件库,不会打包整个库,只会打包我们引用的函数。

注意:它依赖 ES Module Webpack 已经默认开启了这个功能,无需其他配置。

Babel

Babel 为编译的每个文件都插入了辅助代码,使代码体积过大! 对一些公共方法使用了非常小的辅助代码,比如 _extend

你可以将这些辅助代码作为一个独立模块,来避免重复引入。

Image Minimizer

本地项目静态图片压缩

  • image-minimizer-webpack-plugin

4. 优化代码运行性能

Code Split

代码分割(Code Split)主要做了两件事:

  1. 分割文件:将打包生成的文件进行分割,生成多个 js 文件。
  2. 按需加载:需要哪个文件就加载哪个文件。

为什么需要Code Split:

打包代码时会将所有 js 文件打包到一个文件中,体积太大了。我们如果只要渲染首页,就应该只加载首页的 js 文件,其他文件不应该加载。

所以我们需要将打包生成的文件进行代码分割,生成多个 js 文件,渲染哪个页面就只加载某个 js 文件,这样加载的资源就少,速度就更快。

Preload Prefetch

使用 import 动态导入语法来进行代码按需加载(我们也叫懒加载,比如路由懒加载就是这样实现的)。 但是加载速度还不够好,比如:是用户点击按钮时才加载这个资源的,如果资源体积很大,那么用户会感觉到明显卡顿效果。

在浏览器空闲时间,加载后续需要使用的资源。我们就需要用上 Preload 或 Prefetch 技术。

  • Preload:告诉浏览器立即加载资源。
  • Prefetch:告诉浏览器在空闲时才开始加载资源。

Network Cache

浏览器可以对同名的文件进行缓存。打包时应尽量对只有内容变化的文件更改文件名。保证项目正确更新,且合理利用缓存。

  • fullhash
  • chunkhash
  • contenthast

配置optimization.runtimeChunk,额外生成runtime文件,文件只保存文件的 hash 值和它们与文件关系,使引用变化文件的文件名称不改变。

Core js

core-js 是专门用来做 ES6 以及以上 API 的 polyfill。解决js 兼容性问题。例如async 函数、promise 对象、数组的一些方法(includes)等(低版本浏览器会直接报错)。

自动按需加载,使用到的core-js的包。

// babel.config.js
module.exports = {
  // 智能预设:能够编译ES6语法
  presets: [
    [
      "@babel/preset-env",
      // 按需加载core-js的polyfill
      { useBuiltIns: "usage", corejs: { version: "3", proposals: true } },
    ],
  ],
};

webpack-dev-server

提供了一个基本的 web server,并具有实时重新加载的功能。

budle, chunk, module是什么

bundle:是由 webpack 打包出来的⽂件;

chunk:代码块,⼀个 chunk 由多个模块组合⽽成,⽤于代码的合并和分割;

module:是开发中的单个模块,在 webpack 的世界,⼀切皆模块,⼀个模块对应⼀个⽂件, webpack 会从配置的 entry 中递归开始找出所有依赖的模块。

以上内容均是 由尚硅谷 Web 前端之Webpack5教程总结,列了大纲,方便梳理。 教程地址:yk2012.github.io/sgg_webpack…

视频教程地址:www.bilibili.com/video/BV14T…