2020-01-16

# 1. 第8部分. 模块化 

## 1.1. 什么是模块化

模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题进行系统性的分解以之处理。

模块化是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方式。可以想象一个巨大的系统代码,被整合优化分割成逻辑性很强的模块时,对于软件是一种何等意义的存在。

## 1.2. 为什么要模块化? 

无模块时刻面临着:

- 全局变量的灾难

- 函数命名冲突

- 依赖关系不好管理

## 1.3. 模块化解决方案

### 1.3.1. 闭包

每个js文件都是IIFE包裹的,各个js文件分别在不同的词法作用域中,相互隔离,最后通过闭包的方式来暴露变量。每个闭包都是独立的文件,每个文件仍然通过script下载,标签顺序就是模块的依赖关系。

### 1.3.2. 面向对象

在闭包的基础上,所有返回值都是对象,对象其实就是一些方法和属性的集合

优点:

1. 规范化输出,更加统一的便于相互依赖和引用

2. 使用类的方式开发,辩护后面的依赖进行扩展

### 1.3.3. UI

  雅虎出品的一个工具,包含模块化管理、js压缩、混淆、请求合并等性能优化的工具。

  通过YUI全局对象去管理不同模块,所有模块都只是对象上的不同属性,相当于是不同程序运行在操作系统上。核心是闭包。

  ------

### 1.3.4. CommonJS

commonjs作为Node模块化规范

特点:

  - 每个文件都是一个Module实例,原生Module对象

  - 文件内通过require对象引入指定模块

  - 所有文件加载均是同步完成

  - 通过module关键字暴露内容:

  >  exports与module.exports 为了方便Node为每个模块提供一个exports变量,指向module.exports, 等同于var exports = module.exprots。所以exports不能直接指向一个变量。

  - 每个模块加载一次后就会被缓存

  - 模块编译本质上是沙箱编译

  - node的API,只能在服务端上运行 

优点:

  - 强大的查找模块功能,开发十分方便

  - 标准化的输入输出,非常统一

  - 每个文件引入自己的依赖,最终形成文件依赖树

  - 模块缓存机制,提高编译效率

  - 利用node实现文件同步读取

  - 依赖注入变量的 **沙箱** 编译实现模块化

```

var a = require('');

module.exports = {}

```

沙箱编译之后

```

(function(exports, require, module,__filename,__dirname){})();

```

### 1.3.5. AMD规范和RequireJS(Asynchronous Module Definition)异步模块

  AMD规范:采用异步方式加载模块,模块加载不影响它后面的语句进行,所有依赖这个模块的语句,都定义在一个回调函数中,等到所有依赖加载完成后,这个回调函数才会运行。

RequireJs 是模块化工具框架,是AMD规范的具体实现

特点

  - 配置文件:有一个main文件,配置不同模块的路径,以及shim不满足AMD规范的js文件

  - 依赖前置,动态创建script引入依赖,在script标签的onload事件监听文件加载完毕,一个模块的回调函数必须等所有依赖都加载完毕之后,才可以执行,类似Promise.all

加载

```

    require([module], callback)

```

定义

```

    define(id?, dependencies?, factory);

```

```

    // main.js

    requirejs.config({

        shim:{},

        paths:{

            a:'/a.js',

            b:'/b.js',

            c:'/c.js',

            index:'/index.js',

        }

    })

    require(['index'], function(index){

        index();

    })

```

优点

  - 动态并行加载js。依赖前置,无需再考虑js加载顺序问题

  - 核心还是注入变量的沙箱编译,解决模块化问题

  - 规范化输入输出

  - 对于不满足AMD规范的文件可以很好的兼容

### 1.3.6. CMD规范和SaeJs

**特点** 

- define定义模块,require加载模块,exporta暴露变量

- 不同于AMD的依赖前置,CMD按需加载

- 推崇api功能单一,一个模块干一件事

**核心特点**

- 需要配置模块对应的url

- 入口文件执行只有,根据文件内的依赖关系整理出依赖树,然后通过script标签加载依赖

