美文网首页前端
webpack中Loader的深入理解

webpack中Loader的深入理解

作者: any_5637 | 来源:发表于2020-05-06 11:07 被阅读0次

之前在开发过程中一虽然了解过一些webpcak的基础知识,但是对webpack的流程还是知道的太少,所以这次学习了下webpack中loader的知识。

webpack 工作流程

关于 webpack 的工作流程,简单来说可以概括为以下几步:
1、参数解析
2、找到入口文件
3、调用 Loader 编译文件
4、遍历 AST,收集依赖
5、生成 Chunk
6、输出文件

关于 Loader

Loader 的作用很简单,就是处理任意类型的文件,并且将它们转换成一个让 webpack 可以处理的有效模块。

  1. Loader 的配置和使用
    1.1 在 config 里配置
    Loader 可以在 webpack.config.js里配置,这也是推荐的做法,定义在 module.rules 里:
// webpack.config.js
module.exports = {
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'postcss-loader' },
        ]
      }
    ]
  }
};

每一条 rule 会包含两个属性:test 和 use,比如 { test: /.js$/, use: 'babel-loader' } 意思就是:当 webpack 遇到扩展名为 js 的文件时,先用 babel-loader 处理一下,然后再打包它。
use 的类型:string|array|object|function:
string: 只有一个 Loader 时,直接声明 Loader,比如 babel-loader。
array: 声明多个 Loader 时,使用数组形式声明,比如上文声明 .css 的 Loader。
object: 只有一个 Loader 时,需要有额外的配置项时。
function: use 也支持回调函数的形式。
注意: 当 use 是通过数组形式声明 Loader 时,Loader 的执行顺序是从右到左,从下到上。比如暂且认为上方声明是这样执行的:
postcss-loader -> css-loader -> style-loader
其实就是:

styleLoader(cssLoader(postcssLoader(content)))

1.2 内联
可以在 import 等语句里指定 Loader,使用 ! 来将 Loader分开:

import style from 'style-loader!css-loader?modules!./styles.css';

内联时,通过 query 来传递参数,例如 ?key=value。

一般来说,推荐使用统一 config 的形式来配置 Loader,内联形式多出现于 Loader 内部,比如 style-loader 会在自身代码里引入 css-loader:

require("!!../../node_modules/css-loader/dist/cjs.js!./styles.css");
  1. Loader 类型
    2.1 同步 Loader
module.exports = function(source) {
  const result = someSyncOperation(source); // 同步逻辑
  return result;
}

一般来说,Loader 都是同步的,通过 return 或者 this.callback 来同步地返回 source转换后的结果。
2.2 异步 Loader
在 Loader 里做一些异步的事情,比如说需要发送网络请求。如果同步地等着,网络请求就会阻塞整个构建过程,这个时候我们就需要进行异步 Loader,可以这样做:

module.exports = function(source) {
  // 告诉 webpack 这次转换是异步的
  const callback = this.async();
  // 异步逻辑
  someAsyncOperation(content, function(err, result) {
    if (err) return callback(err);
    // 通过 callback 来返回异步处理的结果
    callback(null, result, map, meta);
  });
};

2.3 Pitching Loader

{
  test: /\.js$/,
  use: [
    { loader: 'aa-loader' },
    { loader: 'bb-loader' },
    { loader: 'cc-loader' },
  ]
}

Loader 总是从右到左被调用。上面配置的 Loader,就会按照以下顺序执行:
cc-loader -> bb-loader -> aa-loader
每个 Loader 都支持一个 pitch 属性,通过 module.exports.pitch 声明。如果该 Loader 声明了 pitch,则该方法会优先于 Loader 的实际方法先执行,官方也给出了执行顺序:

|- aa-loader `pitch`
  |- bb-loader `pitch`
    |- cc-loader `pitch`
      |- requested module is picked up as a dependency
    |- cc-loader normal execution
  |- bb-loader normal execution
|- aa-loader normal execution

也就是会先从左向右执行一次每个 Loader 的 pitch 方法,再按照从右向左的顺序执行其实际方法。

Loader 工作流程简述

我们来回顾一下 Loader 的一些特点:

  Loader 是一个 node 模块;
  Loader 可以处理任意类型的文件,转换成 webpack 可以处理的模块;
  Loader 可以在 webpack.config.js 里配置,也可以在 require 语句里内联;
  Loader 可以根据配置从右向左链式执行;
  Loader 接受源文件内容字符串或者 Buffer;
  Loader 分为多种类型:同步、异步和 pitching,他们的执行流程不一样;

webpack 为 Loader 提供了一个上下文,有一些 api 可以使用;
我们根据以上暂时知道的特点,可以对 Loader 的工作流程有个猜测,假设有一个 js-loader,它的工作流程简单来说是这样的:

  1. webpack.config.js 里配置了一个 js 的 Loader;
  2. 遇到 js 文件时,触发了 js-loader;
  3. js-loader 接受了一个表示该 js 文件内容的 source;
  4. js-loader 使用 webapck 提供的一系列 api 对 source 进行转换,得到一个 result;
  5. 将 result 返回或者传递给下一个 Loader,直到处理完毕。
    未完待续。。。

相关文章

  • webpack中Loader的深入理解

    之前在开发过程中一虽然了解过一些webpcak的基础知识,但是对webpack的流程还是知道的太少,所以这次学习了...

  • loader初识

    loader 介绍 loader让webpack能够去处理那些非JavaScript文件(webpack自身只理解...

  • webpack学习笔记【二】:打包样式资源

    loader webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的...

  • webpack学习:plugin

    1.plugin和loader的区别 loader: webpack只能理解JavaScript和JSON文件。l...

  • 8-webpack-less-loader使用

    这里webpack中loader处理规则,问题,解决方法 一.webpack中loader处理规则 判断当前需要打...

  • 7 webpack + vue-loader

    vue-loader vue-loader基于webpack webpack+vue-loader

  • 如何理解webpack中的loader概念

    抛弃commonjs规范不提,webpack通过分析入口文件中esm的导入语法进行递归文件寻找,众所周知导入js时...

  • webpack4打包css,html

    webpack安装 webpack打包css 安装style-loader css-loader webpack打...

  • webpack中loader笔记

    loader loader是做什么的? 众所周知,webpack中万物皆模块,但是呢webpack默认只能处理js...

  • webpack

    webpack 唯一功能:打包loader,没有loader,webpack只能打包js,有了loader,可以打...

网友评论

    本文标题:webpack中Loader的深入理解

    本文链接:https://www.haomeiwen.com/subject/twuightx.html