EDIT:这是not about fat arrows.这也不是把this分传给IIFE分.这是一个与运输相关的问题.

因此,我为我正在开发的一个小应用程序创建了一个简单的wine 吧sub.我在ES6中编写它是为了使用spread/rest并避免一些头痛.我用npm和gulp设置它来传输它,但这让我抓狂.

我把它做成了一个浏览器库,但意识到它可以在任何地方使用,所以我决定让它与JS和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
});

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

}(undefined, function() {

这可能与巴贝尔不知道this会是什么,然后把它运走有关,但我还有其他方法吗?

UPDATE:通过}((window || module || {}), function() {而不是this似乎有效.但我不确定这是不是最好的方法.

推荐答案

对于巴贝尔>=7.十、

ES6代码有两种处理模式:

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

在巴别塔7.x、 默认情况下,文件解析为"模块".给您带来麻烦的是,在ES6模块中,thisundefined,而在"script"的情况下,这取决于环境,比如浏览器脚本中的window或CommonJS代码中的exports.同样,"module"个文件自动严格,所以Babel将插入"use strict";个.

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

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

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

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

For Babel < 7.x

ES6代码有两种处理模式:

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

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

如果您使用的是Babel,最简单的 Select 是在不使用UMD包装器的情况下编写代码,然后使用Browserify之类的工具Bundle 文件,自动为您添加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个预设可以 Select ,所以你也可以 Select

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

在Babel配置(.babelrc)中,使用babel-preset-es2015并禁用模块处理.

Node.js相关问答推荐

Windows上使用ES6+的OpenAPI规范的Express服务器不接受嵌套路由'

当建议在第二代上运行云功能时,现在是否有新的Firestore AdminClient可供使用?

对于具有重叠列的组合键,在冲突&q;上没有唯一或排除约束匹配错误

在 Docker 容器内创建一个 cron 作业(job)来执行 run.js 文件中的函数

DynamoDB 分页数据检索

每个数组值在 mongodb 中查找一个文档

Next.js 在我的电脑上没有构建错误,但它们在使用 Vercel 部署时发生

如何使用 NodeJS 加密模块将 ECDH 密钥转换为 PEM 格式

Electron 模板(Typescript + Webpack)中的这个 Electron Forge ERROR 是什么?

JavaScript & Node - 将图像文件保存到服务器但无法查看

当我使用 uuid 代码意外崩溃,然后工作正常?

提供静态文件到底是什么意思?

socket.io 发出回调合适吗?

将 myproject/.npmrc 与注册表一起使用

如何将子集合添加到 Firestore 中的文档?

为什么我会收到错误:解决方法指定过多?

如何判断 Node.js 中是否设置了环境变量?

AWS Lambda 函数写入 S3

用于轻松部署和更新的 Node.js 设置

node.js 中的意外保留字导入