美文网首页
如何编写自定义webpack loader?

如何编写自定义webpack loader?

作者: 努力学习的小丸子 | 来源:发表于2021-06-22 09:23 被阅读0次

https://webpack.docschina.org/contribute/writing-a-loader/

书写规范

loader 需导出一个函数

监听文件实时编译

const path = require("path");
const fs = require("fs");
export default function (source) {
  var callback = this.async();
  var headerPath = path.resolve("header.js");
  // 当header.js文件发生改变时会触发编译
  this.addDependency(headerPath);

  fs.readFile(headerPath, "utf-8", function (err, header) {
    if (err) return callback(err);
    callback(null, header + "\n" + source);
  });
}
webpack 5 新特性

webpack 5 发布后,在 loader 的上下文中,会带有内置的 this.getOptions 方法。这对于那些使用之前推荐 schema-utils 中的 getOptions 方法的 loader 而言,这是一个重大更新。

模块依赖

根据模块的类型,可以使用不同的模式来指定依赖项。例如在CSS中,使用@import和url(…)语句。这些依赖关系应该由模块系统来解决。
这可以通过两种方式之一来实现:

  • 通过将它们转换为require语句。
  • 使用 this.resolve 解析路径函数。

对于 less-loader ,它不能将每个@import转换为require,因为所有的.less文件必须一次编译一次,用于变量和mixin跟踪。因此,less loader使用自定义路径解析逻辑扩展了less compiler。然后它利用了第二种方法this.resolve来解析依赖。

绝对路径

不要在模块代码中插入绝对路径,因为当项目的根被移动时,它们会破坏散列。loader-utils中有一个stringifyRequest方法,可以用来将绝对路径转换为相对路径。

jtest 测试

使用webpack和memfs来避免输出文件到磁盘

// compiler.js
import path from 'path';
import webpack from 'webpack';
import { createFsFromVolume, Volume } from 'memfs';
export default (fixture, options = {}) => {
    const compiler = webpack({
        context: __dirname,
        entry: `./${fixture}`,
        output: {
            path: path.resolve(__dirname),
            filename: 'bundle.js',
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: 'replace-loader',
                        options,
                    },
                },
            ],
        },
        resolveLoader: {
            modules: ["../loader"], // 配置loader的查找目录
        },
    });
    compiler.outputFileSystem = createFsFromVolume(new Volume());
    compiler.outputFileSystem.join = path.join.bind(path);
    return new Promise((resolve, reject) => {
        compiler.run((err, stats) => {
            if (err) reject(err);
            if (stats.hasErrors()) reject(stats.toJson().errors);
            resolve(stats);
        });
    });
};
// loader.test.js
import compiler from './compiler.js';

test('Inserts name and outputs JavaScript', async () => {
    const stats = await compiler('example.js', { name: 'Alice' });
    const output = stats.toJson({ source: true }).modules[0].source;
    console.log(output);
    expect(output).toBe("console.log('hello Alice');");
});
// example.js
console.log('hello world');
// package.json
"test": "jest"

其他代码:

// loader/replace-loader.js
// 注意导出的函数不能是箭头函数
// webpack 5 发布后,在 loader 的上下文中,会带有内置的 this.getOptions 方法。
// 这对于那些使用之前推荐 schema-utils 中的 getOptions 方法的 loader 而言,这是一个重大更新:
import { getOptions } from 'loader-utils';
import { validate } from 'schema-utils';
const schema = {
    type: 'object',
    properties: {
        test: {
            type: 'string'
        }
    }
};
export default function(source) {
    const options = getOptions(this);
    validate(schema, options, {
        name: 'Example Loader',
        baseDataPath: 'options'
    });
    return source.replace(/world/g, options.text);
}
// vue.config.js
configureWebpack: {
    module: {
      rules: [
        {
          test: /\.js$/i,
          use: ["replace-loader"],
        },
      ],
    },
    resolveLoader: {
      modules: ["./node_modules", "./loader"], // 配置loader的查找目录
    },
  }

相关文章

  • 如何编写自定义webpack loader?

    https://webpack.docschina.org/contribute/writing-a-loader...

  • 怎么编写一个 webpack loader

    编写 loader 前需要知道 webpack loader 的执行循序?从右到左执行。 为什么 webpack ...

  • 编写 webpack loader

    loader loader 用于对模块的源代码进行转换。loader 可以使你在 import 或 "load(加...

  • 编写 webpack Loader

    loader 类型 pre post normal inline 行内 loader 1、2、3 通过修改 loa...

  • webpack

    一、 1.webpack通过loader可以支持各种语言和预处理器编写模块。webpack的各种loader描述了...

  • 如何写一个 webpack loader

    本文主要讲如何快速写一个 webpack loader 和如何调试 webpack loader. 01 背景 w...

  • 编写 webpack loader(一)

    用过webpack的人都知道处理各种资源的时候要用到loader,比如babel-loader可以将ES6转化为E...

  • [转]webpack loader编写

    webpack简介 tapable(webpack控制事件流的超级管家) Tapable的核心功能就是依据不同的钩...

  • 轻量webpack脚手架 bicycle

    why 每次新建工程都要手动搭建基本的webpack项目结构(安装各种loader、编写webpack.confi...

  • webpack原理

    写在前面:本文是webpack的一个学习笔记,涉及webpack打包流程、plugin、loader的编写、以及实...

网友评论

      本文标题:如何编写自定义webpack loader?

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