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)

      

  • 相关阅读:
    支持向量机SVM知识点概括
    决策树知识点概括
    HDU 3081 Marriage Match II
    HDU 3572 Task Schedule
    HDU 4888 Redraw Beautiful Drawings
    Poj 2728 Desert King
    HDU 3926 Hand in Hand
    HDU 1598 find the most comfortable road
    HDU 4393 Throw nails
    POJ 1486 Sorting Slides
  • 原文地址:https://www.cnblogs.com/hellohello/p/8137034.html
Copyright © 2011-2022 走看看