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

时间:2015-09-14 12:53:27

标签: javascript browser ecmascript-6 amd commonjs

在正常的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;

在发现这一点时,巴贝尔抛出了一个错误:

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吗?

2 个答案:

答案 0 :(得分:1)

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

当加载器规范完成后,可能会有一种方法将模块添加到注册表中,这将是你在UMD中包含ES6模块的方式,直到那时,因为没有浏览器实际上支持ES6模块你唯一的目标是AMD和CommonJS,但你应该使用浏览器或Babel等众多编译器或trsnspilers中的一个来为你做这件事。

答案 1 :(得分:0)

您不会拥有一个通用输出,但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": {}
        }
    }
}