在公司写代码的时候,开头都是下面两种写法的,这是什么意思啊?不明白是什么鬼,只能照葫芦画瓢,人家怎么写我也怎么写吧,后来的后来,原来这样写是原因的。最近有个表单提交的项目,刚好有机会可以研究下,记录下学习进展吧~~
写法一:
define(['Model', 'Store', 'Util'], function(model, store, util){
//……正常代码
})
写法二:
define(function(require, exports, module){
//……正常代码
})
其实,这些就是所谓的js模块化。第一种写法用的是RequireJS,第二种写法用的是SeaJS。
一、简介
1、AMD是RequireJS在推广过程中对模块化定义的规范化产出,在使用时需要用到它的库函数RequireJS。(RequireJS 官网 http://www.requirejs.cn/)
特点是:异步模块加载,依赖前置,提前执行。
define定义模块
define(['foo','food'], function(foo,food){ return //return一个函数,外面就可以调用了 })
2、CMD是SeaJS(made in China)在推广过程中对模块化定义的规范化产出。(sea.js 官网 http://seajs.org/docs/)
特点是:同步模块加载,依赖就近,延迟执行。
define(function(require, exports, module){//无需传名字,直接传回调函数,加载需要模块,exports可将当前所有函数都导出,module存储当前模块的一些对象。
require(['foo','bar'],function(foo,bar){}) //equire()直接引入,Require.async异步引入。
});
3、es6引入了模块(Module)的概念——摘自http://es6.ruanyifeng.com/#docs/module
ES6模块的的设计思想是尽量的静态化,使得编译时就可以确定模块的依赖关系,以及输入和输出的变量。而上述两种包括CommonJS都只能在运行时确定。以CommonJS为例
//CommonJS模块
let {start, exists, readFile} = require('fs');
//等同于
let _fs = require('fs'); //实质是在整体加载fs模块后,生成一个对象_fs,再从_fs这个对象上读取start、exists、readFile三个方法,这种加载称为"运行时加载",因为只有运行时才可得到这个对象
let start = _fs.start; //无法编译时静态优化
let exists = _fs.exists;
let readFile = _fs.readFile;
ES6模块不是对象而是通过export命令显式指定输出的代码,再通过import命令输入
import {start, exists, readFile} from 'fs'; //从fs模块加载3个方法,这种加载称为”编译时加载“或者静态加载,即ES6可在编译的时候就完成模块加载,比运行时加载方式效率高。ES6模块不是对象,因此无法引用它本身
运行时加载和编译时加载:(https://segmentfault.com/q/1010000007382252?_ea=1328120)
二、实战:
- SeaJS项目搭建
先搭一个SeaJS的遍历表单的项目。同时准备用ES6试下,也就顺便搭一个ES6的环境吧。
1、搭建ES6环境。其实主要做的就是将ES6转码成ES5,用的是gulp。前两天写好的,就不写了。http://www.cnblogs.com/xxchi/p/6386397.html
2、搭建Sea.js环境,这个是按照官网步骤来的。只是路径略调整了下。
先下了sea.js文件,放在modules路径下,然后下了jquery、react等放在了libs下,这次没用到react,先下好为后续做准备。其他文件的路径就看下图吧。
3、从form.html文件入手,写完html和css后,在form.html最后引入sea.js并编写相应配置。
在页面中加载模块:
<script src="./app/modules/sea.js"></script> //引入sea.js
<script type="text/javascript">
seajs.config({ //配置sea.js
base: "./app/",
alias: {
"jquery" : "libs/jquery.js"
}
})
seajs.use("./app/js/form"); //引入入口js文件
</script>
整个配置很简单,这样写好后,后面就可以在form中用sea.js的写法编写代码了。
form.js 模块中的代码
define((require, exports, module) => { //所有模块都通过define定义,可以看出seajs依赖就近,并不需要前置
const $ = require('jquery'); //通过require引入jquery依赖
const formatForm = {
el: document,
$el: $(document),
init(){
let tryJquery = $('[name="FamilyInfo"]');
console.log(tryJquery);
}
}
formatForm.init();
module.exports = formatForm; //通过module.exports提供整个接口。还可以通过exports对外提供接口 exports.doSomething = ...
})
这一切似乎都挺简单,但其中踩到了一个坑,搞了好半天,就是jquery引进来了,但是$选择符不能用,总是报错:form.js:7 Uncaught TypeError: $ is not a function(…)
不知道是个什么幺蛾子,后来网上查了好久才发现,原来jquery是需要先规范成cmd写法的,如下:
define(function (require, exports, module) { //jquery代码 })
终于完全可以了,这样一个sea.js环境就搭好了,现在就可以在form.js中书写自己的代码啦
- RequireJS项目搭建 javascript 模块化(二)——RequireJS