JavaScript——前端模块化开发 一、前端模块化规范 二、CommonJS 三、AMD(Asynchromous Module Definition) 异步模块定义 三、CMD(Common Module Definition)通用模块定义 四、原生模块化(ECMAScript模块化) 五、UMD(通用的模块定义)

二、CommonJS

  1、CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}

    1.1、require():用来引入外部模块;   

    1.2、exports:对象用于导出当前模块的方法或变量,唯一的导出口;

    1.3、module:对象就代表模块本身。

  2、NodeJS中使用CommonJS模块管理

    2.1、模块定义:根据commonJS规范,一个单独的文件是一个模块,每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非为global对象的属性。

      2.1.1、说明:模块只有一个出口,module.exports对象,我们需要把模块希望输出的内容放入该对象。

      2.1.2、common.js模块定义

let message="Hello CommonJS!";  
module.exports.message=message;  
module.exports.add=(m,n)=>console.log(m+n);

    2.2、模块依赖

      2.2.1、说明:加载模块用require方法,该方法读取一个文件并且执行,返回文件内部的module.exports对象。

      2.2.2、app.js 模块依赖

var common=require("./common");  //读取common.js文件
console.log(common.message);    //调用 
common.add(
100,200);

    2.3、测试运行

      安装好node.JS

      打开控制台,可以使用cmd命令

      JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

  3、在浏览器中使用CommonJS 模块管理

    3.1、由于浏览器不支持 CommonJS 格式。要想让浏览器用上这些模块,必须转换格式。

    例:创建index.html直接引用app.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <script src="js/app.js"></script>
</body>
</html>

    JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

    报错,提示require没有被定义

    3.2、方法:使用browserify,可以把nodejs的模块编译成浏览器可用的模块,解决上面提到的问题。本文将详细介绍Browserify实现Browserify是目前最常用的CommonJS格式转换的工具

      3.2.1、安装browserify

          使用下列命令安装browserify

npm install -g browserify

      3.2.2、转换

          使用下面的命令,就能将app.js转为浏览器可用的格式apps.js

browserify app.js > apps.js

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

生成apps.js文件

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

apps.js文件内容:

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
var common=require("./common");
console.log(common.message);
common.add(100,200);
},{"./common":2}],2:[function(require,module,exports){

let message="Hello CommonJS!";
module.exports.message=message;
module.exports.add=(m,n)=>console.log(m+n);
},{}]},{},[1]);
转换的apps.js文件内容

index.html引用apps.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <script src="js/apps.js"></script>
</body>
</html>

 运行结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

三、AMD(Asynchromous Module Definition) 异步模块定义

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出

AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。

适用AMD规范适用define方法定义模块。

1、定义模块:define(id,dependencies,factory)

——id 可选参数,用来定义模块的标识,如果没有提供该参数,脚本文件名(去掉拓展名)

——dependencies 是一个当前模块用来的模块名称数组

——factory 工厂方法,模块初始化要执行的函数或对象,如果为函数,它应该只被执行一次,如果是对象,此对象应该为模块的输出值。

2、加载模块:require([dependencies], function(){});

require()函数接受两个参数:

——第一个参数是一个数组,表示所依赖的模块;

——第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块

3、简单示例

模块定义:amd.js

//定义模块
define(function(){
    return{
        message:"Hello AMD!",
        add:function(n1,n2){
            return n1+n2;
        }
    }
})

模块依赖:app.js

require(['amd'],function(amd){
    console.log(amd.message);
    console.log(amd.add(100,200))
})

下载:require.js

官网:http://www.requirejs.cn

浏览器调用:index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<script src="AMD/require.js" data-main="AMD/app.js"></script>
</body>
</html>

结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

4、依赖第三方的库(AMD依赖jQuery)

导入jQuery

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

app.js代码

require(['amd','jquery'],function(amd){
    console.log(amd.message);
    console.log(amd.add(100,200));
    $("body").text("引用了第三方插件")
})

