webpack系列之loader

loader是什么?

webpack默认只支持解析打包.js文件和.json文件,当我们在项目中使用其他资源时,会失败的,所以为了能够解析多种类型资源,webpack提出了为资源设置loader的概念

loader的使用:

webpack.config.js项目中

module。exports={
  .....
  module:{
	rules:[      //rules是一个数组,一个项目可以放置多个loader
	  {
	  	test:'/\.css$/',  //正则匹配  .css文件时使用以下loader
	  	use:['style-loader','css-loader'],   //解析test匹配成功的文件使用的loader  css-loader解析.css文件,style-loader则是将解析结果内嵌入html中
	  },
	   {
                    test:/\.(png|jpg|jpeg)$/,
                    use:[
	                    {
	                     loader: 'url-loader',
	                          options:{   //loader还支持options选项,可以配置loader
	                             limit:10*1024   //小于10*1024大小的文件直接变成base64
	                          }
	                    }
						]
                       
                },
	]
	}
}

loader类型

  • 同步loader:JS单线程,需要等待该loader完成才去执行下一个操作
  • 异步loader:当需要进行异步操作才能完成的loader,例如:读取文件,需要网络请求等

loader机制

  • 从后往前解析
  • Loader加载发生在编译阶段,compiler实例化之后
  • 串行解析,use:[‘style-loader’,‘css-loader’]----当css-loader解析完毕之后,将结果传给下一个loader:style-loader
  • 默认开启loader缓存,当loader加载过的文件没有发生变化时,不再去使用loader解析此文件,this.cacheable(false)可更改

编写一个简单的loader

  • loader目的:解析.txt文件,将一个目标字段替换成需求字段
  • 匹配文件:.txt
  • options配置:targetName—目标字段 demandName----需求字段

1、创建raw-loader.js文件

一般编写loader会建立一个loader文件夹,里面是我们自写编写的loader,loader命名规范为xxx-loader.js

2、raw-loader文件需要导出一个模块获取文件内容

因为webpack是一个模块管理器,所有经由webpack管理的项目是由一个个模块组成的,所以raw-loader.js 导出也是一个模块
loader解析发生在编译阶段,compiler实例化之后,compiler由entry入口开始,寻找module(模块),将module经由loader处理,文件内容是由compiler获取,然后通过参数传入loader
上一个loader处理过的内容将直接传送给下一个loader

module.exports=functionmm(source){
//注意这里的参数source  是compiler对象传递给raw-loader的,是webpack找到.txt文件的内容
......
}

3、获取options传递的参数

我们需要targetName和demandName字段,所以需要借助loader的API,

const loaderUtlis=require('loader-utils')//引入 loader-utils工具
module.exports=function(source){
.......
  const {targetName}=loaderUtils.getOptions(this);   //获取targetName
    const {demandName}=loaderUtlis.getOptions(this); //获取demandName
}

4、逻辑处理

const loaderUtlis=require('loader-utils')

module.exports=function(source){
    const json=JSON.stringify(source);   //使用JSON去解析
    const {targetName}=loaderUtlis.getOptions(this);
    const {demandName}=loaderUtlis.getOptions(this);

    const result= json.replace(targetName,demandName);
  
}

5、返回处理的内容

可以直接return 或者this.callback(…),this.callback更加灵活

const loaderUtlis=require('loader-utils')

module.exports=function(source){
    const json=JSON.stringify(source);   //使用JSON去解析
    const {targetName}=loaderUtlis.getOptions(this);
    const {demandName}=loaderUtlis.getOptions(this);

   return  json.replace(targetName,demandName);

}

6、使用loader

我们在webpack.config.js中直接使用path.resolve(’./loaders/raw-loader’)引入
在options中加入我们的配置

const path =require('path');

module.exports={
  entry:'./src/index.js',
  output:{
     filename:'[name].js',
     path:path.join(__dirname,'./dist')
  },
  module:{
    rules:[
      {
        test:/.txt$/,
        use:[
          {
            loader:'file-loader',
            options:{

              name:'[name]-[hash:2].[ext]'
            }
          },
          {
            loader:path.resolve('./loaders/raw-loader'),   
            options:{
                  targetName:'列侬',
                  demandName:'甲壳虫乐队'
                }
          }
        ]
     
      }
    ]
  },
  plugins:[
   
  ],
  mode:'development'
}

异步loader

只需要使用const callback=this.async()即可进行异步loader了

const loaderUtlis=require('loader-utils')
const fs=require('fs');
const path=require('path');

module.exports=function(source){
    const json=JSON.stringify(source);   //使用JSON去解析
    const callback=this.async();   //异步调用loader
    const {targetName}=loaderUtlis.getOptions(this);
    const {demandName}=loaderUtlis.getOptions(this);

     fs.readFile(path.join(__dirname,'./async.txt'),'utf-8',(err,data)=>{   //读取文件---异步操作
     const result=json.replace(targetName,demandName)
         callback(null,result);
     })
   
}

Loader的API

webpack官网

本demo的loadernpm地址:https://www.npmjs.com/package/replace-txt-loader

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值