如何阻止babel将"this"转换为"undefined"(并插入"use strict") [英] How to stop babel from transpiling 'this' to 'undefined' (and inserting "use strict")

查看:460
本文介绍了如何阻止babel将"this"转换为"undefined"(并插入"use strict")的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:这不是关于粗箭头.这也不是要将 this 传递给 IIFE .这是一个与翻译相关的问题.

EDIT: This is not about fat arrows. It's also not about passing this to an IIFE. It's a transpiler-related question.

因此,我为正在使用的小应用程序创建了一个简单的pub-sub.我在ES6中编写了它,以使用传播/休息并节省一些麻烦.我使用npm和gulp对其进行了设置,以进行翻译,但这使我发疯.

So I've created a simple pub-sub for a little app I'm working on. I wrote it in ES6 to use spread/rest and save some headaches. I set it up with npm and gulp to transpile it but it's driving me crazy.

我使它成为浏览器库,但意识到它可以在任何地方使用,因此我决定使其与Commonjs和AMD兼容.

I made it a browser library but realized it could be used anywhere so I decided to make it Commonjs and AMD compatible.

这是我的代码的精简版:

Here's a trimmed down version of my code:

(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
});

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

But no matter what I try (such as making this a variable and passing it) it sets it to undefined.

}(undefined, function() {

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

It probably has something to do with Babel not knowing what this will be and transpiling it away but is there any other approach I can take?

更新:似乎可以传递}((window || module || {}), function() {而不是 this .我不确定这是否是最好的方法.

UPDATE: Passing }((window || module || {}), function() { instead of this seems to work. I'm not sure this is the best approach though.

推荐答案

对于Babel> = 7.x

ES6代码具有两种处理模式:

For Babel >= 7.x

ES6 code has two processing modes:

  • 脚本"-通过<script>或任何其他标准ES5加载文件的方式加载文件时
  • 模块"-将文件作为ES6模块处理时
  • "script" - When you load a file via a <script>, or any other standard ES5 way of loading a file
  • "module" - When a file is processed as an ES6 module

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

In Babel 7.x, files are parsed as "module" by default. The thing that is causing you trouble is that in an ES6 module, this is undefined, whereas in the "script" case, this varies depending on the environment, like window in a browser script or exports in CommonJS code. Similarly, "module" files are automatically strict, so Babel will insert "use strict";.

在Babel 7中,如果要避免这种行为,您需要告诉Babel文件是什么类型.最简单的选择是使用 "sourceType" 选项在您的计算机中设置sourceType: "unambiguous" Babel选项,本质上告诉Babel基于importexport语句的存在来猜测类型(脚本与模块).主要的缺点是,使用不使用importexport的ES6模块在技术上是可以的,这些将被错误地视为脚本.另一方面,这实际上并不常见.

In Babel 7, you'll need to tell Babel what type your file is if you want to avoid this behavior. The simplest option would be to use the "sourceType" option to set sourceType: "unambiguous" in your Babel options, which essentially tells Babel to guess the type (scripts vs module), based on the presence of import and export statements. The primary downside there being that it's technically fine to have an ES6 module that doesn't use import or export, and those would be incorrectly treated as scripts. On the other hand, that's really not that common.

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

Alternatively, you can use Babel 7's "overrides" option to set specific files as scripts, e.g.

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

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

Either approach allows Babel to know that some files are script types, and thus shouldn't have this converted to undefined.

ES6代码具有两种处理模式:

ES6 code has two processing modes:

  • 脚本"-通过<script>或任何其他标准ES5加载文件的方式加载文件时
  • 模块"-将文件作为ES6模块处理时
  • "script" - When you load a file via a <script>, or any other standard ES5 way of loading a file
  • "module" - When a file is processed as an ES6 module

使用Babel 6和babel-preset-es2015(或Babel 5)时,Babel默认情况下假定其处理的文件是ES6模块.引起您麻烦的是,在ES6模块中,thisundefined并且文件都是严格的,而在脚本"情况下,this会根据环境而变化,例如浏览器脚本或CommonJS代码中的exports.

When using Babel 6 and babel-preset-es2015 (or Babel 5), Babel by default assumes that files it processes are ES6 modules. The thing that is causing you trouble is that in an ES6 module, this is undefined and files are all strict, whereas in the "script" case, this varies depending on the environment, like window in a browser script or exports in CommonJS code.

如果您使用的是Babel,最简单的选择是在不使用UMD包装器的情况下编写代码,然后使用Browserify之类的文件捆绑文件以自动为您添加UMD包装器. Babel还提供了babel-plugin-transform-es2015-modules-umd.两者都是为了简化而设计的,因此,如果您想要定制的UMD方法,那么它们可能不适合您.

If you are using Babel, the easiest option is to write your code without the UMD wrapper, and then bundle your file using something like Browserify to automatically add the UMD wrapper for you. Babel also provides a babel-plugin-transform-es2015-modules-umd. Both are geared toward simplicity, so if you want a customized UMD approach, they may not be for you.

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

Alternatively, you would need to explicitly list all of the Babel plugins in babel-preset-es2015, making sure to exclude the module-processing babel-plugin-transform-es2015-modules-commonjs plugin. Note, this will also stop the automatic addition of use strict since that is part of the ES6 spec too, you may want to add back babel-plugin-transform-strict-mode to keep your code strict automatically.

babel-core@6.13开始,预设可以使用选项,因此您也可以这样做

As of babel-core@6.13 presets are able to take options, so you can also do

{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}

在Babel配置(.babelrc)中

在禁用模块处理的情况下使用babel-preset-es2015.

in your Babel config (.babelrc) to use babel-preset-es2015 with module processing disabled.

这篇关于如何阻止babel将"this"转换为"undefined"(并插入"use strict")的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