# loader 编写

# loader是什么?

  • loader 用于对模块的源代码进行转换
  • loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。
  • loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

# loader 特性

  • loader 从右到左(或从下到上)地取值(evaluate)/执行(execute)。
  • 支持链式调用
  • loader 可以是同步的,也可以是异步的。
  • loader 运行在 Node.js 中,并且能够执行任何操作。
  • loader 可以通过 options 对象配置
  • loader 能够产生额外的任意文件
  • loader 遵循标准 模块解析 (opens new window) 规则
    • 绝对路径(相对于本机的路径)- 由于已经获得文件的绝对路径,因此不需要再做进一步解析。

    • 相对路径 (自己写的项目) - 使用 import 或 require 的资源文件所处的目录,被认为是上下文目录。在 import/require 中给定的相对路径,会拼接此上下文路径,来生成模块的绝对路径。

      /User/ReadingNotes/view/index.js 文件内容如下
      
      import utils from '../utils'
      
      那么 /User/ReadingNotes/view/会被认为是上下文路径,
      
      最终引用的utils文件路径是 /User/ReadingNotes/utils/index.js
      
      
      1
      2
      3
      4
      5
      6
      7
      8
    • 模块路径 (opens new window)(第三方Npm包)- 在 webpack.config.js 的 resolve.modules 中指定的所有目录检索模块,默认是当前项目的 node_modules

# loader的使用方式

# 配置方式 (最常用方式)

在 webpack.config.js 文件中指定 loader,需要配置在module.rules内部,

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // [style-loader](/loaders/style-loader)
          { loader: 'style-loader' },
          // [css-loader](/loaders/css-loader)
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          },
          // [sass-loader](/loaders/sass-loader)
          { loader: 'sass-loader' }
        ]
      }
    ]
  }
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 内联方式 (opens new window)

不常用见官方文档

# CLI 方式 (opens new window)

不常用见官方文档

# 写个Loader

# 必备知识

  • loader是一个导出函数的node 模块。当通过这个loader转换资源的时候会调用这个函数。这个函数将使用提供给它的this上下文访问Loader API。
  • 调用loader处理资源的时候,只会传递一个资源文件的内容字符串作为参数。同步的loader可以只简单返回一个字符串表示转换后的值。
  • 在更复杂的情况下,加载器可以使用this.callback(err,values ...)函数返回任意数量的值。
  • loader应返回一个或两个值。第一个值是作为字符串或缓冲区的结果JavaScript代码。The second optional value is a SourceMap as JavaScript object
  • 最后一个loader,作为首个调用的的loader.它将被传递原始资源的内容
  • 第一个loader,被最后调用。它应该返回一个JavaScript 和一个可选的 source map
  • 中间的loader将用前一个loader的结果执行。

# 遵循规则

  • loader要简洁
  • 链式调用
  • 模块化输出
  • 确保它们是无状态的
  • 使用 loader utilities
  • 标记 loader dependencies (opens new window)
  • Resolve module dependencies
  • 提取公共代码
  • 避免绝对路径
  • 使用 peerDependencies

# 文档

  1. loader Api (opens new window)
  2. loader 概念 (opens new window)
  3. loader-utils (opens new window)
  4. schema-utils (opens new window)