什么是模块化?
模块化是一种处理复杂系统分解为更好的可管理块的方式。简单来说就是解耦,简化开发,一个模块就是实现特定功能的文件,可以更方便的使用别人的代码,想要什么功能,就加载什么模块,模块开发需要遵从一定的规范。
CommonJS规范
CommonJS就是一个JavaScript模块化的规范,是用在服务器端的node的模块规范,前端的webpack也是相对CommonJS原生支持的。
特点:1、模块输出的是一个值的拷贝,模块是运行时加载,同步加载。 2、commonjs模块的顶层this只向当前模块。
有2个API:
- require:加载所要依赖的其他模块
- module.exports或者exports:对外暴漏的接口。 注意 (1).exports和module.exports的区别:exports是对module.exports的引用,不能直接给exports赋值,直接赋值无效,结果是一个空对象,module.exports可以直接赋值。示例:
module.exports = 123 //123
module.exports = function(){} //function
exports = 123 //{}
exports = function(){} //{}
(2).一个文件不能写多个module.exports,如果多写,对外暴漏的街口是最后一个。 (3).模块如果没有指定使用module.exports 或者 exports对外暴漏接口时,在其他文件就引用该模块,得到的是一个空对象{}。
AMD规范
AMD即Asynchronous Module Definition,中文名称是:“异步模块定义”的意思。它是一个在浏览器端模块化开发的规范,AMD是RequireJS在推广过程中对模块定义规范化产出,所以AMD规范的实现,就算require.js
特点:异步加载,不阻塞页面的加载,能并行加载多个模块,但不能按需加载,必须提前加载所需要的以来。
AMD的规范中两个重要的API:
define(id?,[]?,callback): //定义声明模块,参数id 模块id标识(可选),参数二是一个数组[]可选,依赖其他模块,最后是一个回调函数。 require([module],calback)://加载模块,参数一是一个数组,指定加载的模块,参数二回调函数,模块加载完成后执行。
还有一个配置API:
//首先,引入requiresJS
//requirejs.html
<!DOCTYPE html>
//Math.js
// 定义了AMD 模式的模块,并且引入了jquery 模块 (这里的jquery属于AMD模式)
define(['jquery'],function(_){
//define(['moudel1','moudel2'],callback())
//如果一个模块不依赖其他模块,直接使用define()函数写,
//如果一个模块依赖其他模块,define()第一个参数是数组
//回调函数的参数对应第一个参数数组的值,按顺序
console.log(_);//ƒ (a,b){return new m.fn.init(a,b)}
return {
add:function(x,y){
return x+y;
},
}
})
// index.js (主入口)
//配置好加载路径
require.config({
baseUrl:"../js",
paths:{
"index":"index", // 主入口文件 index:
"jquery":"jquery.min",// jquery 库,符合AMD模式(1.7 版本以上符合AMD)
"maths":"Math", //自定义AMD 模式的模块
}
})
//加载maths.js
require(["maths"],function(_math){
console.log( _math); // {add: ƒ }
})
CMD规范
CMD规范是由阿里的玉伯提出的,实现js库为sea.js,它和require非常类似,及一个js文件是一个模块,但是CMD加载的方式更加优秀,是通过按需加载的方式,而不是必须在模块开始加载所有的依赖。
seajs.config({
alias:{'jquery',:'http://xxxx'}
});
define(function(require,exports,module){
var $ = require('jquery')
})
seajs.use(['./a','./b'],function(a,b){
a.doSomething()
b.doSomething()
})
es6的module规范
ES6在语言标准层面上,实现了模块功能,而且非常简单,ES6到来,完全取代了CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。由Vue,Angular,React这些mvvm模式的框架发展,让前端的编程变的模块化,组件化。
特点:1、ES6模块中,顶层的this指向undefined,即不应该在顶层代码使用this。 2、自动采用严格模式“use strict”。遵循严格模式的要求。 3、ES6模块的设计思想是尽量的静态化,编译时加载,或者静态加载,编译时输出接口。 4、ES6模块的export和import命令可以出现在模块的任何位置,但是必须处于顶层。如果处于块级作用域,就会报错。 5、ES6模块输出的是值的引用
模块功能主要由两个命令构成:export和import 1、export:用于规定模块的对外接口 2、import:用于输入其他模块提供的功能
1、export命令
export.js
//
export function fn (x,y){
return x + y
}
export var m = 1
export class calss1{}
function v1(){}
function v2(){}
export {
v1 as streamv1,
v2 as streamv2
}
2、import命令
main.js
import { m , fn , streamv1} from './require.js'
import * as all from './export.js'
3、export default 命令 本质上,export default就是输出一个叫做 default 的 变量 或 方法
export default function foo (){
console.log('foo')
}
//或者写成
function foo(){
console.log('foo')
}
export default foo
// import
import myfoo form './export-default.js'
比较一下默认输出和正常输出
exports default function a1(){}
import a1 from ''
export function a2 (){}
import {a2} from ''
分析:上面两组代码 第一组是使用export default时,对应的import语句不需要使用大括号 第二组是不使用export default时 , 对应的import 语句需要使用大括号