在浏览器中,受网络和浏览器渲染的制约,不能采用同步加载,只能采用异步加载。因而 AMD 规范应运而生javascript
AMD(Asynchronous Module Definition),意思就是"异步模块定义"。它采用异步方式加载模块,制定了定义模块的规则,这样模块和模块的依赖能够被异步加载,不影响它后面语句的运行。全部依赖这个模块的语句,都定义在一个回调函数中,等到加载完成以后,这个回调函数才会运行。这和浏览器的异步加载模块的环境恰好适应(浏览器同步加载模块会致使性能、可用性、调试和跨域访问等问题)css
本规范只定义了一个函数 "define",它是全局变量 define(id?, dependencies?, factory),参数分别是模块名,依赖,工厂方法html
<script type=”text/javascript” defer async=”true” src=”./require.js”></script> <script type=”text/javascript” defer async=”true” src=”js/init.js”></script>
//require.config 主要是用来对要加载文件的目录进行自定义 require.config({ baseUrl: 'js', paths: { "jquery": "../lib/jquery", "undersocre": "../lib/underscore", } }) require(['jquery', 'underscore'], function ($, _) { $(window).resize(function () { var color = ["rgba(", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ")"]; $(".background").css({ position: "fixed", top: "0px", bottom: "0px", left: "0px", right: "0px", background: color.join("") }); }) });
第一个参数是一个数组,值是依赖的模块。回调事件会在全部依赖模块加载完毕后才会执行java
该规范解决的浏览器环境下如何编写代码实现模块化,该规范定义可模块的一些遵循的特征,来支持能共用的模块jquery
define(factory)定义模块git
define(function(require, exports, module) { // do something });
每一个模块中都有个名叫"exports"的自由变量,这是一个模块能够在模块执行时添加模块 API 的对象。github
懒加载,在 require 时候才会加载模块api
这是 seajs 对象上绑定的属性和方法跨域
color.js数组
define("color", function(require, exports, module) { var \$ = require("jquery"); var createColor = function() { return ["rgba(", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ",", Math.floor(Math.random() * 255), ")"]; }; module.exports = { changeBg: function() { \$("#bg").css({ position: "fixed", top: "0px", bottom: "0px", left: "0px", right: "0px", background: createColor().join("") }); } }; });
使用非函数的工厂包装模块 text.js
define({ text: "我是初始化程序", text2: "我要开始执行了" });
init.js
define("init", function(require, exports, module) { var color = require("../src/color"); var initText = require("../src/text"); var \$ = require("jquery"); module.exports = { start: function() { console.log(initText.text + "," + initText.text2); $(function() { $("#change").click(function() { color.changeBg(); }); }); } }; });
sea.js.html
... <body id="bg"> <button id="change">点我我变色</button> </body> <script src="./lib/sea.js"></script> <script> seajs.config({ alias: { underscore: "underscore.js", init: "./src/init.js", color: "./src/color.js" } }); seajs.use(["underscore", "init"], function(u, init) { init.start(); }); </script> ...
目录结构
通常控制台报错 xxx is not a function
一些库不支持模块引入或者只支持 amd 规范的引入方式,不支持 cmd。全部须要对库进行一些改造
//Underscore.js 1.9.1 if (typeof define === "function" && define.amd && define.amd.jQuery) { define("underscore", [], function() { return \_; }); } //更改以下 if (typeof define === "function" && (define.amd || define.cmd)) { define("underscore", [], function() { return _; }); } //或者整个 define 的判断不要了 if (typeof define === "function") { define("underscore", [], function() { return _; }); }
是一种思想,就是一种兼容 commonjs,AMD,CMD 的兼容写法,define.amd / define.cmd / module 等判断当前支持什么方式,都不行就挂载到 window 全局对象上面去
(function (root, factory) { if (typeof define === 'function' && (define.amd || define.cmd)) { //AMD,CMD define(['b'], function(b){ return (root.returnExportsGlobal = factory(b)) }); } else if (typeof module === 'object' && module.exports) { //Node, CommonJS之类的 module.exports = factory(require('b')); } else { //公开暴露给全局对象 root.returnExports = factory(root.b); } }(this, function (b) { return {}; }));