关于前端:源码学习之前端模块化

20次阅读

共计 2099 个字符,预计需要花费 6 分钟才能阅读完成。

<!– TOC –>

  • 1. 什么是模块化
  • 2. 为什么须要模块化
  • 3. 源码中的模块化

    • 3.1 AMD
    • 3.2 Commonjs
    • 3.3 Vue 源码解析之模块化

<!– /TOC –>


1. 什么是模块化

模块化并不是前端独有的思维。模块化是一种自顶向下的过程,通过把一个大的零碎,逐渐划分为一个个小的模块,这些模块外部封装了一些特定的性能,通过约定的接口对外裸露。各个模块之间互不烦扰,易于插拔。
模块化能够解耦代码,更好地进行复用,每个模块之间互不影响,不必放心变量净化、命名抵触等问题,同时也有利于并行开发,晋升效率。

js 最后是没有模块化的。随着前端利用越来越简单,比方,当一个 html 页面要申请多个 js 文件时,如何保障这些 js 文件之间的变量互不烦扰?为了解决诸如变量净化、命名抵触的问题,js 开始呈现了一些模块化的计划,从 2003 年提出的闭包模块化,再到 2009 年的 CommonJS 和 AMD,以及现在的 ES 模块化。

2. 为什么须要模块化

模块化的益处能够总结为以下几点:

  • 领有独立作用域,防止变量净化、命名抵触
  • 升高我的项目复杂度,进步开发效率
  • 晋升代码可复用性和可维护性

3. 源码中的模块化

在上述提到的 AMD 和 Commonjs 标准,对于模块化的定义不尽相同,在进行模块化时须要对不同环境进行兼容解决。

3.1 AMD

AMD(Asynchronous Module Definition),异步模块定义。在加载模块以及模块所依赖的其它模块时,AMD 都采纳 异步加载 的形式,防止模块加载阻塞网页渲染。

AMD 作为一个标准,只需定义其语法 API,而不关怀其实现。AMD 标准简略到只有一个 API,即模块定义 define 函数:

define(name?, [dependencies]?, factory)

  • name 是模块的标识,如果未提供则以文件名为标识;
  • dependencies 示意所依赖的模块;
  • factory 是模块初始化要执行的函数或对象,如果是函数,只执行一次,如果是对象,即为模块输入值。

AMD 标准次要是针对前端浏览器的标准。

3.2 Commonjs

CommonJS 标准规定,每个模块外部,module 变量代表以后模块。这个变量是一个对象,它的 exports 属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。

CommonJS 标准加载模块是 同步加载 的,也就是说,只有加载实现,能力执行前面的操作。

模块定义语法:
module.exports=factory()

CommonJS 次要是针对浏览器之外的 js 环境的标准。

3.3 Vue 源码解析之模块化

以 vue2 的源码为例,将源码折叠后你会看到如下代码:

这是一个 匿名自执行函数,这个匿名函数领有独立的作用域,既防止净化外界代码,也防止被外界代码净化。

如果须要用到外界的全局变量,能够通过参数传入,如图中的 this,这个this 实际上是 Window 对象,通过传入 this,使得 Window 由全局变量变为局部变量,当在前面那个代码块中拜访 this时,不须要将作用域链回退到顶层作用域,这样能够更快的拜访 Window 对象;将 Window作为参数传入,也能够在压缩代码时进行优化。如:(function(a,b){})(window); // window 被优化为 a

global即自执行传进来的 this 参数,也就是 Window 对象。

factory即传进来的第二个参数,也就是前面那个匿名函数。

开展第一个 function 能够看到如下代码:

typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
      (global = global || self, global.Vue = factory());

这段代码的作用是检测以后的运行环境反对哪种模块化标准,而后将 Vue 模块化,其中 exports 是 Commonjs 标准,define 是 AMD 的标准。

在源码中能够看到,factory()最初 return 的是一个 Vue 对象。

当检测出为 Commonjs 标准时,导出 Vue 对象的写法为:

module.exports = factory()

当检测出为 AMD 标准时,写法为:

define(factory)

为了更直观,改写一下这段代码:

if(typeof exports === 'object' && typeof module !== 'undefined'){
    // Commonjs 标准
    module.exports = factory();}else if(typeof define === 'function' && define.amd){
    // AMD 标准
    define(factory);
}else{
    // 其余状况下,将 Vue 挂载到全局对象中
    // 在浏览器里就是给 Window 对象增加 Vue 属性,属性值为 factory()返回的 Vue 对象
    global = global || self,
    global.Vue = factory();}

正文完
 0