JS模块化总结(commonJs规范、AMD规范、CMD规范、ES6)

986 阅读3分钟

什么是模块化?

将一个复杂的程序依据一定的规则(规范)封装成几个块(文件),并进行组合在一起,块的内部数据/实现是私有的,只是向外部暴露一些接口(方法)与外部其他模块通信

为什么要模块化?

降低复杂度和耦合度

模块化的好处?

  1. 避免命名冲突
  2. 更好的分离,按需加载
  3. 更高复用性
  4. 高可维护性

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'