如何拆解ES6模块的联合导出

5

我在导出场景中遇到了一些小问题,不确定原因。我可能需要一个Babel插件来解决它,但不确定是哪个。

// a.js
export function fromA() {}

// b.js
export function fromB() {}

// index.js
import * as a from './a'
import * as b from './b'

export default { ...a, ...b}

// test.js
import all from './index'  
const { fromA } = all // Works

import { fromA } from './index'  // Does not work. Why?

我正在使用Babel。这是我的rc配置文件:

{
  "plugins":  [
    "transform-object-rest-spread", 
    "transform-class-properties", 
    "transform-export-extensions", 
    "transform-decorators-legacy"
   ], 
  "presets":  ["latest", "react"]
}

在test.js中,我似乎应该能够像往常一样在import语句中解构,但实际上不能。如果在index.js中单独导出函数,则可以正常工作。例如:

import { fromA } from './a'
import { fromB } from './b'
export default { fromA, fromB }

然而,我希望避免这种情况。


1
虽然导入语法看起来像解构,但实际上并不是。你正在从 index.js 导出一个对象,因此只能将其作为整个对象导入。 - Leonid Beschastny
唯一的例外是当您导入非ES6模块时。由于CommonJS模块每个模块只能导出一个变量,因此Babel会退回到解构导入它们。 - Leonid Beschastny
1
这个。另外,import { fromA } from './index'不起作用,因为没有fromA导出,只有默认导出。而且使用export { ...a, ...b}无法实现fromA导出,因为导入和导出是模仿JS对象语法并且应该是静态的。 - Estus Flask
1个回答

13

虽然导入语法看起来像解构,但实际上不是。

当你导出一个命名变量时,只能将其作为命名变量导入。当你导出默认变量时,只能将其作为默认变量导入。

例如:

// a.js
export const foo = 1
export const bar = 2
export default { bar: 42, baz: 33 }
import { foo } from './a'
// foo = 1
import { bar } from './a'
// bar = 2
import a from './a'
// a = { bar: 42, baz: 33 }

唯一的例外是当您导入一个非ES6模块时。由于commonjs模块每个模块只能导出一个变量,因此babel会退回到解构导入它们。

所以,由于您从index.js仅导出单个对象,因此只能将其作为整个对象导入。


可能您正在寻找的是一个export * from语句:

export * from './a'
export * from './b'

它将重新导出两个模块的所有命名导出项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接