【问题标题】:How do you author a module that is compatible with CommonJS, AMD and Browser in ES6 with Babel?您如何使用 Babel 在 ES6 中编写与 CommonJS、AMD 和浏览器兼容的模块?
【发布时间】:2015-09-14 12:53:26
【问题描述】:

在普通的 ES5 中,如果我想编写一个可以在服务器端(通过 CJS、AMD、RequireJS)或浏览器使用的包,我会这样做:

(function(name, definition)){
   if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
       module.exports = definition();
   } else if (typeof define === 'function' && typeof define.amd === 'object') {
       define(definition);
   } else {
       this[name] = definition();
   }
}('foo', function foo(){
       'use strict';

        return 'foo';
})

在 ES6 中编写包时,我是如何实现此功能的?

我尝试了什么:

if (typeof exports !== 'undefined' && typeof module !== 'undefined') export Foo;
else if (typeof define === 'function' && typeof define.amd === 'object') define(Foo);
else this['Foo'] = Foo;

编译时,Babel 向我抛出了一个错误:

SyntaxError: src/index.js: 'import' and 'export' may only appear at the top level (10:69)
   9 |
> 10 | if (typeof exports !== 'undefined' && typeof module !== 'undefined') export Foo;
     |                                                                      ^
  11 | else if (typeof define === 'function' && typeof define.amd === 'object') define(Foo);
  12 | else this['Foo'] = Foo;
  13 |

当我使用 module.exports 而不是 export 时它确实有效,但是否可以严格使用 ES6 来做到这一点?

【问题讨论】:

  • 这也叫UMD,通用模块定义。可能会对您的搜索有所帮助:-)
  • 您不需要自己编写此代码。你应该把 ES6 export 声明放在你的源代码中。 UMD 应该由转译器生成。
  • babeljs.io/docs/usage/modules ... 都在文档中。
  • @Bergi,确实如此。完全帮助我找到了我想要的东西。原来我只需要运行这个:babel --modules umd ...
  • @FelixKling,非常感谢。我没想到 babel 会开箱即用地提供这样的东西。

标签: javascript browser ecmascript-6 amd commonjs


【解决方案1】:

因此没有真正的方法将 ES6 模块包含在通用模块定义中,因为 ES6 模块严格来说每个文件一个,并且所有导入和导出语句都必须位于顶层。

加载器规范完成后,可能会有一种方法可以将模块添加到注册表中,这将是您在 UMD 中包含 ES6 模块的方式,在此之前,因为没有浏览器真正支持您唯一目标的 ES6 模块是 AMD 和 CommonJS,但你应该使用许多编译器或 trsnspiler 之一,如 browserify 或 Babel 来为你做这件事。

【讨论】:

  • “所有导入和导出语句必须在顶层”是什么意思,我的应用程序出现此错误,但不明白,我有一个名为 main.js 的文件,而其中的前两行是import语句,那么需要的“顶层”是什么!
  • import 和 export 语句不能在函数体、循环或 if/else 块中。好的import foo from 'bar';不行`如果(某事){从'bar'导入foo; } else { 从“baz”导入 foo; }
【解决方案2】:

您不会有一个通用输出,但StealJS 可以将您的 Babel 转译 ES6 项目导出到 CommonJS、AMD 和作为独立的。对于 CommonJS 和 AMD,您的原始模块结构将被保留,因此您仍然可以仅加载您真正需要的依赖项。

project exporting 指南对其进行了更详细的解释,但在使用 NPM 工作流程时,您的构建脚本是这样的(如果包含,它还将构建 CSS/LESS/SASS 和其他依赖项):

{
    dist: {
        system: {
            config: "package.json!npm"
        },
        outputs: {
            "+cjs": {},
            "+amd": {},
            "+global-js": {},
            "+global-css": {}
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-11
    • 2017-04-12
    • 2014-09-09
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多