Javascript 如何阻止巴贝尔传输';这';至';未定义';(并插入“严格使用”)

Javascript 如何阻止巴贝尔传输';这';至';未定义';(并插入“严格使用”),javascript,node.js,amd,babeljs,commonjs,Javascript,Node.js,Amd,Babeljs,Commonjs,编辑:这与脂肪箭头无关。这也不是把它传递给一个生活。这是一个与运输相关的问题 所以我为我正在开发的一个小应用程序创建了一个简单的酒吧sub。我在ES6中编写它是为了使用spread/rest并避免一些麻烦。我用npm和gulp设置它来传输它,但这让我发疯 我把它做成了一个浏览器库,但意识到它可以在任何地方使用,所以我决定让它与JS和AMD兼容 以下是我的代码的精简版本: (function(root, factory) { if(typeof define === 'function' &am

编辑:这与脂肪箭头无关。这也不是把它传递给一个生活。这是一个与运输相关的问题

所以我为我正在开发的一个小应用程序创建了一个简单的酒吧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
});
但无论我做什么尝试(例如将其设置为变量并传递),它都会将其设置为未定义

这可能与巴贝尔不知道这将是什么,并将其传送出去有关,但我还有其他方法可以采取吗

更新:传递
}((窗口| | |模块| |{}),函数(){
而不是这个似乎是可行的。不过我不确定这是最好的方法。

对于Babel>=7.x ES6代码有两种处理模式:

  • “脚本”-通过
    或任何其他标准ES5加载文件方式加载文件时
  • “模块”-当文件作为ES6模块处理时
在Babel 7.x中,文件默认被解析为“模块”。在ES6模块中,
这个
是未定义的,而在
的“脚本”中
在这种情况下,这取决于环境,如浏览器脚本中的
窗口
或CommonJS代码中的
导出
。类似地,
“模块”
文件自动严格,因此巴贝尔将插入
“使用严格”

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

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

overrides: [{
  test: "./vendor/something.umd.js",
  sourceType: "script",
}],
任何一种方法都允许Babel知道某些文件是
script
类型,因此不应该将
this
转换为
undefined

对于巴别塔<7.x ES6代码有两种处理模式:

  • “脚本”-通过
    或任何其他标准ES5加载文件方式加载文件时
  • “模块”-当文件作为ES6模块处理时
当使用Babel 6和
Babel-preset-es2015
(或Babel 5)时,默认情况下,Babel假定它处理的文件是ES6模块。给您带来麻烦的是,在ES6模块中,
未定义的
,文件都是严格的,而在“脚本”中在这种情况下,
因环境而异,如浏览器脚本中的
窗口
,或CommonJS代码中的
导出

如果您使用的是Babel,最简单的选择是在不使用UMD包装器的情况下编写代码,然后使用Browserify之类的工具捆绑您的文件以自动为您添加UMD包装器。Babel还提供了一个
Babel-plugin-transform-es2015-modules-UMD
。这两个工具都是为了简单起见,因此如果您想要定制UMD方法h、 它们可能不适合你

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

babel开始-core@6.13
预设可以选择选项,因此您也可以选择

{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}
在您的Babel配置(
.babelrc
)中使用
Babel-preset-es2015
,禁用模块处理。

默认情况下,“es2015”预设将Babel输出包装在commonJs包装器中。使用“Babel-preset-es2015-script”(您必须
npm安装--首先保存Babel-preset-es2015-script
)以输出“script”(没有模块)。这对我用Babel打包的其他库造成了严重破坏


预设:

您可以使用Browserify并让它为您处理所有这些。在这种情况下,
等于
未定义的
,这意味着两者都是相同的。“不知道这将是什么”---它和每个人都知道它将是
未定义的
,按照标准。@zerkms在浏览器中,
此===窗口
和节点中
此===模块
在全局范围内使用时(以及节点模块可以是全局的).@AlexanderO'Mara嗯,不是每种情况都如此。提示:严格模式如何?@zerkms说console确实在全局范围内运行,但请自己看看:谢谢!这很有意义。我选择了传递所有可能的信息,但我可能会根据您的建议重新访问。然后使用而不是
babel-preset-es2015
babel-preset-es2015-script
已经排除了
babel-plugin-transform-es2015-modules-commonjs
。我在尝试导入一个使用UMD语法包装的模块时遇到了这个问题。我遇到的最棘手的事情是,当我使用npm3安装依赖项时,一切都很好。但是当我不得不突然返回到npm2时,我就明白了根据
babel-preset-es2015-scr的GitHub页面,当我的代码的一部分需要我的模块时,这是未定义的
{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}