如何阻止babel将'this'转换为'undefined'(并插入"use strict")

JR *_*hak 49 javascript amd commonjs node.js babeljs

编辑:这不是胖箭.这也是不是通过一个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
});
Run Code Online (Sandbox Code Playgroud)

但是,不管我什么(如使这个变量和传递),将其设置到未定义.

}(undefined, function() {
Run Code Online (Sandbox Code Playgroud)

它可能与Babel有什么关系,不知道将是什么,并将其转移,但是我还有其他方法吗?

更新:通过}((window || module || {}), function() {而不是似乎工作.我不确定这是最好的方法.

log*_*yth 62

对于Babel> = 7.x

ES6代码有两种处理模式:

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

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

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

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

overrides: [{
  test: "./vendor/something.umd.js",
  sourceType: "script",
}],
Run Code Online (Sandbox Code Playgroud)

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

对于Babel <7.x

ES6代码有两种处理模式:

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

使用Babel 6和babel-preset-es2015(或Babel 5)时,Babel默认假定它处理的文件是ES6模块.导致你麻烦的是,在ES6模块中,thisis undefined和文件都是严格的,而在"脚本"的情况下,this根据环境而不同,例如window在浏览器脚本或exportsCommonJS代码中.

如果您使用的是Babel,最简单的选择是在没有UMD包装器的情况下编写代码,然后使用Browserify之类的东西捆绑您的文件以自动为您添加UMD包装器.巴别塔还提供了一个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 } ]
  ]
}
Run Code Online (Sandbox Code Playgroud)

在你的Babel config(.babelrc)中用于babel-preset-es2015禁用模块处理.

  • 根据`babel-preset-es2015-script`的GitHub页面,该模块已被弃用,您应该使用它:`{"presets":[["es2015",{modules:false}]]} (5认同)
  • 然后使用[`babel-preset-es2015-script)](https://github.com/Collaborne/babel-preset-es2015-script)代替。“ babel-preset-es2015-script”已排除“ babel-plugin-transform-es2015-modules-commonjs”。 (2认同)