黑马程序员技术交流社区

标题: CommonJS和ES6模块化 [打印本页]

作者: JoyZhang    时间: 2021-3-13 10:37
标题: CommonJS和ES6模块化
### CommonJ模块导出(require exports/moudle.exports)
+ 在模块的内部,module变量代表的就是当前模块,它的exports属性就是对外的接口,加载某个模块,加载的就是module.exports属性,这个属性指向一个空的**对象**
```
//module.exports指向的是一个对象,我们给对象增加属性即可。
//module.exports.num = 123;
//module.exports.age = 18;

//通过module.exports也可以导出一个值,但是多次导出会覆盖
module.exports = '123';
module.exports = "abc";
```
### CommonJ module.exports与exports的区别
+ `exports` 是 `module.exports` 的引用
+ 注意:给 `module.exports` 赋值会切断与 `exports` 之间的联系
        + 直接添加属性两者皆可
    + 赋值操作时,只能使用`module.exports`
```
console.log( module.exports === exports ) // ==> true

// 等价操作
module.exports.num = 123
exports.num = 123

// 赋值操作:不要使用 exports = {} 或者 exports = 100
module.exports = {}
```
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e9f20c5a89c64dc3a6045dd68469ea80~tplv-k3u1fbpfcp-watermark.image)

### ES6模块化(import export和export default)
#### export和export default的区别
1. export与export default均可用于导出常量、函数、文件、模块等
2. 你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用
3. 在一个文件或模块中,export、import可以有多个,export default仅有一个
4. 通过export方式导出,在导入时要加{ },export default则不需要
```
1.export
//a.js
export const str = "blablabla~";
export function log(sth) {
  return sth;
}
对应的导入方式:

//b.js
import { str, log } from 'a'; //也可以分开写两次,导入的时候带花括号

2.export default
//a.js
const str = "blablabla~";
export default str;
对应的导入方式:

//b.js
import str from 'a'; //导入的时候没有花括号
```
### 使用export default命令,为模块指定默认输出,这样就不需要知道所要加载模块的变量名

```
//a.js
let sex = "boy";
export default sex(sex不能加大括号)
//原本直接export sex外部是无法识别的,加上default就可以了.但是一个文件内最多只能有一个export default。
其实此处相当于为sex变量值"boy"起了一个系统默认的变量名default,自然default只能有一个值,所以一个文件内不能有多个export default。
```
```
// b.js
本质上,a.js文件的export default输出一个叫做default的变量,然后系统允许你为它取任意名字。所以可以为import的模块起任何变量名,且不需要用大括号包含
import any from "./a.js"
import any12 from "./a.js"
console.log(any,any12)   // boy,boy
```
### require,import区别?
> 另外,export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
```
// counter.js
exports.count = 0
setTimeout(function () {
  console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500)

// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
  console.log('read count after 1000ms in commonjs is', count)
}, 1000)

//es6.js
import {count} from './counter'
setTimeout(function () {
  console.log('read count after 1000ms in es6 is', count)
}, 1000)
```
```
结果
➜  test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
➜  test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1
```
> 这一点与 CommonJS 规范完全不同。CommonJS 模块输出的是值的缓存,不存在动态更新
### 需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
```
// 报错
export 1;

// 报错
var m = 1;
export m;


// 报错
function f() {}
export f;
```
上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。
```
// 写法一
export var m = 1;

// 写法二
var m = 1;
export {m};

// 写法三
var n = 1;
export {n as m};


// 正确
export function f() {};

// 正确
function f() {}
export {f};
```
> 可以这样理解 export 导出的值是import {m} from 'a.js' 如果直接按照第一种写法,import中如何接收






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2