GoJS 使用文档
Loading...
##简介 GoJS 是一个适用于 Web 的 JavaScript 模块加载器,它可以帮助你更优雅地组织代码和模块。它解决了模块之间的依赖问题和命名冲突问题,同时也解决了同类框架中合并压缩成本高的问题,让你能够更加轻松愉快地享受编码的乐趣。 ##获取 - [下载 .zip](https://github.com/Lanfei/GoJS/archive/master.zip) - [下载 .tar.gz](https://github.com/Lanfei/GoJS/archive/master.tar.gz) -
在 GitHub 上查看
##入门 - [为什么要使用 GoJS](#why-gojs) - [5 分钟上手 GoJS](#quick-start) - [GoJS 基础 API](#api) - [官方示例](#examples) ##基础 - [CMD 模块定义规范](#cmd) - [GoJS 模块标识](#identifier) - [require 书写约定](#require) - [GoJS 的详细配置](#config) ##进阶 - [如何将现有模块改造为 CMD 规范](#reform) ##插件 - [go-css](#go-css) - [go-json](#go-json) - [go-text](#go-text) 最后,向
RequireJS
和
Sea.js
致敬,也向所有投身于开源工作的自由人致敬。 注:部分文档参考自 `Sea.js`。
##为什么要使用 GoJS 随着互联网的飞速发展,前端开发越来越复杂。本文将从实际项目中遇到的问题出发,讲述GoJS解决了哪些前端开发中的难题,以及如何使用 GoJS 进行模块化的前端开发。 ###命名冲突 我们从一个简单的例子开始。在开发过程中,为了考虑重用性,常常会把一些底层的、通用的代码提取出来,独立成一个函数,如: ```js function print(){ // some codes } ``` 并将它放入 util.js 文件中,当其它页面需要用到这个功能的时候,只要引入 util.js 就可以了。 但是,这种方法会引入一些隐性的问题: > 为什么你这个函数叫 **print** 啊!正好我也写了一个函数叫 **print** 把你的给覆盖了啊!结果页面就出问题了啊!要不我这个叫 **print2** 吧!(#‵′) > 为什么你这个函数叫 **print** 啊!我引入了一个开源模块,里面也有一个函数叫 **print** 啊!改人家的怕有问题,要不改你的吧!(╯‵□′)╯︵┻━┻ 咳咳,回到正题,那么如何避免这种情况呢?我们可以用对象模拟命名空间: ```js var Util = {}; Util.print = function(){ // some codes }; ``` 但这种方案只能减小冲突的几率,当项目参与的开发人员比较多时,还是可能出现冲突的情况,如命名空间本身的冲突等等,于是只好把命名空间拉长: ```js // 本代码来自 Yahoo! 的一个开源项目 if (org.cometd.Utils.isString(response)) { return org.cometd.JSON.fromJSON(response); } if (org.cometd.Utils.isArray(response)) { return response; } ``` 这样的确可以更大程度上地缓解命名冲突,但调用一个简单的方法,需要记住如此长的命名空间,无疑增加了编码的成本,更是剥夺了许多编码的乐趣。 命名冲突的问题暂且放着,我们继续往下看: ###文件依赖 我们在来讲一个简单的例子,我编写了一个通用的组件 dialog.js,这样其它项目成员就不需要重复造轮子了。 于是有一位同学就这么做了: ```html ``` 看上去似乎没错,但页面报错了!原来我的组件中引用了上一个例子中的 print 方法,而页面中没有引入 util.js,于是给页面加上: ```html ``` 好像又没什么问题了,但我们来看看这个例子的后续发展: - **某天,我扩充了组件的功能,除了依赖 util.js 外,还需要引入 ajax.js** 但这时候已经有大量页面用到了这个组件,于是只好全局搜索每一个调用的地方,给每个页面都加上对 ajax.js 的引用。 - **某天,需求有变,组件不再需要用到 print 方法了,于是再次全局搜索去掉了对 util.js 的引用** 结果好多页面都报错了,原来,虽然 dialog.js 已经不再依赖于 util.js,但页面中的其它模块仍然对 util.js 存在依赖,于是只好累感不爱地去检查每一个页面,看是否仍然依赖于 util.js。 - **某天,需求又变,ajax.js 需要用到 util.js 中的方法** WTF!看到哪句你哭了,不转不是中国人! ###Why GoJS 我们来看看GoJS是如何解决上述问题的,我们遵循CMD(Common Module Definition)规范来改造上述模块: ```js // util.js define(function(require, exports){ // 使用 exports 导出模块接口 exports.print = function(/* args */){ // some codes; } }); ``` 而 Dialog 模块则变成: ```js // dialog.js define(function(require, exports){ // 通过 require 获取其它模块的接口 var util = require('util'); function init(/* args */){ util.print('some text'); } // 也可以通过 return 导出模块接口 return {init: init}; }); ``` 而在页面中使用模块也会变的非常简单: ```html ``` 高潮到了!我们可以看出 GoJS 带来的两大好处: - **通过 `exports` 暴露接口**。这意味着我们不再需要全局变量了,更不需要命名空间,彻底地解决了命名冲突问题。 - **通过 `require` 引入依赖**。开发者不再需要手动管理文件依赖了,GoJS 会自动分析并加载模块依赖。 ###小结 GoJS 解决了前端开发中命名冲突和文件依赖两大问题,对前端项目来说,它极大地减少了维护成本,提高了编码的效率,同时也非常有助于代码的组织和性能的优化。对开发者来说,他们可以只专注于他们所关注的,不必理会模块逻辑以外的环境,让他们能够更加享受编码的乐趣。
##5 分钟上手 GoJS 下面我们通过一个简单而经典的例子来了解 GoJS 的使用。 ###初始化 在页面中通过 `script` 标签引入 GoJS 后,再通过一段简单的代码进行配置: ```html ``` 在不需要配置 GoJS 的场景下,可以直接通过 `data-main` 来设置入口模块: ```html ``` ###模块代码 下面开始编写我们的模块,首先是入口模块 `main.js`: ```js define(function(require){ // 通过 require 引入依赖 var hello = require('./hello'); hello.sayTo('GoJS'); }); ``` 接下来是模块 `hello.js`: ```js define(function(require, exports, module) { function sayTo(target) { document.body.innerHTML = 'Hello, ' + target; } // 通过 exports 导出接口 exports.sayTo = sayTo; // 或者通过 module.exports 导出整个接口 // module.exports = { // sayTo: sayTo // }; }); ``` ###完成 一个简单的 **Hello GoJS** 就这样完成了。怎么样,上手GoJS真的只需要5分钟吧? 所有示例存放于 [examples](https://github.com/Lanfei/GoJS/tree/master/examples) 目录中。
##GoJS 基础 API 以下是 GoJS 的常用API: ###gojs.config(options) 用来 配置 GoJS 或读取 GoJS 配置: ```js // 配置 gojs.config({ base: 'path/to/base', debug: true }); // 读取 console.log(gojs.config()); ``` 更多配置选项请参考 [GoJS 的详细配置](#config)。 ###gojs.use(ids, callback?) 用来在页面中加载一个或多个模块。 ```js // 加载一个模块 gojs.use('./a'); // 加载多个模块 gojs.use(['./a', './b']); // 加载模块后执行回调 gojs.use(['./a', './b'], function(a, b){ a.doSomething(); b.doSomething(); }); ``` **注意**:`gojs.use` 理论上应该只用于加载启动模块,不应该出现在 `define` 中的模块代码里。在代码中需要异步加载其它模块时,请使用 `require.async` 方法。 ###define(factory) 用来定义一个模块,统一规范如下: ```js define(function(require, exports, module) { // 模块代码 }); ``` `require`, `exports` 和 `module` 三个参数可酌情省略,具体用法如下。 ###require(id) `require` 用来获取指定模块的接口。 ```js define(function(require) { // 获取模块 a 的接口 var a = require('./a'); // 调用模块 a 的方法 a.doSomething(); }); ``` **注意**:`require` 方法需要遵循一定的 [书写规范](#require)。 ###require.async(ids, callback?) 用来在模块内部异步加载一个或多个模块。 ```js define(function(require) { // 异步加载一个模块,在加载完成时,执行回调 require.async('./b', function(b) { b.doSomething(); }); // 异步加载多个模块,在加载完成时,执行回调 require.async(['./c', './d'], function(c, d) { c.doSomething(); d.doSomething(); }); }); ``` ###exports 用来在模块内部对外提供接口。 ```js define(function(require, exports) { // 对外提供 foo 属性 exports.foo = 'bar'; // 对外提供 doSomething 方法 exports.doSomething = function() {}; }); ``` ###module.exports 与 `exports` 类似,用来在模块内部对外提供接口。 ```js define(function(require, exports, module) { // 对外提供接口 module.exports = { name: 'a', doSomething: function() {}; }; }); ``` 关于 `define`,`require`,`exports` 与 `module.exports` 的更多内容,请参考 [CMD 模块定义规范](#cmd)。
##官方示例 -
Hello GoJS
-
异步加载
-
模块合并
-
登陆模块
##CMD 模块定义规范 在 GoJS 中,所有 JavaScript 模块都遵循 CMD([Common Module Definition](https://github.com/cmdjs/specification/blob/master/draft/module.md)) 模块定义规范。该规范明确了模块的基本书写格式和基本交互规则。 在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下: ```js define(factory); ``` ###define `Function` `define` 是一个全局函数,用来定义模块。 ###define `define(factory)` `define` 接受 `factory` 参数,`factory` 可以是一个函数,也可以是一个对象或字符串。 `factory` 为对象、字符串时,表示模块的接口就是该对象、字符串。比如可以如下定义一个 JSON 数据模块: ```js define({ "foo": "bar" }); ``` 也可以通过字符串定义模板模块: ```js define('I am a template. My name is {{name}}.'); ``` `factory` 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。`factory` 方法在执行时,默认会传入三个参数:`require`、`exports` 和 `module`: ```js define(function(require, exports, module) { // 模块代码 }); ``` ###define.cmd `Object` 一个空对象,可用来判定当前页面是否有 CMD 模块加载器: ```js if (typeof define === "function" && define.cmd) { // 有 GoJS 等 CMD 模块加载器存在 } ``` ###require `Function` `require` 是 `factory` 函数的第一个参数。 ###require `require(id)` `require` 是一个方法,接受 [模块标识](#identifier) 作为唯一参数,用来获取其他模块提供的接口。 ```js define(function(require, exports) { // 获取模块 a 的接口 var a = require('./a'); // 调用模块 a 的方法 a.doSomething(); }); ``` **注意**:在开发时,`require` 的书写需要遵循一些 [简单约定](#require)。 ###require.async `require.async(id, callback?)` `require.async` 方法用来在模块内部异步加载模块,并在加载完成后执行指定回调。`callback` 参数可选。 ```js 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` 一般用来加载可延迟异步加载的模块。 ###require.resolve `require.resolve(id)` 使用模块系统内部的路径解析机制来解析并返回模块路径。该函数不会加载模块,只返回解析后的绝对路径。 ```js define(function(require, exports) { console.log(require.resolve('./b')); // => http://example.com/path/to/b.js }); ``` ###exports `Object` `exports` 是一个对象,用来向外提供模块接口。 ```js define(function(require, exports) { // 对外提供 foo 属性 exports.foo = 'bar'; // 对外提供 doSomething 方法 exports.doSomething = function() {}; }); ``` 除了给 `exports` 对象增加成员,还可以使用 `return` 直接向外提供接口。 ```js define(function(require) { // 通过 return 直接提供接口 return { foo: 'bar', doSomething: function() {} }; }); ``` 如果 `return` 语句是模块中的唯一代码,还可简化为: ```js define({ foo: 'bar', doSomething: function() {} }); ``` 上面这种格式特别适合定义 `JSONP` 模块。 **特别注意**:下面这种写法是错误的! ```js define(function(require, exports) { // 错误用法!!! exports = { foo: 'bar', doSomething: function() {} }; }); ``` 正确的写法是用 `return` 或者给 `module.exports` 赋值: ```js define(function(require, exports, module) { // 正确写法 module.exports = { foo: 'bar', doSomething: function() {} }; }); ``` **提示**:`exports` 仅仅是 `module.exports` 的一个引用。在 `factory` 内部给 `exports` 重新赋值时,并不会改变 `module.exports` 的值。因此给 `exports` 赋值是无效的,不能用来更改模块接口。 ###module `Object` `module` 是一个对象,上面存储了与当前模块相关联的一些属性和方法。 ###module.id `String` 模块的唯一标识。 ###module.uri `String` 根据模块系统的路径解析规则得到的模块绝对路径。 ```js define(function(require, exports, module) { console.log(module.uri); // ==> http://example.com/path/to/this/file.js }); ``` ###module.dependencies `Array` `dependencies` 是一个数组,表示当前模块的依赖。 ###module.exports `Object` 当前模块对外提供的接口。 传给 `factory` 构造方法的 `exports` 参数是 `module.exports` 对象的一个引用。只通过 `exports` 参数来提供接口,有时无法满足开发者的所有需求。 比如当模块的接口是某个类的实例时,需要通过 `module.exports` 来实现: ```js define(function(require, exports, module) { // exports 是 module.exports 的一个引用 console.log(module.exports === exports); // true // 重新给 module.exports 赋值 module.exports = new SomeClass(); // exports 不再等于 module.exports console.log(module.exports === exports); // false }); ``` **注意**:对 module.exports 的赋值需要同步执行,不能放在回调函数里。下面这样是不行的: ```js // x.js define(function(require, exports, module) { // 错误用法 setTimeout(function() { module.exports = { a: "hello" }; }, 0); }); ``` 在 `y.js` 里有调用到上面的 `x.js`: ```js // y.js define(function(require, exports, module) { var x = require('./x'); // 无法立刻得到模块 x 的属性 a console.log(x.a); // undefined }); ``` ##小结 这就是 CMD 模块定义规范的所有内容。经常使用的 API 只有 `define`,`require`,`require.async`,`exports`,`module.exports` 这五个。其他 API 有个印象就好,在需要时再来查文档,不用刻意去记。 与 RequireJS 的
AMD
规范相比,CMD 规范尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。通过 CMD 规范书写的模块,可以很容易在 Node.js 中运行。
##模块标识 模块标识是一个字符串,用来标识模块。在 `require`、`require.async` 等函数中,第一个参数都是模块标识。 - 模块标识必须是一个有意义的字符串。 - 模块标识可以不包含文件后缀名,如 `.js`。 - 模块标识可以是相对路径,也可以是绝对路径。 注:GoJS 对模块标识的命名规范不做要求(如驼峰命名法、或使用连接符(`-`)、下划线(`_`)等),可根据项目习惯自行决定。 ###相对标识 相对标识以 `.` 开头,在模块环境(`factory` 构造方法)中时,始终相对于当前模块的地址来解析;在页面环境(`gojs.use` 或 `preload` 选项)中时,始终相对于当前页面的地址来解析。 ```js // 在 http://example.com/js/a.js 的 factory 中: require.resolve('./b'); // => http://example.com/js/b.js require.resolve('../c'); // => http://example.com/c.js ``` ```html ``` ###顶级标识 顶级标识不以点(`.`)或斜线(`/`)开始,它始终相对于 GoJS 的基础路径来解析。 ```js // 假设 base 路径是:http://example.com/assets/ require.resolve('js/lib/jquery'); // => http://example.com/assets/js/lib/jquery.js ``` ```html ``` 基础路径的默认值为 `go.js` 的访问路径目录: ``` 如果 go.js 的访问路径是: http://example.com/assets/go.js 则 base 路径为: http://example.com/assets/ ``` **小提示**:某些情况下,可能需要使用相对路径来做顶级标识,这时可以在前面加空格: ```html ``` 当然,更好的做法是更加恰当地配置基础路径: ```html ``` 可以通过 `gojs.config` 来手工 [配置基础路径](#config)。 ###普通路径 除了相对和顶级标识之外的标识都是普通路径。普通路径的解析规则,和 `script` 标签一样,会相对当前页面解析。 ```js // 假设当前页面是 http://example.com/path/to/index.html // 绝对路径是普通路径: require.resolve('http://cdn.com/js/a'); // => http://cdn.com/js/a.js // 根路径是普通路径: require.resolve('/js/b'); // => http://example.com/js/b.js ``` ###后缀名自动添加规则 GoJS 在解析模块标识时,除非路径中含有问号(`?`),或最后一个字符是井号(`#`),或模块标识中已有 `.js`、`.json`、`.css` 后缀,否者都会自动为其添加拓展名(`.js`)。如果不想自动添加扩展名,可以在末尾加上井号(`#`)。 ```js // ".js" 后缀可以省略: require.resolve('http://example.com/js/a'); require.resolve('http://example.com/js/a.js'); // => http://example.com/js/a.js // ".css" 后缀不可省略: require.resolve('http://example.com/css/a.css'); // => http://example.com/css/a.css // 当路径中有问号("?")时,不会自动添加后缀: require.resolve('http://example.com/js/a.json?callback=define'); // => http://example.com/js/a.json?callback=define // 当路径以井号("#")结尾时,不会自动添加后缀,且在解析时,会自动去掉井号: require.resolve('http://example.com/js/a.json#'); // => http://example.com/js/a.json ``` ###设计原则 模块标识设计的核心出发点是: 1. **关注度分离**。比如书写模块 `a.js` 时,如果需要引用 `b.js`,则只需要知道 `b.js` 相对 `a.js` 的相对路径即可,无需关注其他。 2. **尽量与浏览器的解析规则一致**。比如根路径、绝对路径,都是相对所在页面的 URL 进行解析。
##require 书写约定 由于 GoJS 通过正则匹配来自动识别和提取模块依赖,因此使用 GoJS 书写模块代码时,需要遵循一些简单规则。 ###1. 正确拼写 模块 `factory` 构造方法的第一个参数 必须 命名为 `require` 。 ```js // 错误! define(function(req) { // ... }); // 正确! define(function(require) { // ... }); ``` **注意**:在对模块代码进行压缩构建时,也请不要对 `require` 进行混淆,如在 **grunt-contrib-uglify** 中: ```js grunt.initConfig({ uglify: { options: { mangle: { except: ['require'] } }, my_target: { files: { // ... } } } }); ``` ###2. 不要修改 不要重命名 `require` 函数,或在任何作用域中给 `require` 重新赋值。 ```js // 错误 - 重命名 require! var req = require, mod = req("./mod"); // 错误 - 重定义 require! require = function() {}; // 错误 - 重定义 require 为函数参数! function F(require) {} // 错误 - 在内嵌作用域内重定义了 require! function F() { var require = function() {}; } ``` ###3. 使用直接量 `require` 的参数值 必须 是字符串直接量。 ```js // 错误! require(myModule); // 错误! require('my-' + 'module'); // 错误! require('MY-MODULE'.toLowerCase()); // 正确! require('my-module'); ``` 在书写模块代码时,必须遵循这些规则。其实只要把 `require` 看做是 **语法关键字** 就好啦。 ###动态依赖 有时会希望可以使用 require 来进行条件加载: ```js if (todayIsWeekend) { require('play'); } else { require('work'); } ``` 但请牢记,从静态分析的角度来看,这个模块同时依赖 play 和 work 两个模块,加载器会把这两个模块文件都下载下来。 这种情况下,推荐使用 `require.async` 来进行条件加载。
##GoJS 的详细配置 我们可以通过 `gojs.config(options)` 方法来灵活地进行配置: ```js gojs.config({ // 别名配置 alias: { 'jquery': 'http://example.com/path/to/lib/jquery-2.1.1.min.js' }, // 路径配置 paths: { 'deepdir': 'path/to/a/deep/dir' }, // 变量配置 vars: { 'locale': 'zh-cn' }, // 路由配置 routers: { 'foo-bar.min': ['foo', 'bar'] }, // 映射配置 map: [ '.js': '-debug.js' ] // 加载器配置 loaders: [ txt: function(uri, exports){ // ... // exports(exports); } ], // 预加载项 preload: [ 'jquery', './i18n/{locale}' ], // 调试模式 debug: false, // 模块文件的基础路径 base: 'path/to/base/', // 文件编码 charset: 'utf-8' }); ``` ###alias `Object` 当模块标识很长时,可以使用 `alias` 来简化。 ```js gojs.config({ alias: { 'jquery': 'http://example.com/path/to/lib/jquery-2.1.1.min.js' } }); ``` ```js define(require){ // 将会加载 http://example.com/path/to/lib/jquery-2.1.1.min.js var $ = require('jquery'); } ``` ###paths `Object` 当模块标识中的目录比较长时,可以使用 `paths` 来简化书写。 ```js gojs.config({ paths: { 'deepdir': 'path/to/a/deep/dir' } }); ``` ```js define(require){ // 将会加载 path/to/a/deep/dir/biz.js var biz = require('deepdir/biz.js'); } ``` ###vars `Object` 有些场景下,模块路径在运行时才能确定,这时可以使用 `vars` 来配置。 ```js gojs.config({ vars: { 'locale': 'zh-cn' } }); ``` ```js define(function(require) { // 加载的是 ./i18n/zh-cn.js var lang = require('./i18n/{locale}.js'); }); ``` ###routers `Object` 当项目发布上线时,常常需要通过合并压缩 JS 文件来减少 HTTP 连接数,这时可以通过 `routers` 来配置合并模块的分发。 ```js gojs.config({ map: { 'foo-bar.min': ['foo', 'bar'] } }); ``` ```js define(function(require) { // 加载的是 ./foo-bar.min.js var foo = require('./foo.js'); var bar = require('./bar.js'); }); ``` ###map `Array` 该配置可对模块路径进行映射修改,可用于路径转换、在线调试等。 ```js gojs.config({ map: [ // 这里的第一项可以是正则 ['.js', '-debug.js'] ] }); ``` ```js define(function(require) { var a = require('./a'); // => 加载的是 ./a-debug.js }); ``` ###loaders `Array` 当需要将一些非 JS 文件作为模块来加载和管理时,可以通过 loaders 来配置自定义的加载器。 ```js gojs.config({ loaders: [ // 这里的第一项可以是正则 ['.txt', function(uri, expose){ // some codes expose(exports); }] ] }); ``` ###preload `Array` GoJS 会在普通模块加载前,先加载好 preload 选项中指定的模块。 ```js // 在老版本浏览器中,提前加载好 ES5 和 json 模块 gojs.config({ // preload 中的空字符串会被忽略掉 preload: [ Function.prototype.bind ? '' : 'es5-safe', this.JSON ? '' : 'json2' ] }); // 当 use 被调用时,会先确保 preload 中的模块已经加载完毕 gojs.use('./main'); ``` **注意**:`preload` 配置不能放在模块文件里面: ```js gojs.config({ preload: 'a' }); define(function(require, exports) { // 此处执行时,不能保证模块 a 已经加载 }); ``` ###debug `Boolean` 当 `debug` 的值为 `true` 时,加载器不会删除动态插入的 script 标签,也不会根据路由配置进行模块加载和分发,这对项目构建前的调试非常有用。默认为 `false`。 ###base `String` 在解析顶级标识时,会相对 `base` 路径来解析,详情请参阅 [模块标识](#identifier)。 ###charset `String | Function` 获取模块文件时,`script` 或 `link` 标签的 charset 属性,默认是 `utf-8`。 `charset` 还可以是一个函数: ```js gojs.config({ charset: function(url){ if(url.indexOf('http://example.com/') === 0){ return 'gbk'; } return 'utf-8'; } }); ``` ##其它说明 ###配置合并 `go.config` 可以多次运行,每次运行时,GoJS 会对对配置选项中未存在的项进行合并,已存在的项进行覆盖。 ###配置文件 配置可以直接写在 html 页面上,也可以独立出来成为一个文件。 ```js // config.js gojs.config({ // ... }); ``` 独立成一个文件时,一般需要通过 `script` 标签在页面中同步引入,或者直接与 go.js 一起合并压缩。
##如何将现有模块改造为 CMD 规范 首先还是请大家先了解一下 [CMD 模块定义规范](#cmd),只要洞悉事物的定义和本质,一切问题可迎刃而解。 ###改造主流模块 这里指的是 jQuery、Moment、Backbone、underscore 等业界主流模块,这些模块一般都有对 AMD 和 CommonJS 的支持代码,例如 jQuery 源文件的最后几行: ```js if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; }); } ``` 我们只要将其对 AMD 规范的支持改造为 CMD 即可: ```js if ( typeof define === "function" && define.cmd ) { define(function() { return jQuery; }); } ``` ###改造普通模块 对于没有模块化兼容代码的文件,则需要手动引入依赖,以及暴露模块所提供的接口。 如: ```js var dialog = { init: function(options){ $('body').append('
'); // some codes }, show: function(){ // some codes } }; ``` 改为: ```js define(function(require, exports, module){ var $ = require('jquery'); var dialog = { init: function(options){ $('body').append('
'); // some codes }, show: function(){ // some codes } }; return dialog; }); ``` 或: ```js define(function(require, exports, module){ var $ = require('jquery'); exports.init = function(options){ $('body').append('
'); // some codes }; exports.show = function(){ // some codes } }); ``` ###改造 jQuery 插件 这也是一个经常遇到的问题,我们推荐以下的包装方式: ```js // jquery-plugin-abc define(function(require, exports, module) { var $ = require('$'); $.fn.abc = function() { // some codes }; }); ```
##go-css 有时候可能需要将 CSS 文件也作为模块依赖进行加载和管理,这时候可以使用 go-css 插件。 ```js gojs.config({ preload: ['go-css'] }); ``` 然后在模块中进行引用: ```js define(function(require){ require('login.css'); // some codes }); ```
##go-json 有时候可能需要将 JSON 文件也作为模块依赖进行加载和管理,这时候可以使用 go-json 插件。 ```js gojs.config({ preload: ['go-json'] }); ``` 然后在模块中进行引用: ```js define(function(require){ var data = require('data.json'); // some codes }); ```
##go-text 有时候可能需要将文本文件也作为模块依赖进行加载和管理,这时候可以使用 go-text 插件。 ```js gojs.config({ preload: ['go-text'] }); ``` 然后在模块中进行引用: ```js define(function(require){ var text = require('text.txt'); // some codes }); ```