webpack源码之loader机制详解


Posted in Javascript onApril 06, 2018

loader概念

loader是用来加载处理各种形式的资源,本质上是一个函数, 接受文件作为参数,返回转化后的结构。

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

loader和plugin区别

之前一篇文章中介绍了plugin机制,和今天研究的对象loader,他们两者在一起极大的拓展了webpack的功能。它们的区别就是loader是用来对模块的源代码进行转换,而插件目的在于解决 loader 无法实现的其他事。为什么这么多说呢?因为plugin可以在任何阶段调用,能够跨Loader进一步加工Loader的输出,在构建运行期间,触发事件,执行预先注册的回调,使用compilation对象做一些更底层的事情。

loader用法

配置

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

内联

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

CLI

webpack --module-bind 'css=style-loader!css-loader'

说明 上面三种使用方法作用都是将一组链式的 loader, 按照从右往左的顺序执行,loader 链中的第一个 loader 返回值给下一个 loader。先使用css-loader解析 @import 和 url()路径中指定的css内容,然后用style-loader 会把原来的 CSS 代码插入页面中的一个 style 标签中。

loader实现

//将css插入到head标签内部
module.exports = function (source) {
  let script = (`
   let style = document.createElement("style");
   style.innerText = ${JSON.stringify(source)};
   document.head.appendChild(style);
  `);
  return script;
}
//使用方式1
resolveLoader: {
  modules: [path.resolve('node_modules'), path.resolve(__dirname, 'src', 'loaders')]
},
{
  test: /\.css$/,
  use: ['style-loader']
},
//使用方式2
//将自己写的loaders发布到npm仓库,然后添加到依赖,按照方式1中的配置方式使用即可

说明 上面是一个简单的loader实现,同步的方式执行,相当于实现了style-loader的功能。

loader原理

function iteratePitchingLoaders(options, loaderContext, callback) {
  var currentLoaderObject = loaderContext.loaders[loaderContext.loaderIndex];
  // load loader module
  loadLoader(currentLoaderObject, function(err) {
    var fn = currentLoaderObject.pitch;
    runSyncOrAsync(
      fn,
      loaderContext, [loaderContext.remainingRequest, loaderContext.previousRequest, currentLoaderObject.data = {}],
      function(err) {
        if(err) return callback(err);
        var args = Array.prototype.slice.call(arguments, 1);
        if(args.length > 0) {
          loaderContext.loaderIndex--;
          iterateNormalLoaders(options, loaderContext, args, callback);
        } else {
          iteratePitchingLoaders(options, loaderContext, callback);
        }
      }
    );
  });
}

说明 上面是webpack源码中loader执行关键步骤,递归的方式执行loader,执行机流程似于express中间件机制

参考源码

  1. webpack: "4.4.1"
  2. webpack-cli: "2.0.13"

参考文档
https://webpack.js.org/concepts/loaders/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQUERY 设置SELECT选中项代码
Feb 07 Javascript
用队列模拟jquery的动画算法实例
Jan 20 Javascript
JavaScript实现的字符串replaceAll函数代码分享
Apr 02 Javascript
JS特效实现图片自动播放并可控的效果
Jul 31 Javascript
js实现有过渡渐变效果的图片轮播相册(兼容IE,ff)
Jan 19 Javascript
JS判断图片是否加载完成方法汇总(最新版)
May 13 Javascript
javascript加减乘除的简单实例
Jul 12 Javascript
js自制图片放大镜功能
Jan 24 Javascript
基于JavaScript实现幸运抽奖页面
Jul 05 Javascript
详解javascript设计模式三:代理模式
Mar 25 Javascript
使用apifm-wxapi快速开发小程序过程详解
Aug 05 Javascript
jQuery实现简单飞机大战
Jul 05 jQuery
vue.js项目nginx部署教程
Apr 05 #Javascript
常用的 JS 排序算法 整理版
Apr 05 #Javascript
通过 JS 判断页面是否有滚动条的实现方法
Apr 05 #Javascript
mint-ui在vue中的使用示例
Apr 05 #Javascript
webpack热模块替换(HMR)/热更新的方法
Apr 05 #Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
Apr 05 #Javascript
express默认日志组件morgan的方法
Apr 05 #Javascript
You might like
PHP生成短网址的3种方法代码实例
2014/07/08 PHP
PHP数组函数知识汇总
2016/05/12 PHP
php处理单文件、多文件上传代码分享
2016/08/24 PHP
php-fpm添加service服务的例子
2018/04/27 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
javascript下function声明一些小结
2007/12/28 Javascript
jquery向.ashx文件post中文乱码问题的解决方法
2011/03/28 Javascript
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
2012/07/31 Javascript
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
Javascript异步编程的4种方法让你写出更出色的程序
2013/01/17 Javascript
在每个匹配元素的外部插入新元素的方法
2013/12/20 Javascript
jquery插件开发之实现google+圈子选择功能
2014/03/10 Javascript
js获取指定日期周数以及星期几的小例子
2014/06/27 Javascript
jQuery实现页面内锚点平滑跳转特效的方法总结
2015/05/11 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
优雅的将ElementUI表格变身成树形表格的方法步骤
2019/04/11 Javascript
JavaScript提升机制Hoisting详解
2019/10/23 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
python中函数传参详解
2016/07/03 Python
Python获取当前函数名称方法实例分享
2018/01/18 Python
python实现接口并发测试脚本
2019/06/25 Python
Python学习笔记之文件的读写操作实例分析
2019/08/07 Python
python+requests接口压力测试500次,查看响应时间的实例
2020/04/30 Python
Python新手学习raise用法
2020/06/03 Python
matplotlib基础绘图命令之errorbar的使用
2020/08/13 Python
Html5游戏开发之乒乓Ping Pong游戏示例(三)
2013/01/21 HTML / CSS
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
应届生服务员求职信
2013/10/31 职场文书
超市重阳节活动方案
2014/02/10 职场文书
应届中专生自荐书范文
2014/02/13 职场文书
仓管员岗位责任制
2014/02/19 职场文书
竞选劳动委员演讲稿
2014/04/28 职场文书
入党积极分子半年考察意见
2015/06/02 职场文书
详解JVM系列之内存模型
2021/06/10 Javascript
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技