webpack5 loader

2023-11-11

作用

  • webpack只会处理js、json文件,当需要处理其它类型的文件就需要添加对应的loader
  • 在使用require()/import语句时,先用对应的loader处理后,再加入打包后的boundle中

基本使用

  • test:匹配要处理的文件
    • /.txt$/:匹配任何以 .txt 结尾的文件
    • “/.txt$/”: 匹配具有绝对路径 ‘.txt’ 的单个文件
  • use:添加处理的loader
    • 同一个use中loader处理顺序为从右到左,从下到上
module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
};
  • 为 import 语句添加前缀启动指定类型loader
    • “!”禁止所有普通loader
    • “!!”禁止preLoaders、loaders、postLoaders
    • “-!”禁止preLoaders、loaders
// 禁用普通 loaders
import { a } from '!./file1.js';
// 禁用前置和普通 loaders
import { b } from '-!./file2.js';
// 禁用所有的 laoders
import { c } from '!!./file3.js';

内联loader

  • 使用 ! 将资源中的 loader 分开。loader加载顺序和上方相同
  • 传递loader参数使用?key=value&foo=bar或者{key":“value”,“foo”:“bar”}.
import Styles from 'style-loader!css-loader?modules!./styles.css';
  • 为内联 import 语句添加前缀启动指定类型loader
    • “!”禁止所有普通loader
    • “!!”禁止preLoaders、loaders、postLoaders
    • “-!”禁止preLoaders、loaders
import Styles from '!style-loader!css-loader?modules!./styles.css';
import Styles from '!!style-loader!css-loader?modules!./styles.css';
import Styles from '-!style-loader!css-loader?modules!./styles.css';

loader执行顺序

Loader 之间按照配置的顺序从前到后先执行 pitch 方法,再从后到前依次执行主方法

  • Less 文件的处理流程
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/i,
        use: [
          "style-loader",
          "css-loader",
          "less-loader",
        ],
      },
    ],
  },
};

在这里插入图片描述
在这里插入图片描述

loader pitch

  • loader.pitch 出现的原因:
    • Loader 链条一旦启动之后,需要所有 Loader 都执行完毕才会结束,没有中断的机会 —— 除非显式抛出异常
    • 某些场景下并不需要关心资源的具体内容,但 Loader 需要在 source 内容被读取出来之后才会执行
const loader = function (source){
    console.log('后执行')
    return source;
}

loader.pitch = function(remainingRequest: string, previousRequest: string, data) {
    console.log('先执行')
}

module.exports = loader
  • remainingRequest : 当前 loader 之后的资源请求字符串
  • previousRequest : 在执行当前 loader 之前经历过的 loader 列表
  • data : 与 Loader 函数的 data 相同,用于传递需要在 Loader 传播的信息
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/i,
        use: [
          "style-loader", "css-loader", "less-loader"
        ],
      },
    ],
  },
};

// css-loader.pitch 中拿到的参数依次为:
// css-loader 之后的 loader 列表及资源路径
remainingRequest = less-loader!./xxx.less
// css-loader 之前的 loader 列表
previousRequest = style-loader
// 默认值
data = {}
  • 中断 pitch

在这里插入图片描述

  • pitch示例

    • less-loader :将 less 规格的内容转换为标准 css
    • css-loader :将 css 内容包裹为 JavaScript 模块
    • style-loader :将 JavaScript 模块的导出结果以 link 、style 标签等方式挂载到 html 中,让 css 代码能够正确运行在浏览器上
      • style-loader 只是负责让 css 能够在浏览器环境下跑起来,本质上并不需要关心具体内容,很适合用 pitch 来处理
//style-loader pitch处理后结果,可以看到具体内容的转换交给其他loader进行处理
var api = require('xxx/style-loader/lib/runtime/injectStylesIntoLinkTag.js')
var content = require('!!css-loader!less-loader!./xxx.less');

在这里插入图片描述

  • 所以从 webpack 的角度看,实际上对同一个文件调用了两次 loader 链,第一次在 style-loader 的 pitch 中断,第二次根据 inline loader 的内容跳过了 style-loader。

自定义loader

  • 查找loader

// 方法1:直接给loader指定绝对路径
const path = require('path')
module: {
  rules: [
    {
      test: /\.js$/,
      loader: path.resolve(__dirname, 'loader/babel-loader.js'),
      exclude: /node_modules/
    }
  ]
}

// 方法2:配置resolveLoader的别名与其绝对路径,然后在rules中直接使用别名
const path = require('path')
resolveLoader: {
  alias: {
    'babel-loader': path.resolve(__dirname, 'loader/babel-loader.js')
  }
},
module: {
  rules: [
    {
      test: /\.js$/,
      use: 'babel-loader',
      exclude: /node_modules/
    }
  ]
}

