404
That's a Four-Oh-Four.Take me home.
在 startUP 中,一个模块就是一个文件。代码的书写格式如下:
define(factory);
21 | define 是一个全局函数,用来定义模块。
define 接受 factory 参数,factory 是一个函数表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module:
define(function(require, exports, module) {
22 |
23 | // 模块代码
24 |
25 | });
26 | 27 | ← 28 | 29 | 模块系统概述 30 | 31 | 路径规则 32 | 33 | → 34 |
相对标识只出现在模块环境中,以 "." 开头。会相对当前模块的 URI 来解析:
// 在 http://statUP.com/js/b.js 中:
require('./b');
21 | // => http://statUP.com/js/b.js
22 | 顶级标识不以点(".")或斜线("/")开始, 会相对 startUP 的 base 路径来解析:
// 假设 base 路径是:http://statUP.com/js/libs/
23 | // 在模块代码里:
24 | require('jquery/1.7.1/jquery');
25 | // => http://statUP.com/js/libs/jquery/1.7.1/jquery.js
26 | 当然,也可以手工配置 base 路径:
seajs.config({
27 | base: 'common/js'
28 | });
29 |
30 | // 在模块代码里:
31 | require('jquery');
32 | // => common/js/jquery.js
33 | 除了相对和顶级标识之外的标识都是普通路径。普通路径的解析规则,和 HTML 代码中的 script.src 一样,会相对当前页面来解析。
// 在 http://startUP.com/js/main.js 中:
34 | require('http://example.com/js/a');
35 | // => http://example.com/js/a.js
36 | 37 | ← 38 | 39 | 定义规范 40 | 41 | 书写约定 42 | 43 | → 44 |
#快速上手 21 | 在 starUP 中,一个文件就是一个模块。所有模块都遵循 starUP 规范,我们可以像在 Node 环境中一样来书写模块代码:
define(function(require, exports, module) {
22 | var $ = require('jquery');
23 |
24 | exports.rules = function() {
25 | $('#box').toggle('slow');
26 | };
27 | });
28 | 将上面的代码保存为 main.js,然后就可以通过 starUP 来加载使用了:
seajs.config({
29 | alias: {
30 | 'jquery': 'http://startUP.org/jquery/1.7.2/jquery.js'
31 | }
32 | });
33 |
34 | seajs.use(['./main', 'jquery'], function(main, $) {
35 | $('#context').click(rules);
36 | });
37 | 38 | ← 39 | 40 | 书写约定 41 | 42 | 全局配置 43 | 44 | → 45 |
使用 starUP 书写模块代码时,需要遵循一些简单规则:
在模块代码中,第一个参数 必须 命名为 require.
// 错误!
21 | define(function(resolve) {
22 | // ...
23 | });
24 |
25 | // 正确!
26 | define(function(require) {
27 | // ...
28 | });
29 | 不要重命名 require 函数,或在任何作用域中给 require 重新赋值。
// 错误 - 重命名 "require"!
30 | var req = require, mod = req("./mod");
31 |
32 | // 错误 - 重定义 "require"!
33 | require = function() {};
34 |
35 | // 错误 - 重定义 "require" 为函数参数!
36 | function F(require) {}
37 |
38 | // 错误 - 在内嵌作用域内重定义了 "require"!
39 | function F() {
40 | var require = function() {};
41 | }
42 | require 的参数值 必须 是字符串直接量。
// 错误!
43 | require(Module);
44 |
45 | // 错误!
46 | require("js-" + "module");
47 |
48 | // 错误!
49 | require("js - module".toLowerCase());
50 |
51 | // 正确!
52 | require("module");
53 | 在书写模块代码时,必须遵循这些规则。
为什么require参数如此重要原因是:
当前模块所依赖的模块是一个由模块标识组成的数组,通过factory.toString() 中解析。为了使静态分析能成功获取到模块依赖信息,在书写模块时,需要遵循以上的 规则。
54 | ← 55 | 56 | 路径规则 57 | 58 | 基本用法 59 | 60 | → 61 |
可以使用 config 方法来配置加载器。
seajs.config({
21 | alias: {
22 | 'jquery': 'jquery/1.7.1/jquery'
23 | },
24 | preload: [
25 | Function.prototype.bind ? '' : 'es5-safe',
26 | this.JSON ? '' : 'json'
27 | ],
28 | base: 'common/libs/',
29 | });
30 | 支持以下配置选项:
当模块标识很长时,可以使用 alias 配置来简化。
seajs.config({
31 | alias: {
32 | 'jquery': 'jquery/1.7.1/jquery'
33 | }
34 | });
35 | main.js
define(function(require, exports, module) {
36 | var $ = require('jquery');
37 | //=> http://startUP/jquery/1.7.1/jquery.js
38 | });
39 | 使用 preload 配置项,可以在普通模块加载前,提前加载并初始化好特定模块。
// 在老浏览器中,提前加载好 ES5 和 json 模块:
40 | seajs.config({
41 | preload: [
42 | Function.prototype.bind ? '' : 'es5-safe',
43 | this.JSON ? '' : 'json'
44 | ]
45 | });
46 | preload 中的空字符串会被忽略掉。
starUP 在解析顶级标识时,会相对 base 路径来解析。
47 | ← 48 | 49 | 基本用法 50 | 51 | API快速参考 52 | 53 | → 54 |
和requireJS相似的,startUP也是用JavaScript编写的js框架,主要功能是可以按不同的先后依赖关系对 JavaScript 等文件的进行加载工作,可简单理解为js文件的加载器,它非常适合在浏览器中使用,它可以确保所依赖的js文件加载完成之后再加载当前的js文件,这在大量使用js文件的项目中可确保各个js文件的先后加载顺序,确保避免了以前因某些原因某个文件加载慢而导致其它加载快的文件需要依赖其某些功能而出现某函数或某变量找不到的问题。
在早期编写JavaScript时,我们只需在 script 标签内写入JavaScript的代码就可以满足我们对页面交互的需要了。但随着时间的推移,时代的发展,原本的那种简单粗暴的编写方式所带来的诸如逻辑混乱,文件依赖管理问题,全局变量暴露,开发效率低,等问题接踵而至,社区为了解决这些问题提出了很种的解决方案,其中javaScript模块化编程是目前最有效的一种方式。
2009年Node.js横空出世,主要用于服务器编程。而对于服务器端来说,必须要拥有模块化开发的方式。因此Commonjs社区制定了一个与社区同名的关于模块化的规范——Commonjs。
Commonjs规范分为三部分:
根据CommonJS规范的规定,每个文件就是一个模块,有自己的作用域,也就是在一个文件里面定义的变量、函数、类,都是私有的,对其他文件是不可见的。
// a.js
21 | const name = "max";
22 | const getName = function() {
23 | return name;
24 | }
25 | 上面代码中,变量name和函数getName,是当前文件a.js私有的,其他文件不可见。如要在其他的文件中访问变量name,最好的方式是输出模块对象module.exports:
// a.js
26 | const name = "max";
27 | const getName = function() {
28 | return name;
29 | }
30 | module.exports.getName = getName;
31 | 上面代码通过module.exports对象扩展了一个方法,该方法就是模块外部与内部通信的桥梁。加载模块需要使用require方法,该方法读取一个文件并执行,最后返回当前加载文件内部的module.exports对象。
var object = require('./a.js');
32 | console.log(object.getName()); //max
33 | CommonJS规范加载模块是同步的,也就是说,加载完成才执行后面的操作,Node.js主要用于服务器编程,模块都是存在本地硬盘,由于这个特性决定了CommonJS只能在服务器端大规模使用。 34 | 而在浏览器端由于文件都放在服务器上,如果网速不够快的话,前面的文件如果没有加载完成,浏览器就会失去响应!由此不适合同步方式加载,但模块化开发管理方式势在必行,根据这个需求,针对浏览器的模块化规范就产生了 ——AMD就产生了!
AMD的全名叫做:Asynchronous Module Definition即异步模块定义。它采用了异步的方式来加载模块,然后在回调函数中执行主逻辑,因此模块的加载不影响它后面的模块的运行。
define(id?, deps ?, factory);
35 | 规范如下:
在加载模块方面,AMD和CommonJs都是使用require。
require([module]);
36 | 参数[module],是一个数组,里面的成员就是需要加载的模块;
//启动程序
37 | requirejs([module], callback);
38 | requirejs等同于require, 参数callback,是加载成功之后的回调函数。
虽然require.js实现了异步的模块化,解决了命名冲突,文件依赖,增加文件的独立性降低了耦合度,但它仍然有一些不足的地方,在使用require.js的时候,我们必须要提前加载所有的依赖,然后才可以使用,而不是需要使用时再加载,使得初次加载其他模块的速度较慢,提高了开发成本。
而startUP则借鉴了require.js的设计思想,并且改变了他不足的地方。
和requireJS相似的,startUP也是用JavaScript编写的js框架,主要功能是可以按不同的先后依赖关系对 JavaScript 等文件的进行加载工作,可简单理解为js文件的加载器,它非常适合在浏览器中使用,它可以确保所依赖的js文件加载完成之后再加载当前的js文件,这在大量使用js文件的项目中可确保各个js文件的先后加载顺序,确保避免了以前因某些原因某个文件加载慢而导致其它加载快的文件需要依赖其某些功能而出现某函数或某变量找不到的问题。
在早期编写JavaScript时,我们只需在 script 标签内写入JavaScript的代码就可以满足我们对页面交互的需要了。但随着时间的推移,时代的发展,原本的那种简单粗暴的编写方式所带来的诸如逻辑混乱,文件依赖管理问题,全局变量暴露,开发效率低,等问题接踵而至,社区为了解决这些问题提出了很种的解决方案,其中javaScript模块化编程是目前最有效的一种方式。
2009年Node.js横空出世,主要用于服务器编程。而对于服务器端来说,必须要拥有模块化开发的方式。因此Commonjs社区制定了一个与社区同名的关于模块化的规范——Commonjs。
Commonjs规范分为三部分:
根据CommonJS规范的规定,每个文件就是一个模块,有自己的作用域,也就是在一个文件里面定义的变量、函数、类,都是私有的,对其他文件是不可见的。
// a.js
21 | const name = "max";
22 | const getName = function() {
23 | return name;
24 | }
25 | 上面代码中,变量name和函数getName,是当前文件a.js私有的,其他文件不可见。如要在其他的文件中访问变量name,最好的方式是输出模块对象module.exports:
// a.js
26 | const name = "max";
27 | const getName = function() {
28 | return name;
29 | }
30 | module.exports.getName = getName;
31 | 上面代码通过module.exports对象扩展了一个方法,该方法就是模块外部与内部通信的桥梁。加载模块需要使用require方法,该方法读取一个文件并执行,最后返回当前加载文件内部的module.exports对象。
var object = require('./a.js');
32 | console.log(object.getName()); //max
33 | CommonJS规范加载模块是同步的,也就是说,加载完成才执行后面的操作,Node.js主要用于服务器编程,模块都是存在本地硬盘,由于这个特性决定了CommonJS只能在服务器端大规模使用。 34 | 而在浏览器端由于文件都放在服务器上,如果网速不够快的话,前面的文件如果没有加载完成,浏览器就会失去响应!由此不适合同步方式加载,但模块化开发管理方式势在必行,根据这个需求,针对浏览器的模块化规范就产生了 ——AMD就产生了!
AMD的全名叫做:Asynchronous Module Definition即异步模块定义。它采用了异步的方式来加载模块,然后在回调函数中执行主逻辑,因此模块的加载不影响它后面的模块的运行。
define(id?, deps ?, factory);
35 | 规范如下:
在加载模块方面,AMD和CommonJs都是使用require。
require([module]);
36 | 参数[module],是一个数组,里面的成员就是需要加载的模块;
//启动程序
37 | requirejs([module], callback);
38 | requirejs等同于require, 参数callback,是加载成功之后的回调函数。
虽然require.js实现了异步的模块化,解决了命名冲突,文件依赖,增加文件的独立性降低了耦合度,但它仍然有一些不足的地方,在使用require.js的时候,我们必须要提前加载所有的依赖,然后才可以使用,而不是需要使用时再加载,使得初次加载其他模块的速度较慢,提高了开发成本。
而startUP则借鉴了require.js的设计思想,并且改变了他不足的地方。
39 | 定义规范 40 | 41 | → 42 |
seajs.use('./a');
21 |
22 | seajs.use('./a', function(a) {
23 | a.doSomething();
24 | });
25 |
26 | seajs.use(['./a', './b'], function(a, b) {
27 | a.doSomething();
28 | b.doSomething();
29 | });
30 | seajs.config({
31 | alias: {
32 | 'jquery': 'jquery/1.7.1/jquery'
33 | },
34 | preload: [
35 | Function.prototype.bind ? '' : 'es5-safe',
36 | this.JSON ? '' : 'json'
37 | ]
38 | });
39 | define(function(require, exports, module) {
40 |
41 | // The module code goes here
42 |
43 | });
44 | define(function(require) {
45 | var main = require('./main');
46 | main.rules();
47 | });
48 | define(function(require) {
49 | define(function(require, exports) {
50 | // snip...
51 | exports.foo = 'bar';
52 | exports.relus = function() {};
53 | });
54 | });55 | ← 56 | 57 | 全局配置 58 |