本文只是seajs的入门贴。要详细了解,请看GitHub主页上的相关链接,精彩不断,精选几篇:
前端模块化开发的价值
前端模块化开发的历史
ID和路径匹配原则
与RequireJS的异同
模块的加载启动
模块标识
下面本文开始:
原生javascript的一个弱项,就是不支持模块化,说白了就是没有其他语言的import,include等语句。所以开发者就只有2个选择:把所有的东西写到一起,或者通过全局变量来交互
这至少造成以下几个问题:
1、污染全局变量,容易发生命名空间冲突,难以维护
2、无法按需加载
由于javascript官方迟迟未能解决这些问题,所以就有民间的社区提出标准,希望能自行解决,弥补语言的不足。主要有2种规范,一种是CommonJS提出的CMD规范,另一种是AMD规范,server端的node就是CMD的一种实现,seajs实现的也是CMD规范。所以熟悉node的用户会发现,seajs的API和node的API非常类似,这就是因为它们是同一种规范的不同实现
关于seajs的价值,这篇帖子说得更加详细:why seajs
官网上的5分钟入门例子也很简单,不过本文再简化一点,用一个更简单的例子进行说明:
目录结构简化后是这样的:
helloworld.html:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Hello Sea.js</title> </head> <body> <div id="thediv"> <p>hello world</p> </div> <script src="../javascript/sea.js"></script> <script> seajs.config({ alias: { "jquery": "jquery-debug.js" } }); seajs.use("../javascript/main"); </script> </body> </html>
seajs.use("../javascript/main");
main.js
define(function (require, exports, module) { var module1 = require("./module1"); alert(module1.add(1, 2)); })
熟悉node的用户会觉得非常眼熟,define方法是seajs自己的实现方式,require,exports,module都是CMD规范的设计,所以跟在node里是一样的。所有的seajs module,都应该写在define方法的factory function里
上面这段代码就引入了另一个模块module1,然后调用了其上的一个方法
module1.js
define(function (require, exports, module) { exports.add = function (a, b) { return a + b; } var $ = require("jquery"); $("#thediv").click(function () { alert("on click"); }); })
这里有一点要注意,就是对jQuery进行了CMD改造(也就是导出了变量$),这里有个小坑,后面会说
factory function有3个参数,分别是require,exports,module,作用跟node里是完全一样的。但是还有另外一种写法:
define(function () { return {sayHello: function () { alert("hi there"); }}; });
seajs的例子就到此为止了,确实非常易用
var $ = require("jquery");
var $ = require("jquery-debug");// path是"jquery-debug"
define("jquery/jquery/1.10.1/jquery-debug", [], function () { return jQuery; } );// module_id是"jquery/jquery/1.10.1/jquery-debug"
define("jquery-debug.js",[],function(){return jQuery});
define(function(){return jQuery});