// 方法3:配置resolveLoader的模块,通过修改loader查找的目录(默认在node_modules文件中查找)
const path = require('path')
resolveLoader: {
  // 优先使用我们自定义的loader目录中的loader
  modules: [path.resolve(__dirname, 'loader'), path.resolve(__dirname, 'node_modules')]
},
module: {
  rules: [
    {
      test: /\.js$/,
      use: 'babel-loader',
      exclude: /node_modules/
    }
  ]
}
  • loader方法参数

module.exports = function(source, sourceMap?, data?) {
  // source 为 loader 的输入,可能是文件内容,也可能是上一个 loader 处理结果
  return source;
};
  • source:资源输入,对于第一个执行的 loader 为资源文件的内容;后续执行的 loader 则为前一个 loader 的执行结果

  • sourceMap: 可选参数,代码的 sourcemap 结构

  • data: 可选参数,其它需要在 Loader 链中传递的信息,比如 posthtml/posthtml-loader 就会通过这个参数传递参数的 AST 对象

  • 同步loader

  • return方式

export default function rawLoader(source) {
  // ...

  const json = JSON.stringify(source)
    .replace(/\u2028/g, '\\u2028')
    .replace(/\u2029/g, '\\u2029');

  const esModule =
    typeof options.esModule !== 'undefined' ? options.esModule : true;

  return `${esModule ? 'export default' : 'module.exports ='} ${json};`;
}
  • this.callback方式

export default function loader(content, map) {
  // ...
  linter.printOutput(linter.lint(content));
  this.callback(null, content, map);
}
// this.callback 的完整签名如下 
this.callback(
    // 异常信息,Loader 正常运行时传递 null 值即可
    err: Error | null,
    // 转译结果
    content: string | Buffer,
    // 源码的 sourcemap 信息
    sourceMap?: SourceMap,
    // 任意需要在 Loader 间传递的值
    // 经常用来传递 ast 对象,避免重复解析
    data?: any
);
  • 异步loader

import less from "less";

async function lessLoader(source) {
  // 1. 获取异步回调函数,this.async 返回的异步回调函数签名与 this.callback 相同
  const callback = this.async();
  // ...

  let result;

  try {
    // 2. 调用less 将模块内容转译为 css
    result = await (options.implementation || less).render(data, lessOptions);
  } catch (error) {
    // ...
  }

  const { css, imports } = result;

  // ...

  // 3. 转译结束,返回结果
  callback(null, css, map);
}

export default lessLoader;
  • 缓存

    • 默认情况下 Webpack 会缓存 Loader 的执行结果直到资源或资源依赖发生变化
    • 必要时可以通过 this.cachable 显式声明不作缓存
module.exports = function(source) {
  this.cacheable(false);
  // ...
  return output;
};
  • loader上下文接口

    • 常用的接口
const loaderContext = {
    // 获取当前 Loader 的配置信息
    getOptions: schema => {},
    // 添加警告
    emitWarning: warning => {},
    // 添加错误信息,注意这不会中断 Webpack 运行
    emitError: error => {},
    // 解析资源文件的具体路径
    resolve(context, request, callback) {},
    // 直接提交文件,提交的文件不会经过后续的chunk、module处理,直接输出到 fs
    emitFile: (name, content, sourceMap, assetInfo) => {},
    // 添加额外的依赖文件
    // watch 模式下,添加的依赖文件发生变化时会触发资源重新编译
    addDependency(dep) {},
};
  • addDependency 在 less loader的使用

  try {
    result = await (options.implementation || less).render(data, lessOptions);
  } catch (error) {
    // ...
  }

  const { css, imports } = result;

  imports.forEach((item) => {
    // 调用 this.addDependency 函数将 import 到的其它资源都注册为依赖,之后这些其它资源文件发生变化时都会触发重新编译。
    this.addDependency(path.normalize(item)); // /Users/xx/Desktop/webpack/wb/src/css/5.less"
  });
  • loader常用工具

    • loader-utils

      • 提供了一系列诸如读取配置、requestString 序列化与反序列化、计算 hash 值之类的工具函数
    • schema-utils

      • 参数校验工具
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

