js 的模块化历史 (commonJS AMD CMD)

228 阅读4分钟

(一)首先平常是怎么引入文件的

image.png

(二)据了解没有模块化概念之前, js在项目开发当中, 站的地位非常低

  1. 在ie6之前, 是没有js引擎的, 当时js应该在渲染引擎中, 在当时写一点js代码, 浏览器就直接崩溃了
  2. ie6之后出来了javascript引擎, 就是单独列出了一个 js 的解释器, 当时的写法是
<script type="text/javascript">
    ..xxxx...
<script>
  1. 浏览器后来发展功能加多, js代码加多, 这种写法不行了, 页面会写一堆js, 不好维护, 这是就用了开始的方法, 所有的逻辑放到一个文件中去维护, 然后只引入这一个文件 image.png

(三)随着前端的技术增加, 异步 ajax cookie..... js的代码会越来越多

  1. 开始我们说所有逻辑都放到一个js中, 但是如果多个页面呢? 每个页面都需要引入一次, 那不是重复引入吗
  2. 所以就想到了, 一个页面使用一个js去维护, (以页面为思想 分模块js文件)但是还是不合理
  3. 想到通过程序来划分模块, 那个页面用到这个程序就引入这个程序

(四)问题出现了

  1. 引入很多程序时就会出现
  • 污染全局 --> 变量重名 --> 变量覆盖
  • 文件相互依赖, 顺序不对时, 就会报错
  1. 那么模块化解决的问题就是:
  • 加载顺序
  • 污染全局

(五)所以我们在解决模块化文件就想到创建作用域, 谁创建作用域就是函数

  1. 这里我们想就会创建一个命名函数, 然后调用它, 将逻辑写到函数中
  2. 但是这样麻烦, 就想到用立即执行函数
  3. 我们将它放在作用域中, 但是需要在外部拿到数据, 就需要return 并且需要写成对象, 这样就可以导出很多数据

image.png

  1. 这样是解决了 , 但是, 看到这里是依赖b的, 所以就有了, 将每个模块抛出的东西去接收 模块A:

image.png

模块B:

image.png

  • 这里看到就是模块的注入
  • 解决了污染全局
  • 模块之间独立并且相互依赖

image.png 5. 但是我么在es5的方法中, 依然没有解决引入顺序不对就会报错的问题

(六)讨论到目前就是使用立即执行函数做模块化, 使用的是javascript语法本身去实现 [模块化, 插件化]

(七)之后Nodejs诞生, 带来了前所未有的模块化体验 叫 CommonJs

CommonJs -> 不是js, 是规范 -> 他不是js的方法, 集合, 库, 也不是框架, 就是一种规范 -> 来源于nodeJs -> 他是同步进行的

  • require('....') 引入模块
  • mdule.exports 导出模块 到这里我们不再依赖html页面, 我们依赖的是真正js实现模块化 但是他运行于node环境上

image.png

(八)客户端 的 "CommonJS" === AMD

Asynchronous Module Definition 异步模块定义

  • define(moudleName模块名, [module] 需要依赖的模块, factory工厂函里面写); // 定义模块
  • require([module], callback); // 引入模块

其实AMD, 浏览器也是不支持的, 是通过 require.js 实现的

模块A

image.png

模块B

image.png

  • index.js 配置 require.config 文件路径, 他不会像node中自动寻找文件
  • 前面所有模块加载完毕才执行回调函数, 这也叫前置依赖
  • 一个模块的回调函数的执行, 必须依赖前面的模块的执行完毕, 也就是前置依赖

image.png

html引入

image.png

看控制台发现了引入模块通过async实现异步加载

image.png

CMD - 他是阿里为模块化做的贡献

Common Module Definition 通用模块定义

  • define(function (require, export, module) {}); 定义模块
  • seajs.use([module路径], function (moduleA, moduleB, moduleC) {}); 使用模块

image.png

CMD 和 AMD 的区别

  • AMD 导入先加载模块, 依赖前置(不懂看上面)
  • CMD 依赖就近 按需加载, 虽然引入写在前面, 但是什么时候用到了他才会加载

ES6模块化

image.png

ES6 和 commonJS 的区别 不同点

导出 image.png

es6导入 image.png

commonJS导入 image.png

image.png

通过结果看出, 不同点

(1)

  • commonJS 模块输出的是一个值的拷贝
  • ES6 输出的是值的引用

(2)

  • commonJS模块是在运行时加载(因为commomJS是运行在服务端的, 程序编译后, 当正式运行时遇到require函数才会加载)
  • es6模块是在编译时加载(es6是载编译时模块就已经存在了)

最后我觉得, 刚开始js根本没有想到自己会发展这么快, 他以为自己只是窗口的简单脚本, 大量的项目, 不得不发明模块化, 所以es6他给了所有人一个交代, 去更新了这些必要的功能