Webpack中的自定义 loader 的简单实现

1.loader简单介绍

webpack 中 loader 是用于对模块的源代码进行转换(处理)的插件。例如 webpack 中常见的loader, css-loader、babel-loader。

2.自定义 loader

关于 loader:

  • loader本质上是一个导出为函数的JavaScript模块,即函数;
  • loader runner库会调用这个函数,然后将上一个loader产生的结果或者资源文件传入进去;
  • 自定义 loader函数的接收参数有content(资源文件的内容)、map(sourcemap的数据)、meta(一些元数据);

例如自定义个 loader 并希望打包时指定类型文件能够经过自定义loader 的函数的处理:
自定义一个 hgf-loader01的 loader

javascript 复制代码
const { validate } = require('schema-utils')
const schema = require('../schema/loader01-schema.json')

module.exports = function(context) {

  console.log('testing hgf-custom-loader111111~~~~~~~~~~~~~~~~~~~');
  // 获取传入 options
  const options = this.getOptions()
  validate(schema, options)

  console.log('hgf-custom-Options~~~~~~~~~~~~~~~~~~', options);

  return context + 'hgf-custom-loader'
}


module.exports.pitch = function() {
  console.log('testing hgf-custom-loader111111-pitching~~~~~~~~~~~~~~~~~~~');

}

3.关于 pitching loader

webpack 的官方文档中有对 pitching loader 的介绍,即自定义 loader 中的 pitch 属性

4.多 loader 的执行流程、顺序

例如该 webpack 中配置多个 loader进行打包:

javascript 复制代码
const path = require('path')

module.exports = {
  entry: './src/main.js',
  mode: 'development',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test:/\.js$/i,
        use: {
          loader: 'hgf-loader01',
          options: {
            parameter1: 'hgf-loader01----parameter1',
            parameter2: 2222
          }
        },
        enforce: 'pre'
      },
      {
        test:/\.js$/i,
        use: {
          loader: 'hgf-loader02'
        }
      },
      {
        test:/\.js$/i,
        use: {
          loader: 'hgf-loader03'
        }
      }
    ]
  },
  resolveLoader: {
    modules: ['node_modules', './src/hgf-loader']
  }
}

loader 的内容

javascript 复制代码
// hgf-loader01
const { validate } = require('schema-utils')
const schema = require('../schema/loader01-schema.json')

module.exports = function(context) {

  console.log('testing hgf-custom-loader111111~~~~~~~~~~~~~~~~~~~');
  // 获取传入 options
  const options = this.getOptions()
  validate(schema, options)

  console.log('hgf-custom-Options~~~~~~~~~~~~~~~~~~', options);

  return context + 'hgf-custom-loader'
}


module.exports.pitch = function() {
  console.log('testing hgf-custom-loader111111-pitching~~~~~~~~~~~~~~~~~~~');

}



// hgf-loader02
module.exports = function(context) {

  console.log('testing hgf-custom-loader222222~~~~~~~~~~~~~~~~~~~');
  
  return context + 'hgf-custom-loader'
}

module.exports.pitch = function() {
  console.log('testing hgf-custom-loader222222-pitching~~~~~~~~~~~~~~~~~~~');

}



// hgf-loader03

module.exports = function(context) {

  console.log('testing hgf-custom-loader333333~~~~~~~~~~~~~~~~~~~');
  
  return context + 'hgf-custom-loader'
}

module.exports.pitch = function() {
  console.log('testing hgf-custom-loader333333-pitching~~~~~~~~~~~~~~~~~~~');

}

打包运行结果:

可看到从上往下依次运行 loader 的 pitching loader,再从下往上的运行 loader,pitching loader从上往下运行,可以在 pitching 阶段,传递给 pitch 方法的 data,在执行阶段也会暴露在 this.data 之下,并且可以用于在循环时,捕获并共享前面的信息。

a.webpack 的 resolveLoader 属性

webpack 中通过配置resolveLoader属性,设置 webpack 解析文件的查找来源

b.webpage 的 enforce 属性

webpack 中 loader 的执行顺序默认是从下往上依次执行 loader 对资源文件进行处理,但是 webpack 也提供了 enforce 属性,可以指定 loader 的执行顺序

"pre": 设置第一个执行, "post"设置最后一个执行

例如将上面代码的 loader 改为如下顺序,配置 enforce 属性后,loader 的执行顺序变化

可看出默认从下往上应该为 loader03 →loader02→loader01,配置 enforce 属性后,基于属性配置值进行了 loader 执行顺序的改变。

相关推荐
英俊潇洒美少年4 分钟前
前端性能优化:非关键脚本/第三方资源异步加载全解(彻底解决首屏阻塞)
前端·性能优化
开飞机的舒克_29 分钟前
vue3+router动态权限路由
前端·vue.js
VitoChang29 分钟前
放弃手搓路由吧!用 SolidStart 搞 SPA,真香
前端
GuWenyue29 分钟前
告别JS类型坑!Ts为什么在ai时代逐渐成为"第一"语言
前端·算法·typescript
三乐22832 分钟前
事件循环是什么东西,一篇文章带你了解
前端·javascript
wuhen_n33 分钟前
RAG 核心:向量嵌入与本地向量数据库实战
前端·langchain·ai编程
孟陬34 分钟前
国外技术周刊 #139:LLM 正在杀死程序员的「懒惰美德」
前端·人工智能·后端
lichenyang45343 分钟前
补充:Repeat 虚拟滚动与 cachedCount 到底怎么用
前端
七牛云行业应用43 分钟前
Codex CLI 和 Codex 桌面端完整教程:两种入口的功能对比与选择指南
前端·后端·github
kisshyshy44 分钟前
告别 Node 噩梦?用 Bun + TypeScript 像写诗一样调用大模型
前端·typescript