webpack5 loader 的相关文章

  • 在打字稿中导入 json

    我是 typescript 的新手 在我的项目中 我们使用 typescript2 在我的要求之一中 我需要导入 json 文件 所以我创建了 d ts 文件如下 test d ts declare module json const va
  • Bootstrap按钮加载+Ajax

    我正在使用 Twitter Bootstrap 的按钮加载状态 http twitter github com bootstrap javascript html buttons http twitter github com bootst
  • 防止 iOS 键盘在 cordova 3.5 中滚动页面

    我正在使用 Cordova 3 5 和 jQuery mobile 构建 iOS 应用程序 我在大部分应用程序中禁用了滚动功能 但是 当我选择输入字段时 iOS 键盘会打开并向上滚动页面 我不想要这个功能 由于输入足够高 键盘不会覆盖它 我
  • 如何纠正流警告:解构(缺少注释)

    我正在编写一个小型 React Native 应用程序 并且正在尝试使用 Flow 但我无法在任何地方真正获得有关它的正确教程 我不断收到错误 destructuring Missing annotation 有关 station 这段代码
  • 调整图像大小并将画布旋转 90 度

    这里有很多关于在 js 上使用画布旋转图像的主题 我阅读了其中的大部分内容 但无法找到解决我的问题的方法 我正在接收任何分辨率的图像 来自上传组件 我将其大小调整为 1024x768 如下所示 var canvas document cre
  • 如何制作没有 ng-repeat 的模板并使用 Angular-drag-and-drop-lists 将数据传递到 $scope?

    我想用角度拖放列表 https github com marceljuenemann angular drag and drop lists使用我自己的网格模板到所见即所得编辑器 如何构建我自己的 HTML 模板而不需要ng repeat因
  • 使用 CSS 或 Javascript 填充动画

    我只是想知道是否可以使用 CSS 或 javascript 创建填充动画 基本上我想创建一个填充动画 如下图所示 http i40 tinypic com eit6ia png http i40 tinypic com eit6ia png
  • 在 HTML5 画布中,如何用我选择的背景遮盖图像?

    我试图用画布来实现这一点 globalCompositeOperation 但没有运气 所以我在这里问 这里有类似的问题 但我没有在其中找到我的案例 我的画布区域中有图层 从下到上的绘制顺序 画布底座填充纯白色 fff 用fillRect
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • window.location 和 location.href 之间的区别

    我对之间的区别感到困惑window location and location href 两者似乎都以相同的方式行事 有什么不同 window location是一个对象 它保存有关当前文档位置的所有信息 主机 href 端口 协议等 lo
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • DataTables row.add 到特定索引

    我正在替换这样的行项目 var targetRow entity row dataTable targetRow closest table dataTable DataTable dataTable row targetRow remov
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • Javascript 假值(null、未定义、false、空字符串:“”或 '' 和 0)和比较(==)运算符 [重复]

    这个问题在这里已经有答案了 当我使用任何一个值时 null undefined false 0 in a if陈述 它总是被评估为谬误 false 另外 这些值的否定 null undefined false 0 in a if语句总是被评
  • 正则表达式 - 从 markdown 字符串中提取所有标题

    我在用灰质 https www npmjs com package gray matter 以便将文件系统中的 MD 文件解析为字符串 解析器产生的结果是这样的字符串 n Clean er ReactJS Code Conditional
  • 在移动设备上滚动

    这个问题更多的是一个建议研究 我确实希望它对其他人有帮助 并且它不会关闭 因为我不太确定在哪里寻求有关此事的建议 在过去的 6 个月里 我一直在进行移动开发 我有机会处理各种设备上的各种情况和错误 最麻烦的是滚动问题 当涉及到在网站的多个区
  • 在 Javascript 中连接空数组

    我正在浏览一些代码 我想知道这有什么用处 grid push concat row 根据我的理解 它等同于 grid push row 为什么要大惊小怪 连接 你想使用 concat当您需要展平数组并且没有由其他数组组成的数组时 例如 va
  • 用于交互式图形绘制的轻量级 JavaScript 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有兴趣了解用于绘制交互式图表的最轻量级 javascript 库 我掌握的数据主要是与海洋研究相关的科学数据 我知道一些 jquery
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz
  • JavaScript 相对路径

    在第一个 html 文件中 我使用了一个变量类别链接 var categoryLinks Career prospects http localhost Landa DirectManagers 511 HelenaChechik Dim0