结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

三、CMD(Common Module Definition)通用模块定义

实例:

导入Seajs库

去官网下载最新的seajs文件,http://seajs.org/docs/#downloads

目录结构:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

定义模块:

cmd.js

define(function(require,exports,module){
    var obj={
        msg:"Hello SeaJS!",
        show:()=>console.log(obj.msg)
    }
    exports.cmd=obj;
})

 导入模块:

app.js

seajs.config({
    //Sea.js 的基础路径(修改这个就不是路径就不是相对于seajs文件了)
    base: './js/',
    //别名配置(用变量表示文件,解决路径层级过深和实现路径映射)
    alias: {
        'jquery': 'CMD/jquery'
    },
    //路径配置(用变量表示路径,解决路径层级过深的问题)
    paths: {
        'm': 'CMD/'
    }
})

seajs.use(["m/cmd.js",'jquery'],function(cmd,$){
    cmd.cmd.show();
    $("body").text("Hello CMD!");
})

 浏览器调用:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <script src="js/sea.js"></script>
    <script src="js/CMD/app.js"></script>
</body>
</html>

结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

四、原生模块化(ECMAScript模块化)

实例:

目录结构:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

定义模块:

es6.js

//定义模块
export let msg="Hello Es6(原生模块)";
export function add(n,m){
    return n+m;
}

导入模块:

es6.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


    <script type="module">
        //导入
        import {msg,add} from './es6/es6.js';
        console.log(add(100,200));
        console.log(msg);
    </script>
</body>
</html>

结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

五、UMD(通用的模块定义)

UMD(Universal Module Definition)通用的模块定义、UMD等于CommonJS加上AMD。UMD的工作其实就是做了一个判断:

  • - 先判断当前环境对NodeJs支持的模块是否存在,存在就用Node.js模块模式(exports)。
  • - 如果不支持,就判断是否支持AMD(define),存在就使用AMD方式加载。

CommonJs和AMD风格一样流行,似乎缺少一个统一的规范。所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了。

UMD示例

1、定义模块Utils.js

(function (global, factory) {
    if (typeof define === 'function' && (define.amd || define.cmd)) {
        // AMD规范. 注册一个匿名模块,兼容AMD与CMD
        define([], factory);
    } else if (typeof module === 'object' && module.exports) {
        //CommonJS规范,NodeJS运行环境
        module.exports = factory();
    } else {
        //浏览器全局对象注册
        global.UMD = factory();
    }
}(this, function () {
    var msg = "UMD!";
    //返回要导出的对象
    return {
        show: function () {
            console.log("Hello " + msg);
        }
    };
}));

2、在CommonJS规范下运行

useUtils.js

var utils=require('./Utils.js');
utils.show();

运行结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

在AMD规范下运行

app.js

require(['amd','jquery','../Utils.js'],function(amd,$,u){
    console.log(amd.message);
    console.log(amd.add(100,200));
    $("body").text("引用了第三方插件");
    u.show();
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script src="require.js" data-main="app.js"></script>
</body>
</html>

运行结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

3、在CMD规范下运行

app.js

seajs.use(["cmd.js",'jquery','../Utils.js'],function(cmd,$,u){
    cmd.cmd.show();
    $("body").text("Hello CMD!");
    u.show();
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script src="sea.js"></script>
    <script src="app.js"></script>
</body>
</html>

运行结果:

JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)

4、原生浏览器环境运行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


    <script src="../Utils.js"></script>
    <script>
        UMD.show();
    </script>
</body>
</html>

运行结果:

 JavaScript——前端模块化开发
一、前端模块化规范
二、CommonJS
三、AMD(Asynchromous Module Definition) 异步模块定义
三、CMD(Common Module Definition)通用模块定义
四、原生模块化(ECMAScript模块化)
五、UMD(通用的模块定义)