We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
模块是一个可划分,对内封装起来,对外界可提供相关接口的代码块 模块化是模块之间有依赖关系的
模块是一个可划分,对内封装起来,对外界可提供相关接口的代码块
模块化是模块之间有依赖关系的
为什么需要模块化? 模块化是什么样的? 如何使用模块化?
文章
直接定义依赖 - 1999
命名空间模式 - 2002
命名空间为代码组织提供了某种排序
// file app.js var app = {}; // file greeting.js app.helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; // file hello.js app.writeHello = function (lang) { document.write(app.helloInLang[lang]); };
模块模式 - 2003
使用闭包封装了代码和数据,并且提供方法让外界访问到它
var greeting = (function () { var module = {}; var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; module.getHello = function (lang) { return helloInLang[lang]; }; module.writeHello = function (lang) { document.write(module.getHello(lang)) }; return module; }());
到了这里,不过都是完成了 隔离 的目标,但是依赖关系呢?
模块定义依赖关系 - 2006
注释定义依赖关系 - 2006
外部定义依赖关系 - 2007
在代码外部使用对象或者数组来定义依赖关系,常见的是配置文件;
// file deps.json { "files": { "main.js": ["sayHello.js"], "sayHello.js": ["helloInLang.js"], "helloInLang.js": [] } } // file helloInLang.js var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; // file sayHello.js function sayHello(lang) { return helloInLang[lang]; } // file main.js console.log(sayHello('en'));
沙盒模式 - 2009
使用一个顶级的对象来代替window的全局作用域,或者说直接是用一个构造函数来代替全局变量。每次都通过 new 一个沙盒对象来构建 文件之间的互相依赖关系。
// file sandbox.js function Sandbox(callback) { var modules = []; for (var i in Sandbox.modules) { modules.push(i); } for (var i = 0; i < modules.length; i++) { this[modules[i]] = Sandbox.modules[modules[i]](); } callback(this); } // file greeting.js Sandbox.modules = Sandbox.modules || {}; Sandbox.modules.greeting = function () { var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; return { sayHello: function (lang) { return helloInLang[lang]; } }; }; // file app.js new Sandbox(function(box) { document.write(box.greeting.sayHello('es')); });
到了这里,以上的所有依赖关系都得自己去处理构建的,然后再自己调用
依赖注入 - 2009
使用依赖注入的设计模式,可以直接调用其它文件,而不再需要自己创建
CommonJs Modules - 2009
commonJs是在 由于nodeJS 没有适当的模块规范来统一代码分发问题 的情况下诞生的,前身是 serverJS, 由 Mozilla 工程师Kevin Dangoor发起,社区人员一起开发的成果。所以,它是一种规范。
它是一种模块化的规范,主要是应用在除客户端js以外的Js应用中,包括服务端nodeJs和桌面应用,它是如何工作? --> 在发送给 js 引擎之前,会把一组组的使用commonJs模块规范的js文件打包,
会被把js代码放到被这样的形式函数中。
(function (exports, require, module, __filename, __dirname) { // ... // Your code injects here! // ... });
是我们非常熟悉的两个关键字: module 、require
使用CommonJs规范的模块都是同步加载的,即第一个模块加载完再会轮到第二个加载
// file greeting.js var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; var sayHello = function (lang) { return helloInLang[lang]; } module.exports.sayHello = sayHello; // file hello.js var sayHello = require('./lib/greeting').sayHello; var phrase = sayHello('en'); console.log(phrase);
ADM (Asynchronous Module Definition) - 2009
有了同步加载,当然会有异步加载规范,在 CommonJs 全面开启规范工作的同时,有另外一种声音 --- 讨论异步加载模块规范的可能性,讨论的动机即:这(异步加载模块)将有助于加快Web应用程序的加载速度,而无需进行任何预先打包。
另一名来自Mozilla的工程师James Burke(开发requireJs)提出ADM的基本思想: 模块加载不应该是同步的,更应该是使用浏览器功能来并行加载js脚本文件(也就是使用浏览器自带的功能来实现异步加载)。所以,异步加载模块规范也诞生了。
// file lib/greeting.js define(function() { var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; return { sayHello: function (lang) { return helloInLang[lang]; } }; }); // file hello.js define(['./lib/greeting'], function(greeting) { var phrase = greeting.sayHello('en'); document.write(phrase); });
这感觉是,两种不同的思想在对抗,但是由于 nodeJS 的蓬勃发展,npm社区的活跃,支持 CommonJS 的开发人员远大于支持 ADM 的开发人员
UMD (Universal Module Definition)- 2011
UMD (通用模块定义),它的出现很好的兼顾了主张同步模块加载的 commomJs 和 主张异步模块加载的 ADM ,可以在服务器环境和浏览器环境都分别支持 commonJS 和 ADM 。
主要思想是,通过判断当前的环境是支持commonJS 还是支持 ADM 来使用不同的参数达到目的。
(function(define) { define(function () { var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; return { sayHello: function (lang) { return helloInLang[lang]; } }; }); }( typeof module === 'object' && module.exports && typeof define !== 'function' ? function (factory) { module.exports = factory(); } : define ));
这段代码使用立即执行函数来判断当前的规范环境,如果是支持commomJs 环境的,则使用函数 function (factory) { module.exports = factory(); } ,否则则使用 define
function (factory) { module.exports = factory(); }
define
例如在CommonJS环境使用
为什么会这样做? 因为当时的支持CommomJs的环境不支持ADM,支持ADMd的环境也不支持CommonJs,两者冲突较大,让整个js生态环境没有得到一个统一的模块规范,呈现一团糟的状态。然后 UMD 的出现,兼顾了2者,得到了众多开发者的拥簇。
Labeled Modules - 2012
标签模块,主要思想是提出可传递模块,(看着代码,是不是感觉有点眼熟,形式类似于c语言的 go to 关键字)。 使用标签来代替模块的引入关系, 这个时候 ES6 已经研发2年了。 ```js // file greeting.js var helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; exports: var greeting = { sayHello: function (lang) { return helloInLang[lang]; } }; // file hello.js require: './lib/greeting'; var phrase = greeting.sayHello('es'); document.write(phrase); ```
YModules - 2013
基于 Yandex 上研发的一个模块化系统,主要是解决CommonJS和ADM没有解决的问题,但是入手的门槛高,有要求。
反正我没看懂...
ES6 模块规范 - 2015
ES6规范准备了5年,
看了代码你可能有点疑惑,这不是ES6规范的代码?
是的,ES6的一个版本即 ES 6.1 版本在2015年6月发布,正式名称是:《ECMAScript 2015 标准》(简称 ES2015),随后的2016年6月发布小幅修订的《ECMAScript 2016 标准》(简称 ES2016),因为差异过小,都统称 ES6 .
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。 -- 引用阮一峰老师的话
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。
-- 引用阮一峰老师的话
es6 的模块规范,完全取代了CommonJs 和 ADM 两者,即可以在服务端支持 js 模块化,又可以在客户端支持 js 模块化。不再需要使用 UMD 的兼顾两者了。
具体链接
// file lib/greeting.js const helloInLang = { en: 'Hello world!', es: '¡Hola mundo!', ru: 'Привет мир!' }; export const greeting = { sayHello: function (lang) { return helloInLang[lang]; } }; // file hello.js import { greeting } from "./lib/greeting"; const phrase = greeting.sayHello("en"); document.write(phrase);
done!
The text was updated successfully, but these errors were encountered:
No branches or pull requests
为什么想去了解 js 模块化
自己对模块化的理解
读 github 上的文章
文章
js 模块化要解决的问题
历史
直接定义依赖 - 1999
命名空间模式 - 2002
命名空间为代码组织提供了某种排序
模块模式 - 2003
使用闭包封装了代码和数据,并且提供方法让外界访问到它
模块定义依赖关系 - 2006
注释定义依赖关系 - 2006
外部定义依赖关系 - 2007
在代码外部使用对象或者数组来定义依赖关系,常见的是配置文件;
沙盒模式 - 2009
使用一个顶级的对象来代替window的全局作用域,或者说直接是用一个构造函数来代替全局变量。每次都通过 new 一个沙盒对象来构建 文件之间的互相依赖关系。
依赖注入 - 2009
CommonJs Modules - 2009
commonJs是在 由于nodeJS 没有适当的模块规范来统一代码分发问题 的情况下诞生的,前身是 serverJS, 由 Mozilla 工程师Kevin Dangoor发起,社区人员一起开发的成果。所以,它是一种规范。
它是一种模块化的规范,主要是应用在除客户端js以外的Js应用中,包括服务端nodeJs和桌面应用,它是如何工作? --> 在发送给 js 引擎之前,会把一组组的使用commonJs模块规范的js文件打包,
会被把js代码放到被这样的形式函数中。
是我们非常熟悉的两个关键字: module 、require
使用CommonJs规范的模块都是同步加载的,即第一个模块加载完再会轮到第二个加载
ADM (Asynchronous Module Definition) - 2009
有了同步加载,当然会有异步加载规范,在 CommonJs 全面开启规范工作的同时,有另外一种声音 --- 讨论异步加载模块规范的可能性,讨论的动机即:这(异步加载模块)将有助于加快Web应用程序的加载速度,而无需进行任何预先打包。
另一名来自Mozilla的工程师James Burke(开发requireJs)提出ADM的基本思想: 模块加载不应该是同步的,更应该是使用浏览器功能来并行加载js脚本文件(也就是使用浏览器自带的功能来实现异步加载)。所以,异步加载模块规范也诞生了。
UMD (Universal Module Definition)- 2011
UMD (通用模块定义),它的出现很好的兼顾了主张同步模块加载的 commomJs 和 主张异步模块加载的 ADM ,可以在服务器环境和浏览器环境都分别支持 commonJS 和 ADM 。
主要思想是,通过判断当前的环境是支持commonJS 还是支持 ADM 来使用不同的参数达到目的。
这段代码使用立即执行函数来判断当前的规范环境,如果是支持commomJs 环境的,则使用函数
function (factory) { module.exports = factory(); }
,否则则使用define
例如在CommonJS环境使用
为什么会这样做?
因为当时的支持CommomJs的环境不支持ADM,支持ADMd的环境也不支持CommonJs,两者冲突较大,让整个js生态环境没有得到一个统一的模块规范,呈现一团糟的状态。然后 UMD 的出现,兼顾了2者,得到了众多开发者的拥簇。
Labeled Modules - 2012
YModules - 2013
基于 Yandex 上研发的一个模块化系统,主要是解决CommonJS和ADM没有解决的问题,但是入手的门槛高,有要求。
反正我没看懂...
ES6 模块规范 - 2015
ES6规范准备了5年,
看了代码你可能有点疑惑,这不是ES6规范的代码?
是的,ES6的一个版本即 ES 6.1 版本在2015年6月发布,正式名称是:《ECMAScript 2015 标准》(简称 ES2015),随后的2016年6月发布小幅修订的《ECMAScript 2016 标准》(简称 ES2016),因为差异过小,都统称 ES6 .
es6 的模块规范,完全取代了CommonJs 和 ADM 两者,即可以在服务端支持 js 模块化,又可以在客户端支持 js 模块化。不再需要使用 UMD 的兼顾两者了。
具体链接
done!
The text was updated successfully, but these errors were encountered: