乐趣区

JavaScript中AMD和ES6模块的导入导出对比

我们前端在开发过程中经常会遇到导入导出功能,在导入时,有时候是 require,有时候是 import 在导出时,有时候是 exports,module.exports,有时候是 export,export default 今天我们对这些内容进行简单的介绍
import,export,export default
import,export,export default 属于 ES6 规范
import
import 是在编译过程中执行也就是说是在代码执行前执行,比如说,import 后面的路径写错了,在运行代码前就会抛错,在编写代码时,import 不是一定要写在 js 的最前面 import 命令具有提升效果,会提升到整个模块的头部,首先执行。(是在编译阶段执行的)import 是静态执行的因为 import 是静态执行的,不能使用表达式和变量,即在运行时才能拿到结果的语法结构比如,不能再 if 和 else 中使用 import 再比如,import 后的 from 的路径,可以是相对路径,可以是绝对路径,但是不能是根据变量得来的路径
//import 路径不可以为变量
var url = ‘./output’
import {
a,
b
} from url// 这么写会报错
//——————
//import 的引入与否不能和代码逻辑向关联
let status= true
if(status){
import {
a,
b
} from url// 这么写会报错
}
import 可以使用 as 进行重命名 import 的有很多种导入方式,
import foo from ‘./output’
import {b as B} from ‘./output’
import * as OBj from ‘./output’
import {a} from ‘./output’
import {b as BB} from ‘./output’
import c, {d} from ‘./output’
导入的方式和导出有些关联,我们在下面说导出的时候,对以上这些导入方式进行逐一介绍
exoprt 和 export default
将 exoprt 和 export default 放在一起,因为它们关联性很大简单说:export 是导出,export default 是默认导出一个模块可以有多个 export,但是只能有一个 export default,export default 可以和多个 export 共存 export default 为默认导出,导出的是用 {} 包裹的一个对象,以键值对的形式存在导出的方式不同,导入的方式也就不同,所以建议同一个项目下使用同一的导入导出方式,方便开发 export default 解构以后就是 export 通过两个直观的 demo 看下 export 和 export default 的区别先看一段代码(export)output.js
const a = ‘valueA1’
export {a}
input.js
import {a} from ‘./output.js’// 此处的 import {a}和 export {a},两个 a 是一一对应关系
console.log(a)//=>valueA1
留意上面的代码其中 export {a}导出的 a,和 import {a}导入的 a 是同一个 a 再看一段代码(export default)
const a = ‘valueA1’
export default{a}
input.js
import a from ‘./output.js’// 此处的 a 和 export default{a},不是一个 a,
console.log(a)//=>{a: ‘valueA1’}
看下 export default 的栗子中的 input.js,我们稍作改动
import abc from ‘./output.js’// 此处的 a 和 export default{a},不是一个 a,
console.log(abc)//=>{a: ‘valueA1’}
我们做了些改动,但是输出没有变化,import 导入的是 export default 下的对象,叫什么名字都可以,因为只会存在一个 export default
exoprt 和 export default 混合使用
exoprt 和 export default 在同一个模块中同时使用,是支持的,虽然我们一般不会这么做看一个栗子 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
const d = ‘valueD1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export {b}
export default {b,d,foo}
input.js
import obj, {a,b} from ‘./output’
console.log(a); //=>valueA1
console.log(b); //=>valueB1
console.log(obj); //=>{b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] }
as 重命名
通过 exoprt 和 export default 导出的在 import 引入时都支持通过 as 进行重命名看个栗子还是上面的那个 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
const d = ‘valueD1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export {b}
export default {b,d,foo}
input.js
import {a as A} from ‘./output’
import {* as A} from ‘./output’// 这是不支持的
import * as obj from ‘./output’
console.log(A); //=>valueA1
console.log(obj); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] },b: ‘valueB1’ }
as 后面的变量是你要在 input.js 中使用的重点看这一部分
import {* as A} from ‘./output’// 这是不支持的
import * as obj from ‘./output’
console.log(obj); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] },b: ‘valueB1’ }
代表了所有,包括了 export 和 export default 导出的
我们之前说 import{}和 export{}, 是一一对应关系,所以在 export 导出的,在 import{}不支持使用 * 关于 import,export,export default 先介绍到这里,我们继续
require,exports,module.exports(记得后面的 s)
这是 AMD 规范
require
require 是运行时调用,所以 require 理论上可以运用在代码的任何地方
require 支持动态引入
例如,这样是支持的
let flag = true
if (flag) {
const a = require(‘./output.js’)
console.log(a); // 支持
}
require 路径支持变量
let flag = true
let url = ‘./output.js’
if (flag) {
const a = require(url)
console.log(a); // 支持
}
通过 require 引入,是一个赋值的过程
exports 与 module.exports
根据 AMD 规范每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
为了方便,Node 为每个模块提供一个 exports 变量,指向 module.exports。这等同在每个模块头部,有一行这样的命令。
const exports = module.exports;
所以说以下两种写法等价
exports.a =’valueA1′
module.exports.a=’valueA1′
前面说在每个模块提供一个 exports 变量,指向 module.exports。所以不能直接给 exports 赋值,赋值会覆盖
const exports = module.exports;
直接给 exports 赋值会切断 exports 和 module.exports 的关联关系看一个栗子 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
module.exports = {c}
exports.b = b// 当直接给 module.exports 时,exports 会失效
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{c: ‘valueC1’, a: ‘valueA1’}
继续看代码 output.js
// 部分省略
exports.b = b// 这样可以生效
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{b: ‘valueB1’, a: ‘valueA1’}
再看一段代码 output.js
// 部分省略
module.exports = {c}
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{c: ‘valueC1’, a: ‘valueA1’}
当直接给 module.exports 时,exports 会失效
交叉使用
在 ES6 中 exprod default 导出的是一个对象在 AMD 中 exports 和 module.exports 导出的也都是一个对象所以如果你手中的项目代码支持两种规范,那么事可以交叉使用的(当然不建议这么去做)通过 export 导出的不一定是一个对象
demo1
output.js
// 部分省略
module.exports = {c}
module.exports.a = a
inputj.s
import obj from ‘./output’
import {a} from ‘./output’
console.log(a);//=>valueA1
console.log(obj);//=>{c: ‘valueC1’, a: ‘valueA1’}
demo2
output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export default {b,c,foo}
export {b}
input.js
const a = require(‘./output.js’)
console.log(a); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, c: ‘valueC1’, foo: [Function: foo] }, b: ‘valueB1’ }
总结

require,exports,module.export 属于 AMD 规范,import,export,export default 属于 ES6 规范
require 支持动态导入,动态匹配路径,import 对这两者都不支持
require 是运行时调用,import 是编译时调用
require 是赋值过程,import 是解构过程
对于 export 和 export default 不同的使用方式,import 就要采取不同的引用方式,主要区别在于是否存在{},export 导出的,import 导入需要{}, 导入和导出一一对应,export default 默认导出的,import 导入不需要{}
exports 是 module.export 一种简写形式,不能直接给 exports 赋值
当直接给 module.export 赋值时,exports 会失效

更多前端资源请关注微信公众号“前端陌上寒”
原文链接
参考链接关于 import 与 require 的区别 JS 中的 require 和 import 区别 module.exports 和 exports 和 export 和 export default 的区别,import 和 require 的区别

退出移动版