CommonJS和ES6模块的导入导出

一、模块

模块 就是一个js 文件,它实现了一部分功能,并且隐藏自己的内部实现,同时提供部分接口供其他模块使用。

模块有两个核心要素:

  • 隐藏:模块内部实现

  • 暴露:供外部使用的接口

任何一个正常的模块化标准,都应该 默认隐藏模块中的所有实现,而通过一些语法 或api 调用 来暴露接口。

1.1 模块导出

  • 接口暴露的过程 就是模块的导出。

1.2 模块导入

  • 当需要使用一个模块是,使用的是该模块暴露的部分(导出的部分),隐藏的部分是永远无法使用的

  • 当通过某种语法 或 api 去使用一个模块时,这个过程就是模块导入

二、CommonJS 规范

2.1 commonJS 使用 exports 导出模块, require 导入模块

具体规范如下:

  • 如果 js 文件中存在 exports 或 require,该 js 文件 是一个模块。
  • 模块内的所有代码均为 隐藏代码,包括 全局变量、全局函数,这些全局的内容 均不应该对全局变量造成污染。
  • 如果一个模块需要暴露一些API给外部使用,需要通过exports 导出,exports 是一个空对象,你可以为该对象 添加任何需要导出的内容。
  • 如果一个模块需要导入其他模块,通过require 实现,require 是一个函数,传入模块的路径即可返回该模块导出的整个内容。
// index.js
const moduleA = require(./a.js’)// 导入模块 使用相对路径,并且以./ 或 ../ 开头
console.log(moduleA);  // {a: 'a'}// a.js
exports.a = 'a';

2.2 nodes 对 CommonJS 的实现

为了实现CommonJS 规范, nodejs 对模块 做出了以下处理

1、为了保证高效的执行,进加载必要的模块。nodejs 执行到require 函数时才会加载并执行。
2、为了隐藏模块中的代码,nodejs 执行模块时,会将模块中的所有放到一个函数中执行,以保证不污染全局变量。

(function(){
  // 模块中的代码
})()

3、为了保证顺利的导出模块内容,nodejs 做了以下处理

  • 在模块开始执行前,初始化一个值 module.exports = {}
  • module.exports是模块导出之
  • 为了方便开发者便捷的导出,nodejs 在初始化 完成module.exports后,有声明了一个变量exports = module.exports
(function(module){
   module.exports = {};
   var exports = module.exports
   // a.js 写入的代码
   exports.a = 'a';
 
   return module.exports;
})()// 所以 我们可以在 a.js 写法
   exports.a = 'a';
   exports.b = 'b';
// 或
   module.exports = {
      a: 'a',
      b: 'b'
   }
// or
   module.exports = 'a'   // 在index.js 打印 就是 a
   module.exports = 'b'// 注意 无效
   exports = ‘a’;
JavaScript 导出代码:
exports.a = 1
exports.b = 2
exports.c = 3

JavaScript 导入代码:
const { a, b, c } = require('./uppercase.js')
  • 为了避免反复加载同一个模块,nodejs 默认开启了模块缓存功能,如果已经加载过的模块,则会自动使用之前的导出结果。
// a.js
console.log('a 模块加载')
module.exports = 'a'// b.js b模块中依赖a模块
console.log('b 模块加载')
const moduleA = require('./a.js');
module.exports = 'b'// index.js 入口文件 依赖 a模块 和 b模块
const moduleA = require('./a.js');
const moduleB = require('./b.js');

打印结果为:

a 模块加载
b 模块加载

三、ES6规范

3.1 只需要在变量或函数前面加 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 使用方式1 ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

//------ main.js 使用方式2 ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

我们也可以直接导出一个列表,例如上面的lib.js可以改写成:

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

3.2 Default exports (导出一个默认 函数/类)

这种方式比较简单,一般用于一个类文件,或者功能比较单一的函数文件使用。一个模块中只能有一个export default默认输出。

export default与export的主要区别有2个:

  • 不需要知道导出的具体变量名
  • 导入(import)时不需要{}
//------ myFunc.js ------
export default function () { ... };

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

导出一个类

//------ MyClass.js ------
class MyClass{
  constructor() {}
}
export default MyClass;

//------ Main.js ------
import MyClass from 'MyClass';

注意这里默认导出不需要用{}。

export default 和 export 区别

1、export与export default均可用于导出常量、函数、文件、模块等
2、你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用
3、在一个文件或模块中,export、import可以有多个,export default仅有一个
4、通过export方式导出,在导入时要加{ },export default则不需要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值