自定义Loader

69 阅读1分钟

自定义webpack-loader

pnpm init

pnpm install webpack webpack-cli -D

新建 src/index.js

新建 webpack.config.js

image.png
webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  output: {
    path: path.resolve(__dirname, "./build"),
    filename: "bundle_[hash:8].js",
  },
  // 添加laoder的前缀
  resolveLoader: {
    modules: ["node_modules", "./my-loader"],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        // use: "./my-loader/loder1.js", // 没有resolveLoader之前
        use: ["loader1", "loader2"], // 执行顺序: 从右往左
      },
      {
        test: /\.js$/,
        use: "loader2",
        enforce: "post" // 控制某个loader优先执行
      },
    ],
  },
};

loader
// loader必须导出函数
module.exports = function(content, map, meta) {
  // content: 资源文件的内容
  // map: sourcemap相关配置
  // meta: 元数据
  console.log("loader1", content);
  return content;
};

以上就是loader的基本使用过程

1 同步loader和异步loader

默认创建的loader就是同步的loader.如果执行到loader函数的return时,这个loader就会结束,执行下一个loader.

注意: 执行顺序 先执行loader2 再执行loader1

同步loader

image.png

异步操作

image.png

都是同步loader时涉及异步操作的执行结果很鸡肋,同步建议手动进行return,或者使用async()

踩坑: 在使用this.async()之前,我用的是箭头函数发现this拿不到async.将箭头函数改为普通的函数

异步loader

image.png

2 loader传递参数

image.png
// loader3.js
module.exports = function (content) {
  // 获取使用loader3时传递进来的参数,通过this.getOptions()
  const option = this.getOptions();
  console.log(option);
  // 可以使用schema-utils库对option进行校验
  console.log("loader3:", content);
  return content;
};

3 自定义解析markdown的laoder

image.png

使用md: 只是导入 => import './demo.md'

image.png image.png

开始编写处理代码

可以使用marked库: pnpm install marked -D

image.png

通过marked库转换,拿到内容并显示

image.png image.png

设置样式(通过标签)

image.png

让md的代码高亮起来

pnpm add highlight.js -D

image.png image.png

也可以使用highlight提供的默认样式

import "highlight.js/styles/default.css";