Webpack Loader和插件 | 青训营笔记

102 阅读4分钟

这是我参与「第五届青训营 」笔记创作活动的第20天。

一、本堂课的重点内容

  • Webpack Loader
  • Webpack 插件

二、详细知识点介绍

问题:Webpack只认识JS

Loader

处理非标准js资源,实现内容转化,用于将资源翻译为标准js

以处理less为例:

  • 安装loader,npm add -D css-loader style-loader less-loader
  • 添加module处理css文件
module: {
  rules: [{
    test: /.less$/i,
    use: [
      "style-loader",
      "css-loader",
      "less-loader"
    ]
  }]
}

Loader的链式调用

前面loader的输出作为后面loader的输入,各个loader内部的功能比较内聚。

image.png

处理less的Loader的运行流程:

  • less-loader:实现less到css的转换
  • css-loader:将CSS包装成类似module.exports="${css}"的内容,包装后的内容符合JavaScript语法
  • style-loader:将css模块包进require语句,并在运行时调用injectStyle等函数将内容注入到也没的style标签。

image.png

在Webpack的Loader Runner内,进入Webpack的make函数,先调用less-loader,将less的内容转化成一段css代码,进入css-loader中,css-loader输出一个字符串,再进入style-loader中,生成一段包含injectStyleIntoStyleTag的函数,在浏览器运行时会执行该函数,将css代码插入到HTML页面中。

pitch阶段根据Webpack的config的module中use数组定义的顺序,依次向后执行,任意loader的pitch阶段有返回值就会停止后面的执行,可用于做catch。

执行阶段从数组的最后一项开始执行,通过链式调用不断向前调用,直到执行结束变成标准的js代码,回到Webpack中。

执行特点:

  • 链式执行
  • 支持异步执行
  • 分normal、pitch两种模式

ndb npx webpack可通过ndb进行调试。

编写loader

loader格式:

module.exports = function (source, sourceMap, data) {
  //source为源码内容
  //sourceMap可选,若前面的loader生成了sourceMap,则会传入
  //data可选,其他的信息
  return source;
};

常用Loader:

image.png

插件

插件能提高整个工具或应用的扩展性

插件架构的精髓:对扩展开放,对修改封闭;应用只做最核心的部分,但是开放一系列的扩展和修改方式,可以通过扩展和修改方式扩充细节。

Webpack是一堆插件组合的结果

插件的使用

  • 安装插件,npm add -D xxx
  • 导入插件,const xxx=require('xxx')
  • 在webpack.config.js中new一个插件的实例,plugins:[new 插件名()],有的插件需要传入参数

理解插件

钩子:

  • 时机,编译过程的特定节点,Webpack会以钩子形式通知插件此刻正在发生的事,compier.hooks.compilation
  • 上下文,通过tapable提供的回调机制,以参数方式传递上下文信息,compilation
  • 交互,在上下文参数对象中附带了很多存在side effect的交互接口,插件可以通过这些接口改变,dependencyFactories.set

image.png

Webpack学习方法

入门应用

  • 理解Webpack打包流程
  • 熟练掌握常用配置项、Loader、插件使用方法,能够灵活搭建集成Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的Webpack环境
  • 掌握常见脚手架工具的用法,如Vue-cli、create-react-app、@angular/cli,提升效率
  • 能用起来,知道怎么用,知道是干嘛的

进阶

  • 理解Loader、Plugin机制,能够自行开发Webpack组件,通过自己写提高理解深度
  • 理解常见性能优化手段,并能用于解决实际问题,如cache等
  • 理解前端工程化概念与生态现状,与Vite等框架的比较

大师级

阅读源码,理解Webpack编译、打包原理,甚至能够参与共建

image.png

三、实践练习例子

ESlint Loader示例: eslint-loader/index.js at master · webpack-contrib/eslint-loader (github.com)

import getOptions from './getOptions';
import Linter from './Linter';
import cacheLoader from './cacheLoader';

export default function loader(content, map) {
  const options = getOptions(this);
  const linter = new Linter(this, options);

  this.cacheable();

  // return early if cached
  if (options.cache) {
    cacheLoader(linter, content, map);
    return;
  }

  linter.printOutput(linter.lint(content));
  this.callback(null, content, map);
}

四、课后个人总结

本节课学习了Webpack的Loader和插件的用法和原理,Webpack通过Loader,处理非js文件,将非js文件转为js。而插件使Webpack更具扩展性,通过学习理解了插件的精髓,对扩展开放,对修改封闭。本节课还学习了Webpack的学习路线,了解了不同阶段应达到的目标。Webpack作为前端工程化重要的编译、打包和压缩工具,需要进一步学习研究。

五、参考链接

Webpack 原理系列七:如何编写loader (qq.com)

‌⁤‍‬⁤‌⁤‌⁤​‌​​⁤⁤‬‌⁤‌⁤⁣‬⁤‍⁤‬‬​‍‍⁤​⁣​⁡⁤​​​‬‌​‍⁡⁤Webpack 知识体系.pptx - 飞书云文档 (feishu.cn)