- 依赖加载完毕之后,执行根factory

- 在factory中遇到require,则去执行对应模块的factory,实现就近依赖

- 类似commonJS,对所有模块进行缓存模块url就是id

- 类似commonJs可以使用相对路径加载模块

- exports和return都可以暴露变量

### 1.3.7. ES6 Module

核心思想是尽量静态化,使得编译时就能确定依赖关系,以及输入和输出的变量。

**es6和commonJS的区别**

- ES6中的模块化在CommonJS的基础上,增加了关键字import  from export as default

- commonjs模块输出的是一个值的拷贝,es6模块输出的是值的引用

- commonjs模块是运行时加载,es6模块是编译时输出接口

- comminjs 模块输出的是值的拷贝,一旦输出一个值,模块内部的变化就影响不带这个值

- es6模块运行机制是js引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用,等到脚本真正执行的时候,再根据这个只读引用,到被加载的那个模块里面去取值。

**关键字**

- **import** 命令用于输入其他模块提供的功能;具有提升功能,本质是import命令是编译阶段执行的,在代码运行之前;静态执行,不能有变量,因为变量是运行时执行的;重复多次只加载一次

- **export** 用于规定模块的对外接口,可以输出变量、函数、类;规定的是对外接口,必须与模块内部的变量一一对应,不能只输出一个值;是动态绑定关系,通过该接口可以取到模块内部实时的值。可以出现在顶层任意位置,不能被包含

- **as** 关键字重命名

- **from** 指定路径,可以是相对,也可以是绝对,也可以是模块名。模块名不带路径,必须通过配置

- **default**

```

function foo(){}

export default foo;

```

```

import customName from ''

```

由于使用import命令的时候,需要知道所加载的变量名或函数名,为了给用户提供方便,可以不阅读文档加载模块。利用export default为模块指定默认输出。

利用default输出的接口都变为匿名接口,引入的时候可以直接重命名为任意名称使用;

只能定义一次,import不需要大括号。

本质上就是输出一个叫做default的变量或方法,然后系统允许你添加任意名字;

只是输出一个名为default的变量或方法,后面不能跟变量声明语句,可以跟class

**export 和 import 混合使用**

    export {foo, bar} from 'my_module' 并对外转发提供接口

**import()**

动态加载

执行到这一句的时候,同步加载模块信息

没有建立静态连接关系,类似于node的require方法

import()模块加载成功之后,这个模块会作为一个对象,当作then方法的参数。因此可以使用对象解构赋值的语法,获取输出接口。模块有default输出接口,可以用参数直接获得

import()也可以用在async函数中

场景

- 按需加载

- 条件加载

- 动态模块路径

**引入**

script加入 type = 'module' 

相当于script加上了defer,渲染完成之后加载,按照顺序加载

加上async之后,就不按照顺序执行了,按照加载完成就执行该模块      

**模块转码**                                                                **es6 module transpiler** 转码器,将es6模块转为commonjs模块或者AMD模块

npm install -g es6-module-transpiler

compile-modules convert file.js file1.js

compile-modules convert -o out.js file1.js

**systemjs** 垫片库

在浏览器内加载es6模块、amd模块、commonjs模块,将其转为es5

System.import('./app.js').then()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 1. 第8部分. 模块化 1.1. 什么是模块化 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分...
    敏_程序媛阅读 270评论 0 0
  • JavaScript 标准参考教程(alpha) 草稿二:Node.js CommonJS规范 GitHub TO...
    鑨的传人阅读 443评论 0 1
  • 模块通常是指编程语言所提供的代码组织机制,利用此机制可将程序拆解为独立且通用的代码单元。所谓模块化主要是解决代码分...
    MapleLeafFall阅读 1,165评论 0 0
  • 转载自:https://www.cnblogs.com/chenguangliang/p/5856701.html...
    小豆soybean阅读 692评论 0 2
  • 上一章介绍了模块的语法,本章介绍如何在浏览器和 Node 之中加载 ES6 模块,以及实际开发中经常遇到的一些问题...
    emmet7life阅读 2,694评论 0 1