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模块机制浅析【一】的更多相关文章

  1. Linux模块机制浅析

    Linux模块机制浅析   Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...

  2. Linux模块机制浅析_转

    Linux模块机制浅析 转自:http://www.cnblogs.com/fanzhidongyzby/p/3730131.htmlLinux允许用户通过插入模块,实现干预内核的目的.一直以来,对l ...

  3. 【ARM-Linux开发】Linux模块机制浅析

    Linux模块机制浅析   Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...

  4. 【Linux开发】Linux模块机制浅析

    Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! 我们通过创建一个简单的模块 ...

  5. 【linux驱动笔记】linux模块机制浅析

      1.   模块module 操作系统分微内核和宏内核,微内核优点,可以使操作系统仅作很少的事,其它事情如网络处理等都作为应用程序来实现,微内核精简的同时,必然带来性能的下降.而linux的宏内核设 ...

  6. 探寻 webpack 插件机制

    webpack 可谓是让人欣喜又让人忧,功能强大但需要一定的学习成本.在探寻 webpack 插件机制前,首先需要了解一件有意思的事情,webpack 插件机制是整个 webpack 工具的骨架,而 ...

  7. typecho流程原理和插件机制浅析(第一弹)

    typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...

  8. Webpack编译结果浅析

    如今Webpack已经是一个不可或缺的前端构建工具,借助这个构建工具,我们可以使用比较新的技术(浏览器不能直接支持)来开发. 你是否好奇你写的代码经过Webpack构建之后会生成什么东西?是否有时调试 ...

  9. Typescript学习笔记(五) 模块机制

    javascript从es5之前都缺少一种模块机制,无法通过js引入文件,于是requirejs等等的加载器应运而生.这些加载器的使用也并不统一,产生了amd,commonjs,umd等等的规范,各有 ...

随机推荐

  1. Flask-配置与调试

    配置管理 复杂的项目需要配置各种环境.如果设置项很少,可以直接硬编码进来,比如下面的方式: app = Flask(__name__) app.config['DEBUG'] = True app.c ...

  2. Git添加远程库和从远程库中获取

    一. Git添加远程库 1. 在本地新建一个文件夹,在该文件夹使用Git工具,运行$ git init,将该文件夹变为本地Git仓库,同时会生成一个隐藏的.git文件夹. 2. 在该文件夹中用Note ...

  3. angular4.0项目文件解读

    这篇文章我觉得是很有用的,便于我们对ng项目的理解,同时在配置项目时,也能够很快的定位到相应文件. 摘录的别人的文章,首先感谢那个路人兄弟,下面就开始学习吧. File 文件 Purpose 用途 e ...

  4. file上传图片获取路径地址

    file上传图片获取路径地址 类似:点击button,选择图片,在对应的输入框input里面显示图片路径地址 类似这样 原理:通过opacity来隐藏原生的input file 然后用.file-bt ...

  5. css实现椭圆、半椭圆

    一.自适应的椭圆 1. 椭圆 css .ellipse{ width: 250px; height: 150px; margin: 50px; background: #FFD900; border- ...

  6. MySQL创建表的语句

    show variables like 'character_set_client';#查询字符集 show databases;#列出所有的服务器上的数据库alter create database ...

  7. .NET使用Office Open XML导出超大数量数据到 Excel

    我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EX ...

  8. MariaDB扩展特性--虚拟列

    存在于表中的列,它们的值是根据确定的表达式或者是根据表中其他列的值自动计算的. 虚拟列有两种,分别对应了定义虚拟列的修饰关键词: 'VIRTUAL'修饰词含义为该虚拟列的值会在查询的时候计算生成. ' ...

  9. spring boot系列03--spring security (基于数据库)登录和权限控制(下)

    (接上篇) 后台 先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 1 @Configuration 2 @EnableWebSecuri ...

  10. 合并 CentOS 6.8 的两个ISO镜像

    合并 CentOS 6.8 的两个ISO镜像 1.创建相关目录: [root@local ~] mkdir -p /mnt/dvd1 /mnt/dvd2 /mnt/dvd3 /mnt/iso 说明: ...