主流模块化规范

2019-07-24  本文已影响0人  明明你也一样

在 es6 之前,没有能提出一套官方的规范,而从社区和框架推广程度而言,通行的 javascript 模块规范有两种:CommonJS 和 AMD,但是现在 es6 的 module 已经实现了,所以目前我们只需要了解CommonJSES6 modules 规范即可。

CommonJS规范

2009年,美国程序员Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。

这标志”Javascript模块化编程”正式诞生。前端的复杂程度有限,没有模块也是可以的,但是在服务器端,一定要有模块与操作系统和其他应用程序互动,否则根本没法编程。

node 编程中最重要的思想之一就是模块化,而正是这个思想,让 JavaScript 的大规模工程成为可能。模块化编程在 js 界流行,也是基于此,随后在浏览器端,require.js 和 sea.js 之类的工具包也出现了,可以说在对应规范下,require 统治了 ES6 之前的所有模块化编程,即使现在,在 ES6 module 被完全实现之前,还是这样。

在 CommonJS 中,暴露模块使用 module.exportsexports,很多人不明白暴露对象为什么会有两个,看下面的例子介绍区别

module.exports = value //value可以是任意类型的值
exports.xxx = value //你也可以通过export的属性向外暴露

无论是哪种方式,本质上向外暴露的都是exports对象,在CommonJS中,有一个全局性方法require(),用于加载模块。假定有一个数学模块math.js,就可以像下面这样加载。

let math = require('math') //如果是自定义模块,可以使用相对路径读取

然后,就可以调用模块提供的方法:

let math = require('math')
math.add(2,3) // 5

也正是由于 CommonJS 使用的require方式的推动,才有了后面的AMD、CMD 也采用的require方式来引用模块的风格。

ES6的模块化标准

ES6 标准发布后,module 成为标准,模块化标准的使用是以 export 指令导出接口,以 import 引入模块。(但是在我们一贯的 node 模块中,我们依然采用的是 CommonJS 规范,使用 require 引入模块,使用 module.exports 导出接口。)

ES6 中 export 和 import 一般的用法有两种

命名导出(Named exports)

就是每一个需要导出的数据类型都要有一个 name,统一引入一定要带有 {},即便只有一个需要导出的数据类型。这种写法清爽直观,是推荐的写法。

//------ lib.js ------
const sqrt = Math.sqrt;
function square(x) {
    return x * x;
}
function diag(x, y) {
    return sqrt(square(x) + square(y));
}

export {sqrt, square, diag}

//------ main.js ------
import { square, diag } from 'lib';             
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

或者把 export 直接加到声明前面

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js ------
import { square, diag } from 'lib';             
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

无论怎样导出,引入的时候都需要解构 {}。

默认导出(Default exports)

默认导出就不需要 name 了,但是一个js文件中只能有一个 export default。

//------ myFunc.js ------
export default function () { ... };

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();

其实这种导出方式可以看成是命名到处的变种,只不过把命名写成了default。
虽然 export default 只能有一个,但也可以导出多个方法。

export default {
  speak () {
    return 'moo'
  },
  eat () {
    return 'cow eats'
  },
  drink () {
    return 'cow drinks'
  }
}

引入与命名空间引入类似

import cow from './default-cow.js'
import goat from './default-goat.js'

cow.speak() // moo
goat.speak() // baa
上一篇 下一篇

猜你喜欢

热点阅读