在 ES6 中,有两种方式来导出模块:export default
和 export
。其中,export default
可以默认导出一个值,而 export
可以导出一个命名值。而在使用 Babel 编译 ES6 时,这两种方式会有一些差异。本文将详细探讨这些差异,以及如何处理这些问题。
export default
export default
可以导出一个默认值。这个默认值可以是一个函数、一个对象、一个字符串等等。在导入时,可以不必使用花括号,直接使用被导出的值。示例如下:
// module.js export default function add(a, b) { return a + b; } // app.js import add from './module'; console.log(add(1, 2)); // 3
上面的代码中,module.js
中导出了一个默认的 add
函数。在 app.js
中,使用 import
导入了这个默认函数,并且直接使用了它。
在使用 Babel 编译 ES6 时,Babel 会将默认导出转化为 CommonJS 规范的导出方式。也就是说,Babel 会将 export default
转化为 exports.default
。如下面的代码所示:
// javascriptcn.com 代码示例 // module.js "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = add; function add(a, b) { return a + b; }
注意,Babel 会自动为模块添加 "use strict";
定义。
export
export
可以导出多个命名值。在导入时,必须使用花括号,并指定要导入的值的名称。示例如下:
// javascriptcn.com 代码示例 // module.js export const name = 'John'; export function greet() { console.log(`Hello, ${name}!`); } // app.js import { name, greet } from './module'; greet(); // Hello, John!
上面的代码中,module.js
中导出了一个 name
常量和一个 greet
函数。在 app.js
中,使用 import
导入了这两个值,并且使用了 greet
函数。
在使用 Babel 编译 ES6 时,Babel 会将命名导出转化为 CommonJS 规范的导出方式。也就是说,Babel 会将 export
转化为 exports.<name>
。如下面的代码所示:
// javascriptcn.com 代码示例 // module.js "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.name = void 0; exports.greet = greet; const name = 'John'; exports.name = name; function greet() { console.log(`Hello, ${name}!`); }
同样地,Babel 会自动为模块添加 "use strict";
定义。
解决 Babel 编译默认导出的问题
上面我们看到,在使用 Babel 编译模块时,export default
与 export
会被转化为不同的语法。这种转化虽然在大部分情况下不会出现问题,但在某些特殊情况下可能会导致代码无法正常运行。
举个例子,下面的代码会在命令行中输出 undefined
:
// javascriptcn.com 代码示例 // module.js export default { name: 'John', age: 30, sayHi() { console.log(`Hello, my name is ${this.name}. I am ${this.age} years old.`); } }; // app.js import person from './module'; person.sayHi();
这个问题的原因是,在 Babel 转化为 CommonJS 规范时,export default
会被转化为 exports.default
,因此在 app.js
中,需要使用 import person from './module'
来导入默认的值。但是,在 sayHi
方法中,因为 this
上下文指向了 person
,而不是 exports.default
,导致输出了 undefined
。
解决这个问题的方法很简单,只需要将 import
语句改为下面这样即可:
// app.js import * as person from './module'; person.default.sayHi();
上面的代码中,使用 import * as person from './module'
语句来导入模块,然后在调用 export default
时,使用 person.default
来访问默认值。这样就可以解决这个问题了。
总结
在 ES6 中,有两种导出模块的语法:export default
和 export
。这两种语法在 Babel 编译 ES6 时会被转化为不同的 CommonJS 规范语法。但是,对于某些特殊情况,会出现一些问题,需要注意。解决这些问题的方法也比较简单,只要注意到问题的本质,就可以轻松解决。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654c39e17d4982a6eb5d471b