前言
前端本没有模块化,但是随着前端工程的发展,各个文件间的关系越来越多,为了能彼此方便地引用,慢慢地便有了模块化,这里的一个文件可以理解为一个模块。
打包就是为了让前端工程化,分离代码间的作用域。导出就是将本模块对外暴露,导入就是引入其他模块来使用其方法等。
ES6 Module是2015年引入的标准,让JS正式具备模块的概念。
ES6 Module的关键点是使用default
一个关键字,import
和export
两个保留字实现模块的导入导出。
1. ES6 Module的导出
导出方式有2种,一个是命名导出,一个是默认导出,二者可以混用。
1.1 命名导出
命名导出可以选择直接和变量声明写在一起,也可以选择最后统一导出,两种写法效果一样。
// 第一种写法
export const name = 'sam'
export const sex = 'man'
// 第二种写法
const name = 'sam'
const sex = 'man'
export { name, sex as sexual } // 在导入时变为 name 和 sexual,此时的sex作废
补充小知识: 用命名导出第二种写法导出时,还可以使用
as
关键字对导出的变量或方法等重命名,让其在导入时使用as
重命名过的名称。(其实导出也可以用它重命名,后面会提到)
1.2 默认导出
默认导出可以理解为==输出一个default变量==,所以无需再次声明变量,直接导出即可
export default {
name : 'sam',
sex : 'man'
}
// 也可以直接导出字符串
export default "This is sam !"
// 直接导出类
export default class() {...}
// 直接导出匿名函数
export default function() {...}
补充小知识: 不同于命名导出,默认导出只能有一个,或者说,每个模块只能用默认导出导出一次
2. ES6 Module的导入
因为有两种不同的导出方式,所以主要也就有两种导入方式。
2.1 命名导入的导出
命名导入的方式有三种,当变量较多可以使用整体导入的,结合as
还可以在导入时对变量重命名,以下代码展示了三种情况:
// 情况一:
// index.js,命名导出的两种写法都对应这种导入方式
import { name, sex } from './people.js'
// 情况二:
// 导入的所有变量作为属性存放在people对象中,减少了对当前作用域的影响
import * as people from './people.js'
// 情况三:
// 结合使用 as 关键字,还可以对导入的变量重命名
// 使用的时候就变成name和sexual
import { name, sex as sexual } from './people.js'
补充知识点: 使用大括号导入的变量需要和导出时的名称保持一致,其效果可以理解为,在当前作用域下声明了这些变量,而且还是只读不可修改的变量。
2.2 默认导入的导出
只有一种方式,直接在import
后面跟上变量名,这个变量名可以自定义,其指向被导入模块的默认导出
// people.js
export default {
name: 'sam',
sex: 'man'
}
// index.js
import handsomeMan from './people.js'
console.log(handsomeMane.name) // sam
2.3 混合导入
如果既有命名导出,又有默认导出,那么就要像下面这样了:
// people.js
export const name = 'sam'
export default {
petType: 'dog',
petName : 'eight'
}
// index.js
import pet, { name } from './people.js'
console.log(pet.petName ) // eight
console.log(name) // sam
补充知识点: 这里pet指向的是该模块的默认导出,name指向的是命名导出,而且这二者导入的顺序不能颠倒,否则会报错。
3. 复合写法
可以将导入的文件立即导出,可以用在比如将全部模块整合导入的入口文件里:
export { name, sex } from './people.js'
但是这种方式==只能用于命名导出==,默认导出只能分两行写:
import people from './people.js'
export default people
4.小结
ES6 Module的导入导出相对CommonJS而言会比较复杂,这里的小节需要好好梳理下:
导出:
- ES6 Module的导出方式有两种:命名导出和默认导出
- 命名导出有2种写法,一个是边声明变量边导出,另一个是先声明变量最后一起导出
- 命名导出的过程中可以使用
as
保留字对变量进行重命名,导入该模块后需要使用重命名后的变量名 - 默认导出可以理解为对外导出一个
default
变量,而且在一个模块中,只能导出一次
导入:
- 命名导出的导入使用大括号来导入,导入的变量需要和导出的变量名完全一致,而且导出后的变量是只读的
- 命名导出的导入也可以使用
as
保留字对变量进行重命名 - 命名导出的导入还可以使用整体导入的方式,
import * as xxx from './xxx.js'
,导入后的xxx
变量名字自定义,且还可以把导入的模块的变量作用域限定在xxx
下减少对当前作用域的影响 - 默认导出的导入用这种方式
import xxx from './xxx.js'
,其中xxx
同样也是可以自定义的 - 混合使用导入的方式需要先把默认导入的变量名放在前,命名导入的变量名放在后:
import React , { Component } from 'react'
- 混合导入写成一行只适用于命名导出,如果是默认导出只能先导入再导出
内容均为我个人阅读《Webpack实战:入门、进阶与调优》后的回忆总结,这是一本很不错的书,想深入了解webpack的同学可以去看看这本书