什么是模块化?
将一个复杂的程序依据一定的规则(规范)封装成几个块(文件),并进行组合在一起,块的内部数据/实现是私有的,只是向外部暴露一些接口(方法)与外部其他模块通信
为什么要模块化?
降低复杂度和耦合度
模块化的好处?
- 避免命名冲突
- 更好的分离,按需加载
- 更高复用性
- 高可维护性
CommonJS规范
开始只是用于服务端,后来出现了专门用于浏览器端的AMD规范,CommonJS也兼容浏览器端
语法
暴露:1.module.exports = value
2.exports.xxx = value
引入:let xxx = require('xx/xx') //引入自己的模块使用相对路径,引入第三方模块写包名
> 使用require引入的本质是什么? --> 是exports对象
实现
服务端实现 --> Node.js,模块加载是同步的
浏览器端实现 --> 借助Browserify进行打包,安装Browserify需要 --save--dev
AMD规范
专门用于浏览器端,模块加载是异步的
语法
暴露:1.定义没有依赖的模块
define(function() {
return 模块
})
2.定义有依赖的模块
define(['module1','module2'],function(m1,m2){
return 模块
})
**注意:这两种情况都可以在参数中的第一位加一个自定义模块名字**
引入:require(['module1','module2'],function(m1,m2){
使用m1,m2
})
或者
requirejs(['module1','module2'],function(m1,m2){
使用m1,m2
})
具体使用
项目文件结构
|-js
|-libs
|-require.js
|-modules
|-module1.js
|-module2.js
|-main.js
|-index.html
1.定义无依赖模块module1
define(function(){
let name = 'module1'
function getName () {
return name
}
// 暴露模块
return {getName}
})
2.定义有依赖模块module2
define(['module1'],function(module1) {
let msg = 'module2'
function showMsg() {
console.log(msg,module1.getname())
}
})
3.在main中引入模块
(function(){
requirejs.config({
baseUrl: "js/", // 配置主路径,可以不配置,配置后出发点在根目录下
paths:{ // 如果没配置baseUrl,下面路径是main的相对路径
module1: "./modules/module1",
module2: "./modules.module2"
}
})
requirejs(['module2'],function(module2){
module2.showMsg()
})
})()
4.在index.html文件中引入入口文件
<script data-main="js/main.js" src="js/libs/require.js"></script>
CMD规范
专门用于浏览器端,模块异步加载,模块使用时才会加载执行
语法
暴露:1.定义没有依赖的模块
define(function(require,exports,module) {
let msg = 'module',
exports.module1 = msg // 第一种暴露方式
或者
module.exports = {msg} // 第二种暴露方式
})
2.定义有依赖的模块
define(function(require,exports,module) {
// 同步引入
var msg = require('xxx')
// 异步引入
require.async('./module1',function(m1){
})
exports.module1 = msg // 第一种暴露方式
或者
module.exports = {msg} // 第二种暴露方式
})
引入:define(function(require,exports,module){
var module1 = require('xxxx')
})
实现
依赖于sea.js
先引入sea.js
<script type'text/javascript' src='js/libs/sea.js'></script>
<script type'text/javascript'>
seajs.use('主模块路径')
</script>
具体使用
项目文件结构
|-js
|-libs
|-require.js
|-modules
|-module1.js
|-module2.js
|-main.js
|-index.html
1.定义无依赖模块module1
define(function(require,exports,module){
var msg = 'module1'
function foo() {
console.log(msg)
}
exports.foo = foo
})
2.定义有依赖模块module2
define(function(require,exports,module){
var module1 = require('./module1');
var name = 'module2'
function fun() {
console.log(name)
module1.foo()
}
exports.fun = fun
})
3.定义主模块main.js
define(function(require,exports,module){
var module2 = require('./module2')
module2.fun()
})
4.在index.html文件中引入入口文件
<script type'text/javascript' src='./js/libs/sea.js'></script>
<script type'text/javascript'>
seajs.use('./js/main.js')
</script>
ES6
依赖模块需要编译打包处理,不是所有浏览器都支持es6,所以需要babel将es6的语法转换成es5的语法, 转换后的es5语法用的require语法,浏览器不认识,所以还需要Browserify进行编译后浏览器才能识别
语法
暴露:1.分别暴露
export function foo() {
}
export function foo2() {
}
2.集中暴露
foo() => {
}
foo2() => {
}
export {foo,foo2}
3.默认暴露
export defult foo() => {
}
引入:import
对应上面的暴露方法,分别暴露和集中暴露
import {foo,foo2} from ‘xx/x/xx’
默认暴露的引入
import module from 'xx/xx'