如何阻止babel转移'这个'未定义' (并插入"使用严格的")

时间:2016-01-24 07:58:49

标签: javascript node.js amd babeljs commonjs

编辑:这是不是胖箭。它也不是将传递给 IIFE 。这是一个与转录相关的问题。

所以我为我正在开发的一个小应用程序创建了一个简单的pub-sub。我在ES6中编写它以使用传播/休息并省去一些麻烦。我用npm和gulp进行设置来解决它,但它让我发疯了。

我把它变成了一个浏览器库,但意识到它可以在任何地方使用,所以我决定让它与Commonjs和AMD兼容。

这是我的代码的精简版本:

(function(root, factory) {
 if(typeof define === 'function' && define.amd) {
    define([], function() {
        return (root.simplePubSub = factory())
    });
  } else if(typeof module === 'object' && module.exports) {
    module.exports = (root.simplePubSub = factory())
  } else {
    root.simplePubSub = root.SPS = factory()
  }
}(this, function() {
 // return SimplePubSub
});

但无论我尝试什么(例如将变量并传递给它),它都会将其设置为 undefined

}(undefined, function() {

这可能与Babel有什么关系,不知道这个将会是什么,并将其转发出来但是我还能采取其他方法吗?

更新:传递}((window || module || {}), function() {代替似乎有效。我不确定这是最好的方法。

2 个答案:

答案 0 :(得分:59)

对于Babel> = 7.x

ES6代码有两种处理模式:

  • “script” - 通过<script>或任何其他标准ES5加载文件的方式加载文件时
  • “module” - 将文件作为ES6模块处理时

在Babel 7.x中,默认情况下将文件解析为“模块”。导致您遇到麻烦的是,在ES6模块中,thisundefined,而在"script"情况下,这取决于环境,例如window CommonJS代码中的浏览器脚本或exports。同样,"module"文件会自动严格,因此Babel会插入"use strict";

在Babel 7中,如果你想避免这种行为,你需要告诉Babel你的文件是什么类型的。最简单的选择是使用"sourceType"选项在您的Babel选项中设置sourceType: "unambiguous",这实际上告诉Babel根据import的存在来猜测类型(脚本与模块)和export陈述。主要的缺点是,在技术上没有使用不使用importexport的ES6模块,并且那些将被错误地视为脚本。另一方面,这真的不常见。

或者,您可以使用Babel 7的"overrides"选项将特定文件设置为脚本,例如

overrides: [{
  test: "./vendor/something.umd.js",
  sourceType: "script",
}],

这两种方法都允许Babel知道某些文件属于script类型,因此不应将this转换为undefined

对于Babel&lt; 7.x的

ES6代码有两种处理模式:

  • “script” - 通过<script>或任何其他标准ES5加载文件的方式加载文件时
  • “module” - 将文件作为ES6模块处理时

使用Babel 6和babel-preset-es2015(或Babel 5)时,Babel默认假定它处理的文件是ES6模块。导致您麻烦的是,在ES6模块中,thisundefined且文件都是严格的,而在“脚本”情况下,this根据环境而有所不同,例如浏览器脚本中的window或CommonJS代码中的exports

如果您使用的是Babel,最简单的选择是在没有UMD包装器的情况下编写代码,然后使用Browserify等文件捆绑您的文件,以便自动为您添加UMD包装器。 Babel还提供babel-plugin-transform-es2015-modules-umd。两者都是为了简化,所以如果你想要一个定制的UMD方法,它们可能不适合你。

或者,您需要在babel-preset-es2015中明确列出所有Babel插件,确保排除模块处理babel-plugin-transform-es2015-modules-commonjs插件。请注意,这也会停止自动添加use strict,因为这也是ES6规范的一部分,您可能需要添加babel-plugin-transform-strict-mode以自动保持代码严格。

babel-core@6.13预设开始就可以选择,所以你也可以

{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}
在您的Babel配置(.babelrc)中

使用babel-preset-es2015禁用模块处理。

答案 1 :(得分:2)

默认情况下,“es2015”预设将Babel输出包装在commonJs包装中。使用“babel-preset-es2015-script”(必须先npm install --save babel-preset-es2015-script)输出“script”(无模块)。这对我使用Babel进行包装的其他库造成了严重破坏。

预设:https://www.npmjs.com/package/babel-preset-es2015-script