随机推荐

  • java面向对象(一)

    面向对象 类对象方法 类的定义 作用域修饰词 一个类可以包含以下类型变量 static静态 静态变量类变量 静态方法 static代码块 final 修饰方法 修饰变量 static final 方法 构造方法特殊的方法 创建对象 访问成员
  • 什么是神经网络架构搜索?

    https mp weixin qq com s F6ZbX2JVqSOAhE2hXBnLLA
  • 洛谷 1969 积木大赛——水题

    题目 https www luogu org problemnew show P1969 include
  • 常见的几种网络故障案例分析与解决

    故障1 交换机刚加电时网络无法通信 故障现象 交换机刚刚开启的时候无法连接至其他网络 需要等待一段时间才可以 另外 需要使用一段时间之后 访问其他计算机的速度才快 如果有一段时间不使用网络 再访问的时候速度又会慢下来 故障分析 由于这台交换
  • 完全背包问题求组合数和排列数

    518 零钱兑换 II 这个是完全背包问题的典型应用 由于只是求个数 不涉及到零钱排列情况不一样算两次的情况 所以两层for循环 外层遍历物品 内层遍历背包 class Solution public int change int amou
  • 阿里云播放器prismplayer抓包的一些理解

    Prismplayer是一套在线视频播放技术方案 同时支持Flash和Html5两种播放技术 可对播放器进行功能配置和皮肤定制 其在线使用文档地址为 入口 在甘肃交通视频云联网平台中用的就是该播放器 通过抓包发现 播放的是hls的ts流 下
  • mysql存储过程

    CREATE DEFINER root localhost PROCEDURE test BEGIN DECLARE i int DEFAULT 0 DECLARE classSize int DEFAULT 0 SELECT count
  • 给jupter设置新环境

    文章目录 给jupternotebook设置新环境 遇到的报错 添加路径的方法 给jupternotebook设置新环境 先在anaconda界面新建环境 conda env list 查看conda prompt下的有的环境变量 带星号的
  • Vue2使用插件合集

    Quill 插件描述 Vue 富文本编辑器 1 下载 vue quill editor npm i vue quill editor S 2 将vue quill editor引入到main js import VueQuillEditor
  • 任务调度器leetcode621

    问题 来自LeetCode 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表 其中每个字母表示一种不同种类的任务 任务可以以任意顺序执行 并且每个任务都可以在 1 个单位时间内执行完 在任何一个单位时间 CPU 可以完成一
  • springcloudgateway集成hystrix

    目录 一 pom引入依赖 二 RestTemplate开启ribbon的负载均衡 LoadBalanced 三 yml配置和熔断降级的fallback接口 四 技术资料 springcloudgateway和Hystrix springcl
  • 如何设计高性能的分布式锁

    什么是分布式锁 在 JVM 中 在多线程并发的情况下 我们可以使用同步锁或 Lock 锁 保证在同一时间内 只能有一个线程修改共享变量或执行代码块 但现在我们的服务都是基于分布式集群来实现部署的 对于一些共享资源 在分布式环境下使用 Jav
  • Antd Table 可编辑表格

    antd Table 官方文档提及了 可编辑单元格 可编辑行 这里解决 可编辑表格 主要思路是将 antd Table 可编辑行 与 antd Form List 相结合 将Table视为 Form List 中循环的 Form Item
  • 如何使用Hexo搭建属于自己的博客

    Hexo安装步骤 Hexo官网 环境准备 Nodejs Git node v npm v 安装Hexo npm install hexo cli g cd到你需要创建博客的文件夹 hexo init blog cd blog npm ins
  • Ubuntu系统连接罗技K380键盘

    近日向学习LInux系统的使用 便把windows系统卸载装上了Ubuntu 下面是罗技K380连接Ubuntu 系统的方法 先打开K380键盘的蓝牙 我选择2 然后进入电脑的终端 输入如下命令 bluetoothctl devices 此
  • 超详细的tomcat的下载安装和配置教程

    tomcat运行的前提是安装并配置了JDK 若没有安装配置JDK 先去安装配置JDK 如下链接 JDK 1 8的下载安装和环境变量的配置 详细步骤 一 下载tomcat 1 进入tomcat的下载 tomcat下载官网 2 点击进入 点击
  • FastDFS在Docker集群安装

    一 简介 FastDFS是由国人余庆所开发 其项目地址 https github com happyfish100 FastDFS是一个轻量级的开源分布式文件系统 主要解决了大容量的文件存储和高并发访问的问题 文件存取时实现了负载均衡 Fa
  • 基于Matlab模拟宇宙射线μ

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 更多Matlab仿真内容点击 智能优化算法 神经网络预测 雷达通信 无线传感器 电力系统 信号
  • springboot+react实现前后端交互

    一 搭建springboot后台 1 创建一个Springboot项目 然后导入pom依赖 本着一切从简的原则 如果不连接数据库的话 有个spring boot starter web的依赖就够用了
  • webpack5 loader

    文章目录 作用 基本使用 内联loader loader执行顺序 loader pitch 中断 pitch pitch示例 自定义loader 查找loader loader方法参数 同步loader return方式 this call