前端模块化

模块化

前端模块化目前比较主流的四个规范分别是,CommonJs、AMD、CMD、ES规范。
CommonJS
由来:JavaScript官方定义的API只能构建基于浏览器的应用程序,CommonJS API定义很多普通应用程序(主要指非浏览器的应用)使用的API,从而填补了这个空白。它的终极目标是提供一个类似Python,Ruby和Java标准库。这样的话,开发者可以使用CommonJS API编写应用程序,然后这些应用可以运行在不同的JavaScript解释器和不同的主机环境中。node.js的模块系统,就是参照CommonJS规范实现的。
定义:即一个单独的文件就是一个模块,且该文件的作用域独立,当中的变量时无法被其他文件引用的,如果使用需要将其定义为global
模块标识: module,module对象就代表模块本身
输出模块:模块只有一个出口,即使用module.exports对象,将需要输出的内容放到该对象中。
加载模块:通过require加载。
该规范用于服务端,浏览器不支持该规范,因为浏览器缺少四个类似与Node.js环境的module,golbal,export,require变量。

// a.js
var data = "hello world";
function show () {
    console.log(data);
}
module.exports = {
    show: show
}

// b.js
var a = require('a.js');
a.show();// hello world

AMD(Asynchronous Module Definition),异步加载模块
由来:基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成,很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。require是同步的,对于服务器而言,所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间;对于浏览器而言,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于”假死”状态。因此,浏览器端的模块,不能采用”同步加载”(synchronous),只能采用”异步加载”(asynchronous)
使用:AMD是一套基于浏览器端模块化开发的规范,在进行页面开发时需要用到该规范的库函数,即:requireJS
定义模块:语法define([], function(){}),数组表示该模块所依赖的模块名称
加载模块:require([], function(){}),数组表示加载的模块,加载的模块按照顺序,作为回调函数的参数传入回调函数
AMD解决了多文件依赖关系处理的问题,被依赖的需要早一步被加载,但是加载js的时候页面会停止渲染,如果加载文件过多,页面失去响应的时间越长。

// 在html中引用requireJS
// a.js
define(
    [], // 这个数组表示模块依赖的模块名称
    function () {
        var a = 'hello world';
        function show () {
            console.log(a); 
        }
        return {show: show};
    }
);
// b.js
require(['a.js'], function (myModule) {
    // 加载之后module模块参数形式:myModule传入回调函数中,供使用
    myModule.show(); // hello world
});

CMD(Common Module Definition)通用模块定义
由来:为了解决AMD的问题出现的规范,大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范。CMD强调就近依赖,需要时再进行加载,所以执行顺序和书写顺序一致;这点与AMD不同,AMD是在使用模块之前将依赖模块全部加载完成,但由于网络等其他因素可能导致依赖模块下载先后顺序不一致这就导致了,执行顺序可能跟书写顺序不一致的情况。seajs也支持AMD规范的书写方式
模块定义:define(function (require, exports, module){})在函数里面通过require实时的加载模块

// 引入seajs
// a.js
define(
    function (require, exports, module) {
        var a = 'hello world';
        exports.show = function () {
            console.log(a); 
        }
        return exports;
    }
);
// b.js
seajs.use(['a.js'], function (myModule) {
    // 加载之后module模块参数形式:myModule传入回调函数中,供使用
    myModule.show(); // hello world
});

ES6规范
ES6模块化规范面向未来,为了统一前端模块化管理。

  • 优点
    1. 类似commonJS,语法更加简洁
    2. 类似AMD,直接支持异步加载和配置模块加载
    3. 结构可以做静态分析,静态检测
    4. 比commonJS更好的支持循环依赖
  • 语法概述
    1. 命名导出方式:每个模块可以有多个
    2. 定义导出方式:每个模块只有一个
// 命名导出方式
// a.js
export a = "hello world";
export function show () {
    console.log(a);
};
// b.js
import {a, show} from 'a.js';
console.log(a); // hello world
show(); // hello world
// 属性命名 import {a, show} as myModule form 'a.js' 使用时myModule.a...

// 定义式导出方式
// a.js
export default {show: function () {consoel.log('hello world')}} // 对象、函数、变量、类都可以
// b.js
import show form 'a.js';
show();

// 所有的导入方式
// 1. 定义式导出和命名式导出,以及相结合的导出
import default from 'module'; // 定义式
import { name1, name2 } from 'module'; // 命名式
import defualt, { name1, name2 } from 'module'; // 结合式
// 2. 导出重命名,即将模块导出后重命名为指定名字以供使用
import { name1 as rename1, name2 } from 'module';// 即将name1重命名为rename1供使用
// 3. 将整个模块一起导入,统一用指定属性名去调用模块内的内容
import * as moduleName from 'module';
// 4. 值加载不导出模块
import 'module';

// 所有的导出方式
// 1. 在模块内部使用export导出
export var v1 = 10; // 全局变量
export let v2 = 11; // 局部变量
export const v3 = 12; // 常量
export function f1() {} // 函数
export class MyClass {} // 类
// 2. 模块内部使用default导出整个表达式
export default 123;
export default function (x) { return x; }
export default x => x;
export default class {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
};
// 3. 将所有想导出的列出来放到文件最后一起导出
export { v1, v2, v3 };
// 4. 还可以别名导出
export { v1 as vv1, v2 as vv2, v3 };
// 5. 最后一种:重导出,即在一个模块里从另一个模块里导出内容
// module.js
export { v1, v2 } from 'otherModule';
// 别名
export { v1 as vv1, v2 } from 'otherModule';
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值