你如何在与Babel的ES6中创作一个与CommonJS,AMD和浏览器兼容的模块?

Uma*_*ayr 5 javascript browser amd commonjs ecmascript-6

在正常的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';
})
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

在发现这一点时,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 |
Run Code Online (Sandbox Code Playgroud)

当我使用它module.exports而不是export但是可以严格地使用ES6这样做时它确实有效吗?

Cal*_*vin 1

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

当加载器规范完成后,可能会有一种方法将模块添加到注册表中,这就是您将 ES6 模块包含在 UMD 中的方式,在此之前,由于没有浏览器真正支持 ES6 模块,您唯一的目标是 AMD 和CommonJS,但您应该使用众多编译器或 trsnspilers 之一(例如 browserify 或 Babel)来为您完成此操作。