Babel无法使用es6的`export Module from 'file'`语法

4

我正在使用ES6构建一个库,用于JavaScript与服务器进行通信。 服务器发送和接收基于JSON编码的特定类型的消息,通过WebSocket完成。

为了确保所有消息字段都被包含,且不会向服务器发送额外的字段,每个消息类型都有自己的类。每个消息在其自己的文件中定义,并具有以下结构:

export default class NameOfMessage extends BaseMessage {
    constructor(values) {
        // Here is code that checks values and sets them as properties
        // so that calling `JSON.stringify(obj)` will return the data
        // to be sent to the server.
    }
}

如果用户只需要特定文件中的一个或两个消息类型,他们可以写成import NameOfMessageType1 from 'package_name/messages/type1'import NameOfMessageType2 from 'package_name/messages/type2'等。
然而,如果用户需要许多消息类型,则包含它们变得繁琐。因此,我创建了一个额外的文件messages.js,该文件import所有消息文件,然后重新export它们。这样,用户可以使用import * as Message from 'package_name/messages'并将消息类型作为Message.Type1Message.Type2等访问。
根据我的阅读(包括http://www.2ality.com/2014/09/es6-modules-final.htmlhttps://hacks.mozilla.org/2015/08/es6-in-depth-modules/(标题为“聚合模块”)等其他来源),我应该能够使用以下内容作为messages.js文件的内容:
export Type1 from './messages/type1';
export Type2 from './messages/type2';
...

然而,当我在任何包含 import * as Messages from 'package_name/messages' 的文件上运行 Babel 时,我得不到任何结果(它根本就没有执行任何操作)。

当我将文件更改为以下内容时,一切都按预期工作:

import Type1 from './messages/type1';
import Type2 from './messages/type2';
export {Type1, Type2};
...

为什么另一种方法不起作用?

那么export Type1 from './messages/type1';真的默默失败了吗?它没有给出语法错误?这是Babel中的一个实验性功能,但如果没有启用,它应该会抛出一个错误。 - loganfsmyth
@loganfsmyth 是的,它默默地失败了。 - Moshe Katz
2个回答

4

仔细阅读官方规范后发现,只有两种使用 export ... from ... 的方式:

ExportDeclaration :
    export * FromClause ;
    export ExportClause FromClause ;
    ... // More export declarations

ExportClause :
    { }
    { ExportsList }
    { ExportsList , }

所有其他使用 export 的方式都不接受 FromClause。事实证明,from 唯一合法的用法是与 * 或花括号包含的导出列表相关联。没有办法在不显式引用的情况下使用 default

既然如此,以下文件可以正常工作:

export {default as Type1} from './messages/type1';
export {default as Type2} from './messages/type2';
...

1
应该提到 https://github.com/leebyron/ecmascript-more-export-from,因为这是在 Babel 的上下文中,但除此之外回答很好。 - JMM

0

我想补充一下,我遇到了非常类似的问题。我试图直接从另一个文件导出变量/模块,但返回值是undefined。不过,如果我将它分成两个步骤,先导入再重新导出,就可以正常运行了。问题的原因最终证明是我在进行某种循环导入。


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