当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JavaScript模块化教程

JavaScript模块化教程

2019年01月21日  | 移动技术网IT编程  | 我要评论

js是一种脚本语言,与php类似。但是如今php不再仅仅构建一个简单的web,它也在向java看齐,也能够支撑起一个庞大的web系统。国外非常有名的脸书网就是一个典型的例子。一门语言,要构建出庞大复杂的系统的基础之一就是语言文件的相互引用。毕竟一个单文件直接实现一个庞大复杂的系统是十分吃力的。

后端模块化

commonjs

在互联网早期,javascript 一直在前端发光发热,但在后端基本上没有什么建树。并且 javascript 官方的一些规范也仅仅只是对于前端做了很多要求,没有考虑到后端,这样导致 javascript 一直寄生于中。但是 javascript 社区不满足仅仅让 javascript 这门语言只存在于浏览器里,他们希望能够在任何地方都能运行 javascript。于是,commonjs 应运而生,它是社区制定的一份 javascript 规范。

commonjs 涵盖的内容

模块 二进制 buffer 字符集编码 i/o流 进程环境 文件系统 套接字 单元测试 web服务器网关接口 包管理 …

commonjs 的模块规范

commonjs 的模块规范很简单,主要包含三部分,模块定义,模块标识以及模块引用。

模块引用

示例如下:

var math = require('math');

主要使用了require()方法,他接受一个参数,模块标识。

模块定义

示例如下:

exports.add = function (a, b) {
  return a + b;
};

主要使用了exports对象,只要将方法挂载在exports对象上作为属性即可定义导出的方式。

下面给出一个模块引入及使用的例子:

var math = require('math');
exports.getall = function (x, y) {
  return math.add(x, y);
};

模块标识

模块标识就是传递给require()方法的参数,他要求是符合小驼峰命名的字符串,或者以.,..开头的相对路径,或者绝对路径。他可以没有文件后缀名js。

commonjs 与 node.js

commonjs 只是定义了一份模块的规范,而 node.js 根据这份规范实现了模块机制。这好比接口和实现类,一个给出了接口,另一个真正实现了接口,但是实现可能有很多种不同的方式。

前端模块化

说完后端模块化,我们再来聊一聊前端模块化。

如何去实现前端的模块化呢?

有人可能会说,这还不简单,既然后端模块化已经可以良好的工作了,那我们直接照搬到前端不就可以了嘛!

理论上是的,但是现实中却遇到了一个大问题。我们要知道在后端,文件的 i/o 很快,因为我们直接在服务器的硬盘上读写文件即可。但是在前端可不是这个样子,所有文件的 i/o 都是要经过 http 请求去完成的,网络延时是个大问题。

如果一个页面空白3秒钟以上,那么用户肯定会不爽,一般他们会刷新,如果刷新页面几次都不能看到页面,那可能会直接关掉页面,甚至以后都不会再次访问你的站点。

所以,在前端我们实现模块化不能仿照后端那样,进行同步加载,最好的方式就是异步加载。而在前端比较火的两个异步加载规范就是 amd 和 cmd。

amd

全称:asynchronous module definition,异步模块定义 amd 是 requirejs 在过程中对模块定义的规范化产出

在 amd 规范中,一个模块就是一个文件。该规范的核心就是define()函数,define() 是一个全局函数,用来定义模块。

define(id, dependencies, factory);

下面给出一个示例:

define("types/manager", ["types/employee"], function (employee) {
    function manager () {
        this.reports = [];
    }
    //开始执行
    manager.prototype = new employee();
    //返回经理构造函数可以由其他模块的应用。
    return manager;
}
);

cmd

全称:common module definition,公共模块加载 cmd 是 seajs 在推广过程中对模块定义的规范化产出

在 cmd 规范中,一个模块就是一个文件。该规范的核心就是define()函数,define() 是一个全局函数,用来定义模块。

define(function(require, exports, module) {

  // 模块代码

});

下面给出一个示例:

define(function(require, exports, module) {
    // 通过 require 引入依赖 注意 .js 可以省略
    var $ = require('jquery');
    // 你也可以引入自己的函数依赖
    var spinning = require('./yourfunction');
    var util = {};
    util.sayhello = function(){
        return 'seajs向你问好';
    }
    // 通过 exports 对外提供接口
    module.exports = util;
});

amd 和 cmd 的区别

对于依赖的模块,amd 是提前执行,cmd 是延迟执行。不过 requirejs 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。cmd 推崇 as lazy as possible。 cmd 推崇依赖就近,amd 推崇依赖前置。
//  cmd
define(function(require, exports, module) {
    var a = require('./a')
    a.dosomething()  
    // 此处略去 100 行  
    var b = require('./b') 
    // 依赖可以就近书写 
    b.dosomething() 
    // ... 
})
// amd 默认推荐的是
define(['./a', './b'], function(a, b) { 
    // 依赖必须一开始就写好  
    a.dosomething()  
    // 此处略去 100 行 
    b.dosomething()   
    ...
})

es6

es6 这个词的原意,就是指 javascript 语言的下一个版本,他由国际标准化组织ecma提出。es6 模块是编译时加载,而commonjs 模块是运行时加载。

es6 模块功能主要由两个命令构成:export和import。

export命令用于规定模块的对外接口 import命令用于输入其他模块提供的功能

export命令

输出变量

export var firstname = 'michael';

输出函数

export function multiply(x, y) {
  return x * y;
};

使用大括号输出的一组变量

var firstname = 'michael';
var lastname = 'jackson';
var year = 1958;
function f() {}
export {firstname, lastname, year, f};
使用as关键字重命名
function v1() { ... }
function v2() { ... }
export {
  v1 as streamv1,
  v2 as streamv2,
  v2 as streamlatestversion
};

import 命令

import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。

引入变量

import {firstname, lastname, year} from './profile';
function setname(element) {
  element.textcontent = firstname + ' ' + lastname;
}

使用as关键字重命名

import { lastname as surname } from './profile';

执行加载模块

import 'lodash';

整体加载

import * as circle from './circle';
console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));

export default 命令

export default function () {
  console.log('foo');
}

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

import customname from './export-default';
customname(); 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网