跟着网站逐步变成”互联网运用顺序”,嵌入网页的Javascript代码愈来愈巨大,愈来愈庞杂。网页愈来愈像桌面顺序,须要一个团队分工合作、进度治理、单元测试等等……开辟者不能不运用软件工程的要领,治理网页的营业逻辑。
Javascript模块化编程,已成为一个急切的需求。
从CommonJS提及
CommonJS团队定义了module花样来处理JavaScript作用域题目,如许确保了每一个module都在本身的定名空间下实行。
依据CommonJS的范例,每一个文件就是一个模块,有本身的作用域。在一个文件内里定义的变量、函数、类,都是私有的,对其他文件不可见。
CommonJS范例划定,每一个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。
CommonJS给出2个东西来完成模块之间的依靠:
require() 用于在当前作用域引入已有的模块
module object 用于从当前作用域导出一些东东
那就先搞一个Hello world的小栗子来试下吧!
编写简朴的JavaScript模块
新建一个项目文件夹吧,虽然项目很小。。。起名commonjs,在里边新建2个JavaScript文件,离别定名为world.js和salute.js,代码以下:
// salute.js 打招呼
var MySalute = "Hello";
module.exports = MySalute;
/*注重高低是离别写在2个文件js文件里哦*/
// world.js
var MySalute = require("./salute");
var Result = MySalute + " world!";
console.log(Result);
然后蒙昧的我有新建了一个demo.html,(想要在浏览器里翻开看看是什么模样)内容以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="world.js"></script>
</head>
<body>
</body>
</html>
效果在浏览器中翻开,检察控制台大失所望,报了一个毛病
world.js:2 Uncaught ReferenceError: require is not defined
发明浏览器不兼容CommonJS的根本原因,在于缺乏四个Node.js环境的变量:
module
exports
require
global
只需能够供应这四个变量,浏览器就能够加载 CommonJS 模块,题目是能够处理的,然则彷佛并不怎样好玩,有兴致的朋侪能够去阮先生博客里走走啊传送门
如今我决议要去Node.js里边玩一下了
Node.js环境里玩一把
翻开命令行东西cd到项目目次:
效果顺遂打印出了Hello world!果真很有搞头啊,呵呵.
那末写到为止简朴完成了模块之间的援用,究竟这个CommonJS范例下还能够做些什么呢?到CommonJS官网看了一下,发明以下内容:
JavaScript是强调大面向对象言语,而且带有最快的诠释器,而且之前的JavaScript定义的APIs仅仅用于构建浏览器端的运用,但是呢有了这个CommonJS就能够构建更宽局限的运用了,细致点就是能够用JavaScript来写:
服务器端运用Server-side JavaScript applications
命令行东西Command line tools
基于GUI的桌面运用Desktop GUI-based applications
Hybrid applications (Titanium, Adobe AIR)(这个是什么?虽然我如今还不晓得,但觉得它很牛逼)
AMD是用来干甚么的?
AMD (Asynchronous Module Definition)浅薄的明白异步模块定义。。。
一开始人人能够以为CommonJS的天分就是同步,它的模块体系并不实用于浏览器,而这个AMD就是指定了一个规范,证实给他人看模块化的JavaScript能够异步加载依靠,处理同步加载涌现的题目。
定义
define函数是AMD定义模块的要领:
define(id?: String, dependencies?: String[], factory: Function|Object);
id:指定模块名字
dependencies:指明依靠
factory:是定义模块的,能够是function或object,假如是function那末函数的返回值就是module 导出的值。
examples
define('myModule', ['jquery'], function($) {
// $ is the export of the jquery module.
$('body').text('hello world');
});
// and use it
require(['myModule'], function(myModule) {});
RequireJS
跟着网站功用逐步雄厚,网页中的js也变得愈来愈庞杂和痴肥,原有经由过程script标签来导入一个个的js文件这类体式格局已不能满足如今互联网开辟情势,我们须要团队合作、模块复用、单元测试等等一系列庞杂的需求。
RequireJS是一个异常玲珑的JavaScript模块载入框架,是AMD范例最好的完成者之一。最新版本的RequireJS紧缩后只要14K,可谓异常轻量。它还同时能够和其他的框架协同事情,运用RequireJS必将使您的前端代码质量得以提拔。此段出处
对照js模块的同步加载和异步加载
CommonJS范例加载模块是同步的,也就是说,只要加载完成,才实行背面的操纵。AMD范例则是非同步加载模块,许可指定回调函数。因为Node.js重要用于服务器编程,模块文件平常都已存在于当地硬盘,所以加载起来比较快,不必斟酌非同步加载的体式格局,所以CommonJS范例比较实用。然则,假如是浏览器环境,要从服务器端加载模块,这时刻就必需采纳非同步情势,因而浏览器端平常采纳AMD范例。
浏览器同步加载js模块
新建a.js
(function(){
function test(){
alert("it works");
}
test();
})()
新建demo1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="a.js"></script>
</head>
<body>
<span>body</span>
</body>
</html>
在浏览器中运转demo1.html,alert实行的时刻,html内容是一片空白的,即<span>body</span>并未被显现,当点击肯定后,才涌现,这就是JS壅塞浏览器衬着致使的效果。
RequireJS异步加载js模块
把a.js改写以下:
define(function(){
function test(){
alert("it works");
}
test();
})
到githug下载require.jsRequireJS download修正demo1.html以下:
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
require(["a"]);
</script>
</head>
<body>
<span>body</span>
</body>
</html>
浏览器提醒了”it works”,申明运转准确,然则有一点不一样,此次浏览器并非一片空白,body已出如今页面中,目前为止能够晓得requirejs具有以下长处:
防备js加载壅塞页面衬着
治理模块之间的依靠性,便于代码的编写和保护,使得代码越发文雅。
CMD范例
CMD(Common Module Definition) 模块定义范例。该范例明白了模块的基础誊写花样和基础交互划定规矩。在 CMD 范例中,一个模块就是一个文件。代码的誊写花样以下:
define(factory);
define 是一个全局函数,用来定义模块。define 接收 factory 参数,factory 能够是一个函数,也能够是一个对象或字符串。
factory 为对象、字符串时,示意模块的接口就是该对象、字符串。比方能够以下定义一个 JSON 数据模块:
define({ "foo": "bar" });
require 是一个要领,接收 模块标识 作为唯一参数,用来猎取其他模块供应的接口。
define(function(require, exports) {
// 猎取模块 a 的接口
var a = require('./a');
// 挪用模块 a 的要领
a.doSomething();
});
require.async 要领用来在模块内部异步加载模块,并在加载完成后实行指定回调。callback 参数可选。
define(function(require, exports, module) {
// 异步加载一个模块,在加载完成时,实行回调
require.async('./b', function(b) {
b.doSomething();
});
// 异步加载多个模块,在加载完成时,实行回调
require.async(['./c', './d'], function(c, d) {
c.doSomething();
d.doSomething();
});
});
require 是同步往下实行,require.async 则是异步回调实行。require.async 平常用来加载可耽误异步加载的模块。
更细致内容请检察CMD 模块定义范例
sea.js
RequireJS 和 Sea.js 都是模块加载器,提倡模块化开辟理念,中心代价是让 JavaScript 的模块化开辟变得简朴天然。
在 SeaJS 中,一切 JavaScript 文件都应该用模块的情势来誊写,而且一个文件只包括一个模块。
运用全局函数 define 来定义模块:
define(id?, dependencies?, factory);
id
当前模块的唯一标识。该参数可选。假如没有指定,默以为模块地点文件的接见途径。假如指定的话, 必需是顶级或相对标识(不能是相对标识)。
dependencies
当前模块所依靠的模块,是一个由模块标识构成的数组。该参数可选。假如没有指定,模块加载器会从 factory.toString() 中解析出该数组。
factory
模块的工场函数。模块初始化时,会挪用且仅挪用一次该工场函数。factory 能够是函数, 也能够是对象、字符串等恣意值,这时刻 module.exports 会直接设置为 factory 值。
factory 函数在挪用时,会一直传入三个参数: require、exports 和 module, 这三个参数在一切模块代码里可用。
define(function(require, exports, module) {
// The module code goes here
});