最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 轻松搞定 webpack loader (基础>>>深入)

    正文概述 掘金(coolFish)   2021-07-16   592

    序言

    在学习之前先抛出三个问题,我们根据这三个问题深入学习 loader 。

    1. 什么是 loader ,它能干什么。
    2. 为什么需要 loader 。
    3. 如何使用 loader ,有哪些要掌握的核心。

    什么是 loader ?


    轻松搞定 webpack loader (基础>>>深入)
    这是 webpack 官网的宣传图,我们可以看到,左侧各种类型的文件,统一打包成右边被浏览器识别支持的文件,那么这个转换的过程是如何实现的呢,没错就是 webpack 的核心概念之一( loader)实现的。

    1. loader 让 webpack 能够处理其他类型的文件,并将它们转换为有效模块
    2. loader 本质是一个函数,导出为函数的 JavaScript 模块
    3. 简单说就是将各种类型的文件,转换成 JS 模块。

    为什么需要loader

    因为 webpack 只能理解 JavaScriptJSON文件。所以需要一个模块来帮它处理其他类型的文件,loader 就是做这件事情的模块。

    webpack常用的loader

    样式:style-loader、css-loader、less-loader、sass-loader 等
    文件:raw-loader、file-loader 、url-loader 等
    编译:babel-loader、coffee-loader 、ts-loader 等
    校验测试:mocha-loader、jshint-loader 、eslint-loader 等
    为什么有这么多种 loader 呢,是因为一种 loader 处理相应的文件,这样的职责单一的设计,可以高度复用和灵活组合

    loader怎么用

    首先 loader 是辅助 webpack 的模块 ,所以要配置 webpack.config 文件指定 loader 的执行区间和执行方式,我们以一个 sass-loader 的例子演示一下使用。

    1. 首先匹配要处理的文件,通过 test,正则过滤出 scss 文件。
    2. 经过 sass-loader 转换 sass 文件为 css 文件, 并且包装一层 module.exports 成为一个 js module 。
    3. 通过 style-loader 将创建一个style 标签将上面转换完成的 css 文件嵌入 html 中。
    4. 最后 css-loader 处理其中的 @importurl()。因为 webpack 不认识,所以将其转化成 require 形式
    module.exports = {
      module: {
        rules: [
            {
              test: /\.scss$/,
              use:[
                  {loader:'style-loader'},
                  {loader:'css-loader',options:{sourceMap:true,modules:true}},
                  {loader:'sass-loader',options:{sourceMap:true}}
              ],
              exclude:/node_modules/,
              enforce: "post",
          }
        ]
      }
    }
    

    深入 loader

    我们已经知道了 loader 的概念和基本使用,所以接下来会探究一下 loader 的分类和执行流程。通过上例,我们发现还有一个 enforce: "post" 配置,这就是loader 分类的配置

    enforce ( loader 分类)

    类别与优先级

    1. 在 webpack 中 loader 可以被分为四类,分别是 :普通normal前置pre行内inline后置 post
    2. 普通 normal ,前置pre,后置 post ,通过 enforce 可以进行分类设置,若无设置,则默认为 normal。
    3. 行内 inline 比较特殊,是在 import / require 的时候,直接写入代码中,用来过滤其他的 loader 。
    4. 四种loader调用先后顺序为:pre > normal > inline > post 。

    inline(行内 loader )

    使用方法是在 import / require 的时候,将他的三种前缀语法写入代码中:

    1. ! : 忽略 normal-loader。
    2. -! : 忽略 pre-loader 和 normal-loader.
    3. !! : 忽略所有 loader (pre / normal / post)

    行内 loader 通过 ! 控制资源中的 loader,同时支持在 loader 后面通过 ? 传递参数。
    Tip:
    该分类是相对于 rules ,并非是某个 loader ,只要在当前这个 rules 范围内的所有 loader 都遵循此设定。
    实例
    假设我们有4个 loader ,分别为 pre-loader ,normal-loader ,post-loader ,inline-loader。
    以上 loader 均为:

    module.exports = function (content) {
      console.log("x-loader");
      return content;
    };
    
    module.exports.pitch = function (remainingRequest, precedingRequest, data) {
      console.log("x-loader-pitch");
    };
    
    1. 无前缀信息时
    import "/Users/jiangyuereee/Desktop/loader/inline-loader.js!./txt.txt"
    
    post-loader-pitch
    inline-loader-pitch
    normal-loader-pitch
    pre-loader-pitch
    pre-loader-pitch
    normal-loader-pitch
    inline-loader-pitch
    post-loader-pitch
    

    我们可以发现,执行顺序是按照我们上文提到的优先级顺序进行排列,并且触发方式类似于洋葱模型。

    1. !前缀信息
    import "!/Users/jiangyuereee/Desktop/loader/inline-loader.js!./txt.txt"
    
    post-loader-pitch
    inline-loader-pitch
    pre-loader-pitch
    pre-loader-pitch
    inline-loader-pitch
    post-loader-pitch
    

    我们看到 normal-loader 并没有触发,所以过滤成功。

    1. -!前缀信息
    import "-!/Users/jiangyuereee/Desktop/loader/inline-loader.js!./txt.txt"
    
    post-loader-pitch
    inline-loader-pitch
    inline-loader-pitch
    post-loader-pitch
    

    我们看到 normal-loader 和 pre-loader 并没有触发,所以过滤成功。

    1. !!前缀信息
    import "!!/Users/jiangyuereee/Desktop/loader/inline-loader.js!./txt.txt"
    
    post-loader-pitch
    post-loader-pitch
    

    我们看到只有 inline-loader 触发,所以过滤成功。

    1. 当出现相同的 loader 的情况下,调用的优先级为,从低到高,自右往左。(pitch情况下,则相反)

    轻松搞定 webpack loader (基础>>>深入)

    Loader-pitch

    1. loader 的调用过程:在从右往左调用 loader 方法之前都会从左往右调用一遍 loader上面的 pitch 方法。

    轻松搞定 webpack loader (基础>>>深入)

    1. loader 的熔断机制

    一旦一个 pitch 返回了结果,那么直接熔断,不会执行后面的 pitch ,直接将现有结果传递给前一个 loader 。
    轻松搞定 webpack loader (基础>>>深入)
    我们看到上图中 loader2.pitch 返回了结果,直接把结果传递给 loader1,剩下的都不会触发了。

    同步 / 异步 loader


    在官方文档中有描述
    如果是单个处理结果,可在同步模式中直接返回,但是如果有多个结果,则要调用 this.callpack()。在异步模式中,必须调用 this.async()来告知 loader runner 等待异步结果,它会返回 this.callback()回调函数,随后 loader 必须返回 undefined ,并且调用该回调函数。
    在 webpack 中,loader 会依赖于读取外部配置文件,进行网络请求等,如果同步操作,会造成进程堵塞。所以loader 会有同步 / 异步之分

    在 loader 中,可以通过两种方式返回数据

    1. return :只能返回 content。
    2. callback :可以返回
    • err : Error | null (错误信息)
    • content : string | Buffer (content信息)
    • sourceMap : SourceMap (sourceMap)
    • meta? : any (奇怪的数据,AST等等)

    同步 loader

    module.exports = function(content, map, meta) {
      // return handleData(content);
      this.callback(null, handleData(content), handleSourceMap(map), meta);
      return; // 当调用 callback() 函数时,总是返回 undefined
    };
    

    异步 loader

    module.exports = function(content, map, meta) {
      var callback = this.async();
      asycnHandleData(content, function(err, result) {
        if (err) return callback(err);
        callback(null, result, map, meta);
      });
    };
    

    总结: 要注意的是,异步要通过 this.async 来获取 callback。

    loader的输出


    由loader的返回方法 callback 可知,当 loader 链路到了最后一个 loader 的时候,compiler 期待得到的结果是可以转换为StringBuffer 或者直接是个 String 。表示当前模板处理后的 JS 源码。根据返回参数得知,还可以传递一个 sourceMap
    除去正常的 loader 输出的 JS 源码,还可以根据 this.emitFile 进行额外输出文件。

    emitFile(
        name: string, 
        content: Buffer|string, 
        sourceMap?: {...}
    );
    
    

    相关使用工具

    1. webpack 官方中文文档。
    2. Loader 机制。
    3. Loader-runner调试工具。


    起源地下载网 » 轻松搞定 webpack loader (基础>>>深入)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元