上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

手写webpack的loader

guduadmin12小时前

一、概念

帮助webpack将不同类型的文件转换为webpack可识别的模块。

二、Loader执行顺序

分类

  • pre:前置loader
  • normal:普通loader
  • inline:内联loader
  • post:后置loader

    执行顺序

    • 4类loader的执行顺序为per>normal>inline>post
    • 相同优先级的loader执行顺序为:从右到左,从下到上。

      例如:

      // 此时loader执行顺序:loader3 - loader2 - loader1
      module: {
        rules: [
          {
            test: /\.js$/,
            loader: "loader1",
          },
          {
            test: /\.js$/,
            loader: "loader2",
          },
          {
            test: /\.js$/,
            loader: "loader3",
          },
        ],
      },
      
      // 此时loader执行顺序:loader1 - loader2 - loader3
      module: {
        rules: [
          {
            enforce: "pre",
            test: /\.js$/,
            loader: "loader1",
          },
          {
            // 没有enforce就是normal
            test: /\.js$/,
            loader: "loader2",
          },
          {
            enforce: "post",
            test: /\.js$/,
            loader: "loader3",
          },
        ],
      },
      

      使用Loader 的方式

      • 配置方式:在 webpack.config.js 文件中指定 loader。(pre、normal、post loader)
      • 内联方式:在每个 import 语句中显式指定 loader。(inline loader)

        inline Loader

        用法:import Styles from ‘style-loader!css-loader?modules!./styles.css’;

        含义:使用 css-loader 和 style-loader 处理 styles.css 文件通过 ! 将资源中的 loader 分开

        inline loader 可以通过添加不同前缀,跳过其他类型 loader。! 跳过 normal loader。

        import Styles from '!style-loader!css-loader?modules!./styles.css';
        

        -! 跳过 pre 和 normal loader。

        import Styles from '-!style-loader!css-loader?modules!./styles.css';
        

        !! 跳过 pre、 normal 和 post loader。

        import Styles from '!!style-loader!css-loader?modules!./styles.css';
        

        三、开发一个Loader

        最简单的Loader

        //loader/loader1.js
        module.exports = function (content){
        	console.log(content)
        	return content;
        }
        

        他接受要处理的源码作为参数,输出转换后的js代码

        Loader接受的参数

        • content 源文件的内容
        • map sourceMap数据
        • meta 数据可以是任何内容

          Loader分类

          1. 同步Loader
          module.exports = function (content ,map ,meta) {
              /* 
                  第一个参数:err代表是否有错误
                  第二个参数:content处理后的内容
                  第三个参数:sorce-map继续传递sourcemap 
                  第四个参数:meta给下一个loader传递参数
              */
              //相比于普通return方式这种写法可以传递更多参数,不中断loader执行。
              //return content 
              this.callback(null,content,map,meta)
          }
          
          1. 异步Loader

          由于同步计算过于耗时,在 Node.js 这样的单线程环境下进行此操作并不是好的方案,我们建议尽可能地使你的 loader 异步化。但如果计算量很小,同步 loader 也是可以的。

          module.exports = function (content, map, meta) {
            const callback = this.async();
            // 进行异步操作
            setTimeout(() => {
              callback(null, result, map, meta);
            }, 1000);
          };
          
          1. Raw Loader

          默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw 为 true,loader 可以接收原始的 Buffer

          module.exports = function (content) {
            // content是一个Buffer数据
            return content;
          };
          module.exports.raw = true; // 开启 Raw Loader
          
          1. Pitching Loader

          webpack 会先从左到右执行 loader 链中的每个 loader 上的 pitch 方法(如果有),然后再从右到左执行 loader 链中的每个 loader 上的普通 loader 方法。在这个过程中如果任何 pitch 有返回值,则 loader 链被阻断。webpack 会跳过后面所有的的 pitch 和 loader,直接进入上一个 loader 。

          module.exports = function (content) {
            return content;
          };
          module.exports.pitch = function (remainingRequest, precedingRequest, data) {
            console.log("do somethings");
          };
          

          手写webpack的loader,在这里插入图片描述,第1张

          手写banner-loader

          作用:给代码添加文本注释包括作者、日期

          //loader/banner-loader.js
          const schema =  require("./schema.json");
          module.exports  = function (content,map,meta){
              //获取Loader的options,同时对options做校验
              //schema 是options的校验规则。
              const options = this.getOptions(schema);
              const date = (new Date()).toLocaleString()
              
              const prefix = `
                /* 
                  Author ${options.author}
                  Date ${date}
                */
              `
              return `${prefix} \n ${content}`
          }
          

          下面是schema.json文件

          {
              "type":"object",
              "porperties":{
                  "author":{
                      "type":"string"
                  }
              },
              "addtionalProperties":false
          }
          

          在webpack.config.js中配置

          //...省略
              module: {
                  rules: [
                      {
                          test:/\.js$/,
                          loader:'./loader/banner-loader',
                          options:{
                              author:'老王'
                          }
                      }
                  ]
              },
          

          在dist压缩文件main.js中

          /***/ "./src/main.js":
          /*!*********************!*\
            !*** ./src/main.js ***!
            \*********************/
          /***/ (() => {
          eval("\n      /* \n        Author 老王\n        Date 2024/1/13 14:32:11\n      */\n     \n console.log('hello main')\n\n//# sourceURL=webpack:///./src/main.js?");
          /***/ })
          /******/ 	});
          /************************************************************************/
          

网友评论

搜索
最新文章
热门文章
热门标签