javascript模块化详解2(AMD CMD ES6)

一、AMD规范

异步, 用于浏览器端,依赖require.js,先载入依赖再使用,异步可以同时进行

1、基本语法

暴露模块:

// 定义没有依赖的模块
define(function(){
    return 模块
})

// 定义有依赖的模块
define(['module1','module2'],function(m1,m2){
    return 模块
})

引入使用模块:

requirejs(['module1','module2'],function(m1,m2){
    使用m1/m2
})

代码演示:

// 无依赖模块 dataService.js
define(function(){
    let name = 'dataService.js'
    function getName() {
        return name
    }
    return {
        getName
    }
})
// 有依赖的模块 alerter.js
define(['dataService','jquery'],function(dataService,$){
    let msg = 'alerter.js'
    function showMsg() {
        $('body').css('color','red')
        console.log(msg, dataService.getName())
    }
    return {
        showMsg
    }
})
// 主模块 main.js
(function(){
    // 配置引用路径
    requirejs.config({
        baseUrl:'./',
        paths:{
            dataService:'./dataService',
            alerter:'./alerter',
            jquery:'./lib/jquery', // 第三方库
            angular:'./lib/angular'
        },
        // angular不支持amd暴露,因此需要配置,将angular对象暴露出来
        shim:{
            angular:{
                exports:'angular'
            }
        }
    })
    // 引用模块 无需再暴露用requirejs
    requirejs(['alerter'],function(alerter){
        alerter.showMsg()
    })
})();

注意jquery插件最后,自定义了模块,因此模块名称必须是jquery
javascript模块化详解2(AMD CMD ES6)_第1张图片



    

二、CMD规范

用于浏览器端,也是异步,只不过是不会提前载入依赖,而是用到时才去载入,sea.js

1、基本语法

暴露模块:

// 定义没有依赖的模块
define(function(require,exports,module){
    exports.xxx=value;
    module.exports = value;
})

// 定义有依赖的模块
define(function(require,exports,module){
    // 同步引入依赖
    var module2 = require('./module2')
    // 异步引入依赖
    require.async('./module3',function(m3){
        ...
    })
    exports.xxx=value;
})

引入使用模块:不需要暴露,因此只有require参数

define(function(require){
    var module1 = require('./module1');
    ...
})

代码演示:

// 无依赖模块 dataService.js
define(function(require,exports,module){
    let name = 'dataService.js'
    function getName() {
        return name
    }
    module.exports = {
        getName
    }
})
// 有依赖的模块 alerter.js
define(function(require,exports,module){
    let msg = 'alerter.js'
    // 同步
    var dataService1 = require('./dataService');
    console.log(dataService1.getName());
    // 异步
    require.async('./dataService',function(m){
        console.log(m.getName());
    })
    function showMsg() {
        console.log(msg)
    }
    module.exports = showMsg
})
// 主模块 main.js
(function(){
    // 引用模块 无需再暴露用requirejs
    define(function(require){
        var alerter=require('./alerter);
        alerter();
    })
})();

// 打印结果
dataService.js
alerter.js
dataService.js // 异步


    
    

三、ES6 module 规范

1、基本语法

引用和暴露:

import {} from ''
export default ...
export ...

es6需要转化成es5需要babel, 但是babel转化完以后,暴露和引用被转化为commonjs中的require, 因此还需要再用browserify继续转换

2、一些疑问

为什么es6 import可以引入commonjs模块的module.exports

es6 的导出模块写法有:

export default 123;
export const a = 123;

const b = 3;
const c = 4;

export { b, c };

babel 会将这些统统转换成 commonjs 的 exports。

exports.default = 123;
exports.a = 123;
exports.b = 3;
exports.c = 4;
exports.__esModule = true;

也就是说, es6和commonjs可以通过打包工具相互转换,例如webpack,更多详细请参阅以下:

import、require、export、module.exports 混合使用详解

你可能感兴趣的:(webpack,node.js,html,模块化,javascript)