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 执行顺序的改变。

相关推荐
api7717 分钟前
1688商品详情API返回值中的售后保障与服务信息
java·服务器·前端·javascript·python·spring·pygame
赵广陆26 分钟前
SprinBoot+Vue门诊管理系统的设计与实现
前端·javascript·vue.js·spring boot·maven
华山令狐虫1 小时前
el-tabs 样式修改
前端
史努比的大头3 小时前
前端开发深入了解webpack
前端
Dovir多多3 小时前
渗透测试入门学习——php与mysql数据库连接、使用session完成简单的用户注册、登录
前端·数据库·后端·mysql·安全·html·php
B.-3 小时前
Remix 学习 - @remix-run/react 中主要的 hooks
前端·javascript·学习·react.js·web
小刘|3 小时前
《实现 HTML 图片轮播效果》
前端·html
罗_三金4 小时前
微信小程序读写NFC标签(实现NFC标签快速拉起小程序)实战
前端·javascript·微信小程序·小程序
大大。5 小时前
el-input 只能输入数字和一个小数点,或者只能输入正整数
前端·javascript·vue.js
盼盼盼5 小时前
如何避免在使用 Context API 时出现状态管理的常见问题?
前端·javascript·react.js