webpack源码-loader的原理
版本
webpack :"version": "3.12.0",
webpack配置中的loaders配置是如何传递的
webpack/lib/NormalModuleFactory.js
//从webpack的参数中获取自定义的所有loaders
this.ruleSet = new RuleSet(options.rules || options.loaders);
经过ruleSet.exec处理找到处理当前模块的loader
const result = this.ruleSet.exec({
resource: resourcePath,
resourceQuery,
issuer: contextInfo.issuer,
compiler: contextInfo.compiler
});
到此处,result中的loader字段的值仍为babel-loader:

经过compiler.resolvers.loader处理之后变成了
/Users/cc/killer/webpack-L/wb/node_modules/babel-loader/lib/index.js
处理代码如下:
asyncLib.parallel([
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, this.resolvers.loader),
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, this.resolvers.loader),
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, this.resolvers.loader)
]
....
经过多次回调传递
到达钩子factory 然后创建新的模块:new NormalModule(..,loader,..)
执行一系列回调函数
-->触发before-resolve NormalModuleFactory.js
-->触发factory NormalModuleFactory.js
-->触发resolver NormalModuleFactory.js
-->执行this.buildModule Compilation.js
-->执行module.build NormalModule.js
-->doBuild回调函数 NormalModule.js
到达runLoaders,执行LoaderRunner.js中的runLoaders方法
执行 iteratePitchingLoaders,该方法是个递归函数,先处理pitch阶段,然后再处理normal阶段
先加载loader的代码
加载:
require(loader.path)
定义currentLoaderObject的normal:
loader.normal = typeof module === "function" ? module : module.default; // normal阶段的执行方法
定义currentLoaderObject的pitch:
loader.pitch = module.pitch;
pitch阶段
loader-runner/blob/master/lib/LoaderRunner.js
获取loader提供的pitch方法:
var fn = currentLoaderObject.pitch;
调用pitch:
runSyncOrAsync(fn,loaderContext,[loaderContext.remainingRequest..],callback)
递归调用:
iteratePitchingLoaders
pitch阶段不进行读取资源文件(readResource),而是向loader传递了 remainingRequest,previousRequest等参数。比如在vue-style-loader仅接受了remainingRequest参数。
normal阶段
loader-runner/blob/master/lib/LoaderRunner.js
如果 loaderContext.loaderIndex >= loaderContext.loaders.length,进入normal阶段
根据loaderContext.resourcePath读取资源内容:
options.readResource(resourcePath)
iterateNormalLoaders递归调用
loader.raw = module.raw; //如果raw配置了,根据raw是否转为buffer
runSyncOrAsync方法是真正调用loader的api并完成转换的地方:
function runSyncOrAsync(fn, context, args, callback) {
......
try {
var result = (function LOADER_EXECUTION() {
return fn.apply(context, args);
}());
} catch(e) {......}
}
结束之后通过层层回调,回到normalModule.js的runLloader的回调函数处,紧接着把转译之后内容复制给模块的_source属性,然后调用模块源码的解析,分析资源依赖:
this.parser.parse(this._source.source(), {
current: this,
module: this,
compilation: compilation,
options: options
});
根据资源类型使用对应的loader,直至make结束
webpack源码-loader的原理的更多相关文章
- .34-浅析webpack源码之事件流make(3)
新年好呀~过个年光打游戏,function都写不顺溜了. 上一节的代码到这里了: // NormalModuleFactory的resolver事件流 this.plugin("resolv ...
- 从Webpack源码探究打包流程,萌新也能看懂~
简介 上一篇讲述了如何理解tapable这个钩子机制,因为这个是webpack程序的灵魂.虽然钩子机制很灵活,而然却变成了我们读懂webpack道路上的阻碍.每当webpack运行起来的时候,我的心态 ...
- Android 网络框架之Retrofit2使用详解及从源码中解析原理
就目前来说Retrofit2使用的已相当的广泛,那么我们先来了解下两个问题: 1 . 什么是Retrofit? Retrofit是针对于Android/Java的.基于okHttp的.一种轻量级且安全 ...
- .30-浅析webpack源码之doResolve事件流(1)
这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- Spring Boot 揭秘与实战 源码分析 - 工作原理剖析
文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...
- .17-浅析webpack源码之compile流程-入口函数run
本节流程如图: 现在正式进入打包流程,起步方法为run: Compiler.prototype.run = (callback) => { const startTime = Date.now( ...
- .30-浅析webpack源码之doResolve事件流(2)
这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...
- .3-浅析webpack源码之预编译总览
写在前面: 本来一开始想沿用之前vue源码的标题:webpack源码之***,但是这个工具比较巨大,所以为防止有人觉得我装逼跑来喷我(或者随时鸽),加上浅析二字,以示怂. 既然是浅析,那么案例就不必太 ...
随机推荐
- 手把手教你利用Docker+jenkins部署你的网站
更新服务器的安装源为阿里的源,参考链接:https://blog.csdn.net/js_xh/article/details/79166655 安装docker; 1 更新资源 sudo apt-g ...
- excel如何快速汇总多个类别的总和?
这个需求是一位在当前抗疫一线的朋友提出的,和各位分享一下. 需求情况 因为众所周知的原因,他每天都需要为照顾的小区居民购买.运送生活物资.小区居民通过表单的形式提交自己每日的需求,最终汇总到一张exc ...
- SpringBoot读取application.properties中文乱码
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 解决方案 在ID ...
- 吃货联盟订餐系统 源代码 Java初级小项目
咳咳,今天博主给大家写一个小的项目:吃货联盟订餐系统.博主不是大神(互联网架构师的路上ing),也是小白一个,不过是刚入门的小白^_^.项目功能也很简单:只是模拟日常的订餐流程呦,所以有错误以及功能不 ...
- Mybatis各语句高级用法(未完待续)
更多的语法请参考官网 http://www.mybatis.org/mybatis-3/dynamic-sql.html# 环境:MySQL5.6,jdk1.8 建议:所有的参数加上@Param re ...
- windows 64位上安装mysql 5.7版本
下载的mysql不是安装exe的软件,而是在windows上编译好的二进制mysql软件 下载安装之后配置环境变量:将目录D:\Program Files\mysql-5.7.18-winx64\my ...
- 入门大数据---HBase Shell命令操作
学习方法 可以参考官方文档的简单示例来 点击查看 可以直接在控制台使用help命令查看 例如直接使用help命令: 从上图可以看到,表结构的操作,表数据的操作都展示了.接下来我们可以针对具体的命令使用 ...
- SpringBoot--使用Spring Cache整合redis
一.简介 Spring Cache是Spring对缓存的封装,适用于 EHCache.Redis.Guava等缓存技术. 二.作用 主要是可以使用注解的方式来处理缓存,例如,我们使用redis缓存时, ...
- 深入理解JVM(③)虚拟机的类加载器(双亲委派模型)
前言 先解释一下什么是类加载器,通过一个类的全限定名来获取描述该类的二进制字节流,在虚拟机中实现这个动作的代码被称为"类加载器(Class Loader)". 类与类加载器 类加载 ...
- vi/vim 行删除操作
好东西就要多用,vi/vim越用越喜欢了. 删除多行怎么办呢? 命令输入“:32,65d”,回车键,32-65行就被删除了.