自己简单总结的 loader 原理

54 阅读1分钟

loader

  • loader 其实就是一个函数,会返回处理文件的结果
  • 当webpack解析资源时,会调用相应的loader 去处理 (从下往上,从右往左的顺序调用)
                  module.exports = function (context,map,meta){
                      console.log(context
                          return context
                          }" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
// context 文件内容
// map SourceMap (传入SourceMap传入的相关数据)
// meta 其他loader 传的参数

module.exports = function (context,map,meta){ console.log(context return context }

同步loader

  • 如果在同步loader中添加异步代码 程序会报错 The callback was already called( 已调用回调 )再次调用 就会报错
<button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="// 第一种 module.exports = function (context,map,meta){ console.log(context) return context }

                          // 第二种  (如有下一个loader 需要处理可以采用这种)
                          module.exports = function (context,map,meta){
                              // 一个参数  如果有错误信息,就传错误信息  如果没有  就是null
                                  // context 文件内容
                                      // map SourceMap (传入SourceMap传入的相关数据) 继续传递 SourceMap
                                          // meta 其他loader 传的参数
                                              this.call(null, context, map, meta)
                                              }" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
// 第一种
module.exports = function (context,map,meta){
    console.log(context)
        return context
        }
    <span class="hljs-comment">// 第二种  (如有下一个loader 需要处理可以采用这种)</span>
    <span class="hljs-keyword">module</span><span class="hljs-variable">.exports</span> = <span class="hljs-keyword">function</span> (<span class="hljs-keyword">context</span>,map,meta){
        <span class="hljs-comment">// 一个参数  如果有错误信息,就传错误信息  如果没有  就是null</span>
            <span class="hljs-comment">// context 文件内容</span>
                <span class="hljs-comment">// map SourceMap (传入SourceMap传入的相关数据) 继续传递 SourceMap</span>
                    <span class="hljs-comment">// meta 其他loader 传的参数</span>
                        <span class="hljs-keyword">this</span><span class="hljs-variable">.call</span>(<span class="hljs-literal">null</span>, <span class="hljs-keyword">context</span>, map, meta)
                        }</pre><h4><strong>异步loader</strong></h4><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="module.exports = function (context,map,meta){
                      const callback = this.async()
                          
                              setTimeout(()=>{
                                      callback(null, context, map, meta)    
                                          }, 1000)
                                          }" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="hljs language-livescript">module.<span class="hljs-built_in">exports</span> = <span class="hljs-keyword">function</span> (context,<span class="hljs-keyword">map</span>,meta){
          <span class="hljs-keyword">const</span> callback = this.<span class="hljs-keyword">async</span>()
              
                  <span class="hljs-built_in">setTimeout</span>(()=&gt;{
                          callback(<span class="hljs-literal">null</span>, context, <span class="hljs-keyword">map</span>, meta)    
                              }, <span class="hljs-number">1000</span>)
                              }</pre><h4><strong>raw Loader</strong></h4><ul><li>raw loader接收的context 是 Buffer 数据 (二进制数据)</li><li>同步loader 和 异步loader 都可以</li><li>需要 配置  module.exports.raw = true</li></ul><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="module.exports = function loader(context,map,meta){
                      console.log(context)
                          return context
                          }
                          module.exports.raw = true" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
module.exports = function loader(context,map,meta){
    console.log(context)
        return context
        }
        module.exports.raw = true

pitch Loader

  • pitch loader 中可以是异步loader 和 同步loader
  • 需要暴露一个 pitch方法
  • 当在 use 中设置多个loader时, 执行顺序是 先执行 pitch loader pitch loader 执行完了会再执行普通loader
module.exports = function loader(context,map,meta){
              console.log(context)
                  return context
                  }
                  module.exports.pitch = function (){
                      console.log(pitch)
                      }

有什么总结不到位请大佬们帮忙补充下