zoukankan      html  css  js  c++  java
  • 自定义loader基础知识

    参考 :译文 编写一个loader

    https://webpack.github.io/docs/loaders.html

    按照loader的返回值可以分为两种:

    • 最左loader:这种loader会返回字符串描述的js模块代码,已经是loader的最终处理结果了,这样的字符串会被添加到webpack的模块函数中
    • 非最左loader:返回值不是js模块代码,而仅仅是对资源的中间处理结果,这样的字符串需要被后续的loader处理

    一般情况下,在loader的链式调用中,一般是这样:最左loader!非最左loader!非最左loader ....

    简单loader例子

    // loaders/myLoader.js 返回的值是js模块代码,这个loader属于最左loader
    module.exports = function loader(source) {
        return `module.exports = {fn: ${source}}`;
    };
    
    // main.js
    const src = require("./src")
    src.fn();
    
    // src.js
    alert(999)
    
    //配置文件
    const path = require('path')
    module.exports = {
        entry:  [__dirname + "/main.js"],
        output: {
            path: __dirname + "/dist",
            filename: "bundle.js",
        },
        module: {
            loaders:[
                {
                    test: /src.js/,
                    use: [
                        {
                            loader: path.resolve(__dirname, './loaders/myLoader.js'),
                        }
                    ]
                }
            ]
        }
    }

    打包后的结果

    /***/ }),
    /* 1 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const src = __webpack_require__(2)
    src.fn();
    
    /***/ }),
    /* 2 */
    /***/ (function(module, exports) {
    
    module.exports = {fn: alert(999)}
    
    /***/ })
    /******/ ]);

    注意:如果loader处理的是所有js,则入口文件是js的话也会被处理。

    从以上代码可以看出,对于某些loader,他们导出的结果可能并不重要,而是可以在导出之前,根据拿到的文本内容对页面做一些操作。

    aync loader

     把以上小例子中的loader定义为:

    module.exports = function(source) {
        var callback = this.async();
        setTimeout(function(){
           callback(null,`module.exports = {fn: ${source}}`)
        },5000);
    };

     启动打包后,经过5s才打包完成。打包结果和以上小例子中的一致。

     pitching loader

       在loader函数对象上添加一个pitch属性,这个pitch所执行的函数称为pitching loader。在pitching loader中可以通过data把数据传递给对应的loader,而不能传递给其他loader。

      在链式调用中,pitching loader 与 loader的执行次序(以 a!b!c!resource 为例):

    • pitch a
      • pitch b
        • pitch c
          • read file resource (adds resource to dependencies)
        • run c
      • run b
    • run a

      在pitching loader有返回值时的情况

    • pitch a
      • pitch b (returns something)
    • run a

      可见,哪个pitching loader有返回值,则对应的loader以及后续的loader都不执行了。以上例子中a loader函数的第一个参数就是b pitching loader的返回值。

     pitching loader的应用场景

      问题是有时候我们想把两个第一种loader chain起来,比如

    style-loader!css-loader

      而 css-loader的返回值是一串js代码(包含了module.export=xxx这样的字符串),如果按正常方式写style-loader的参数就是一串代码字符串。就算eval了也不一定拿到什么值:

    eval('module.export="result";console.log("hello world")') === "hello world"

      为了解决这种问题,我们需要在style-loader里执行require(css-loader!resouce), 这会把css-loader跑一遍,也就是说如果按正常顺序执行css-loader会跑两遍(第一遍拿到的js代码用不了), 为了只执行一次,style-loader利用了pitching, 在pitching函数里require(css-loader!resouce)。然后返回js代码(style-loader能够作为最左边loader)

      

  • 相关阅读:
    MongoDB使用命令列表
    关于.Net WebProxy【转】
    第七章、基本数据类型(tuple)
    第六章、基本数据类型(list)
    python JOB(作业)
    第五章、基本数据类型(int、str)
    第四章、Python运算符
    第三章、pycharm配置
    第二章、python初识以及变量
    第一章、python学习大纲
  • 原文地址:https://www.cnblogs.com/hellohello/p/8137034.html
Copyright © 2011-2022 走看看