最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack深入开发之--Loader

    正文概述 掘金(baymax)   2021-08-17   747

    1. loader 开发场景

    当在项目中需要对我们的文件进行处理,但是现有loader无法满足要求的时候, 那么自己开发一个loader,就显得比较重要了。比如,我们在开发组件库中,要想使用markdown组成网站的一个个功能介绍页面。在我们的markdown文件中,需要新创建一个自定义标签,用于国际化,比如必须使用一个<chn>标签, 但这个标签,实际上现有的markdown loader是不支持的, 那么就需要新加一个loader,来进行标签的解析。

    2. 本文的讨论深度

    本文并不是介绍webpack loader的源码实现, 重点放在我们怎么开发一个可正常运行的loader。 所以下面开始对loader进行一些分析。

    3. webpack中loader的分类

    在webpack的loader中,其实是分为这几类的:

    • pre 前置, 会优先执行
    • post 后置, 会最后执行
    • normal 普通
    • inline 行内

    涉及的是loader的执行顺序。 比如:

    module: {
        rules: [
          {
            test: /.less$/,
            use: 'style-loader'
          },
         {
            test: /.less$/,
            use: 'css-loader'
          },
         {
            test: /.less$/,
            use: 'less-loader'
          }
        ]
      },
    
    

    这是我们经常会用的loader, 它的执行顺序其实是自下往上(或者说从右向左)。 所以执行的顺序是:

    如果我们设置 enforce, 则会明确自定义的执行顺序, 比如:

    module: {
        rules: [
          {
            test: /.less$/,
            use: 'less-loader',
            enforce: 'pre'
          },
         {
            test: /.less$/,
            use: 'css-loader'
          },
         {
            test: /.less$/,
            use: 'style-loader',
            enforce: 'post'
          }
        ]
      },
    
    

    像上面这种写法,则手动确定执行顺序:

    normal 是我们正常在rules中引用loader

    inline 是另外一种写法:

     style-loader!css-loader!stylus-loader
    

    当然目前大家用inline的场景有限,因为很多时候对loader要传入各种参数。

    好, 基础用法和不常用的enforce讲完, 下面,拿normal出来,进行重点讲解

    4. Normal Loader 和 Pitching Loader

    4.1 Loader的执行总结构

    Loader的总体结构是将一个函数 exports出去,供webpack的 runtime(我自己抽象的)使用。

    4.2 Normal Loader的开发方式和执行

    先把最基础的展示:

    // vue-pre-loader.js
    
    const vuePreLoader = (content, map, meta) => {
        console.log('vue PreLoader获取的')
        console.log('vue PreLoader逻辑执行');
        return content;
    }
    module.exports = vuePreLoader;
    

    在webpack中的使用:

    const {resolve} = require('path');
    // ....
    rules: [
        {
            test: /\.vue$/,
            use: [
                    {
                        loader: 'vue-loader'
                    },
                    {
                        loader: resolve(__dirname, './loader/vue-pre-loader.js')
                    }
            ]
        },
    ]
    
    

    在编译.vue文件的时候, 就会先执行我们自己写的loader, 而且会把content打印出来。 这个content是字符串,我们可以对数据进行二次处理。

    好了,现在我们再开发一个loader, 用于 vue-loader执行后。

    // vue-after-loader.js
    
    const vueAfterLoader = (content, map, meta) => {
        // 比如可以把content中的html注释部分给删除掉
        const regExp = /<!--((\s|\r|\n)*((?!-->).)*\s|\r|\n)*-->/;
        if(regExp.test(content)) {
            content = content.replace(content.match(regExp)[0], '');
        }
        console.log('vueAfterLoader 逻辑执行');
        return content;
    }
    
    module.exports = vueAfterLoader;
    
    

    同样,更新webpack中的配置:

    const {resolve} = require('path');
    // ....
    rules: [
        {
            test: /\.vue$/,
            use: [
                    {
                        loader: resolve(__dirname, './loader/vue-after-loader.js')
                    },
                    {
                        loader: 'vue-loader'
                    },
                    {
                        loader: resolve(__dirname, './loader/vue-pre-loader.js')
                    }
            ]
        },
    ]
    
    

    重新执行的时候,注意以下两点:

    • content 的内容可以进行处理,处理成我们想要的
    • 执行顺序: 先执行vue-pre-loader, 再执行vue-arger-loader

    4.3 Pitching Loader是什么

    这个概念在我处理的很多项目中并没有用到, 所以,更需要研究一下。 经过研究发现,这个pitching其实是跟熔断相关的。

    首先加上这个pitch试试

    // vue-pre-loader.js
    
    const vuePreLoader = (content, map, meta) => {
        console.log('vue PreLoader逻辑执行');
        return content;
    }
    vuePreLoader.pitch = function(remainingRequest, precedingRequest, data) {
        console.log('执行vuePreLoader pitching');
    }
    
    module.exports = vuePreLoader;
    
    
    // vue-after-loader.js
    
    const vueAfterLoader = (content, map, meta) => {
        // 比如可以把content中的html注释部分给删除掉
        const regExp = /<!--((\s|\r|\n)*((?!-->).)*\s|\r|\n)*-->/;
        if(regExp.test(content)) {
            content = content.replace(content.match(regExp)[0], '');
        }
        console.log('vueAfterLoader 逻辑执行');
        return content;
    }
    
    vueAfterLoader.pitch = function(remainingRequest, precedingRequest, data) {
        console.log('执行vueAfterLoader pitching');
    }
    
    module.exports = vueAfterLoader;
    
    

    再次执行, 我们会发现,执行顺序是这样的:

    也就是说: pitch的执行是从前向后, pitch执行完毕后,再从后向前执行loader

    那么这个pitching 的应用是什么呢?一个重要功能就是前面说的熔断。 当pitch 返回非undefined, 那么就会阻断之前的进程。 比如, 我在vue-pre-loader.js 中做一个return操作

    vuePreLoader.pitch = function(remainingRequest, precedingRequest, data) {
        console.log('执行vuePreLoader pitching');
        return '熔断流程';
    }
    
    

    那么再看执行结果:

    看到了吧? 它把后面的流程给熔断了, 所以 vue PreLoader逻辑执行这个逻辑就没有执行,就返回到了 vue-after-loader

    整体流程是这样的:

    webpack深入开发之--Loader

    画的不是很好,但是尽量体现他们之间的关系。希望对大家有那么一点点启发。

    上面是今天我要表达的全部内容, 在分享给大家的同时,自己对其中的一些原理也有了更深一些的认识, 希望对大家有用。喜欢的话别忘了点个赞喔~~


    下载网 » webpack深入开发之--Loader

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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