webpack模块机制浅析【一】
webpack模块机制浅析【一】
今天看了看webpack打包后的代码,所以就去分析了下代码的运行机制。
下面这段代码是webpack打包后的最基本的形式,可以说是【骨架】
(function(root,fn){
if(typeof exports ==='object'&&typeof module === 'object'){
module.exports = fn();//exports和module同时存在,说明时在node的CommonJs规范下,这个时候使用module.exports来导出模块,fn函数执行后是返回一个模块
}else if(typeof define === 'function' && define.amd){
define([],fn);//当exports和module不同时存在时,先判断define和define.amd是否存在;如果存在表明在AMD规范下,所以就使用define函数"包裹"一下fn函数,以此来声明一个AMD规范下的模块
}else if(typeof exports === 'object'){
exports['packname'] = fn();//packname表示的包名,exports据说是module.exports的引用,但是我不明白module不存在何来exports,求网友解答,不清楚什么时候代码能够执行到这里?
}else {
root['packname'] = fn();//这个应该是如果上面的情况都不存在那就把它绑定在当前执行环境的"根节点",如在浏览器下就绑定在window上;
}
})(this,function(){//this丢进去变成了root,后面这个function丢进去就是fn
return (function(modules){//modules是参数丢进来的函数数组
var installed = {};//用来装载已声明模块
function _webpack_require_(moduleId){//webpack的包获取函数,使用这个函数去检索前面传进来的modules函数数组,从而解锁出每一个函数数组中的元素(也可以说是模块),每一个数组元素一般都是会存在闭包以隔离作用域,每一个元素中会使用module.exports来作为输出寄托对象。
if(installed[moduleId]){//moduleId其实就是modules数组的索引
return installed[moduleId].exports;//如果存在说明之前函数执行过
}
var module = installed[moduleId] = {//可以说是缓存模块
exports:{},//这个会使用下面的call函数来改变。
id:moduleId,
loaded:false
}
modules[moduleId].call(module.exports,module,module.exports,_webpack_require_)
//上面一句中,其实是执行modules[moduleId]()函数,只不过函数this指向了module.exports(也就是this)
//还是上面一句解释(因为重要啊):第二个参数module其实是一个【地址引用】,只要执行函数在函数中对这个module做了更改,那么最开始的module就做了更改,这也是为什么后面的函数数组中的函数都把方法和变量都绑定在module.exports上面的原因
module.loaded = true;//可以不管
return module.exports;//这个很重要,这个时候module.exports已经被上面的call函数装饰过了。在经过无数个函数的洗礼之后,这个module.exports会逐渐成长为包含各种变量和方法的【大对象】,反正就是个对象,最后return丢给外层的module.exports或者this或者丢给AMD的define可以。
}
_webpack_require_.m = modules;//这个先可以不管
_webpack_require_.c = installed;//缓存,先不管
_webpack_require_.p = '';//先不管
return _webpack_require_(0);//这个是函数执行的入口,相当于执行modules[0]函数,可以在modules的第一个函数中再去调用其他函数
})([//注意这是一个函数数组,里面都是函数,也可以理解为模块
function(module,exports,_webpack_require_){
// console.log('hi');
console.log(this);//如果在下没猜错的话,下面几个函数中的this输出都是{},也就是_webpack_require_一开始定义modules下的exports(初始化为{}),对吧?
module.exports = _webpack_require_(1);
},
function(module,exports,_webpack_require_){
console.log(this);//{}
let str = _webpack_require_(2);//调用其他模块
let isType = _webpack_require_(3);
module.exports = {age:18,str:str,isType:isType};
},
function(module,exports,_webpack_require_){
console.log(this);//{}
module.exports = '你好'
},
function(module,exports,_webpack_require_){
console.log(this);//{}
module.exports = function(type){
return function(obj){//返回一个函数
return Object.prototype.toString.call(obj) === "[object "+type+"]";//判断变量类型的黑科技
}
}
}
]);
}) /*********/
if(typeof module =='object' && typeof exports == 'object'){
console.log(module.exports);//{ age: 18, str: '你好', isType: [Function] }
var isArray = module.exports.isType("Array");//返回的是一个函数
console.log(isArray([1]));//true
console.log(isArray('1'));//false
console.log(isArray(1));//false
}else if(typeof define == 'function'){
console.log('AMD');
}else{
console.log(this);
var isArray = this.isType("Array");//返回的是一个函数
console.log(isArray([1]));//true
console.log(isArray('1'));//false
console.log(isArray(1));//false
}
理解这个对于理解别人源码会有帮助,如果你不懒,我觉得你应该会把这段代码执行一下(用node执行)
webpack模块机制浅析【一】的更多相关文章
- Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- Linux模块机制浅析_转
Linux模块机制浅析 转自:http://www.cnblogs.com/fanzhidongyzby/p/3730131.htmlLinux允许用户通过插入模块,实现干预内核的目的.一直以来,对l ...
- 【ARM-Linux开发】Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- 【Linux开发】Linux模块机制浅析
Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! 我们通过创建一个简单的模块 ...
- 【linux驱动笔记】linux模块机制浅析
1. 模块module 操作系统分微内核和宏内核,微内核优点,可以使操作系统仅作很少的事,其它事情如网络处理等都作为应用程序来实现,微内核精简的同时,必然带来性能的下降.而linux的宏内核设 ...
- 探寻 webpack 插件机制
webpack 可谓是让人欣喜又让人忧,功能强大但需要一定的学习成本.在探寻 webpack 插件机制前,首先需要了解一件有意思的事情,webpack 插件机制是整个 webpack 工具的骨架,而 ...
- typecho流程原理和插件机制浅析(第一弹)
typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...
- Webpack编译结果浅析
如今Webpack已经是一个不可或缺的前端构建工具,借助这个构建工具,我们可以使用比较新的技术(浏览器不能直接支持)来开发. 你是否好奇你写的代码经过Webpack构建之后会生成什么东西?是否有时调试 ...
- Typescript学习笔记(五) 模块机制
javascript从es5之前都缺少一种模块机制,无法通过js引入文件,于是requirejs等等的加载器应运而生.这些加载器的使用也并不统一,产生了amd,commonjs,umd等等的规范,各有 ...
随机推荐
- PyQt4 的事件与信号 -- 重写事件处理方法
# PyQt中的事件处理主要依赖重写事件处理函数来实现 import sys from PyQt4 import QtCore, QtGui class MainWindow(QtGui.QWidge ...
- ActiveMQ进阶学习
本文主要讲述ActiveMQ与spring整合的方案.介绍知识点包括spring,jms,activemq基于配置文件模式管理消息,消息监听器类型,消息转换类介绍,spring对JMS事物管理. 1. ...
- MongoDb 快速入门教程
文章首发于[博客园-陈树义],点击跳转到原文MongoDb 快速入门教程. MongoDb 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 它是可扩展的 ...
- 做了一个web版的 MyBatis Generator
mybatis 官方提供了 MyBatis Generator ,可以通过 xml 配置文件的方式使用,例如自己写调用脚本,或者使用 mvn 插件的方式,其实实现起来还是很简单的.虽然简单,但还是不够 ...
- js 循环 常用方法
$(function () { var num = ["1","2","3","4","5",&qu ...
- Zabbix实战-简易教程--动作(Actions)--自动注册
一.概述 之前已经讲述了自动发现功能,自动注册和自动发现非常类似,但是比自动发现更精确.因为自动注册,是在Agent上自定义元数据,然后Agent将元数据发送给server进行匹配,如果匹配一致,则进 ...
- JSP执行过程分析
概述 在java领域,表现层技术主要有三种:jsp.freemarker.velocity.jsp是由sun公司倡导的官方标准,freemarker和velocity是第三方的模板. jsp是大家最熟 ...
- python模块安装
现在终于知道怎么在windows上导入Python的第三方模块了 首先在DOS下进入Python安装的pip目录:D:/Python27/Scripts 用pip install XXX安装 之前一直 ...
- 细说log4j
可能做过java项目的基本上都是用过log4j,它是用来做java日志的.比如我们做一个项目分为很多的模块,那我们怎么想要知道它什么时候启动了,这时候我们可以使用log4j标记某某模块启动了. 努力的 ...
- CTF---Web入门第六题 因缺思汀的绕过
因缺思汀的绕过分值:20 来源: pcat 难度:中 参与人数:6479人 Get Flag:2002人 答题人数:2197人 解题通过率:91% 访问解题链接去访问题目,可以进行答题.根据web题一 ...