编辑:这是不是胖箭。它也不是将此传递给 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() {
代替此似乎有效。我不确定这是最好的方法。
答案 0 :(得分:59)
ES6代码有两种处理模式:
<script>
或任何其他标准ES5加载文件的方式加载文件时在Babel 7.x中,默认情况下将文件解析为“模块”。导致您遇到麻烦的是,在ES6模块中,this
为undefined
,而在"script"
情况下,这取决于环境,例如window
CommonJS代码中的浏览器脚本或exports
。同样,"module"
文件会自动严格,因此Babel会插入"use strict";
。
在Babel 7中,如果你想避免这种行为,你需要告诉Babel你的文件是什么类型的。最简单的选择是使用"sourceType"
选项在您的Babel选项中设置sourceType: "unambiguous"
,这实际上告诉Babel根据import
的存在来猜测类型(脚本与模块)和export
陈述。主要的缺点是,在技术上没有使用不使用import
或export
的ES6模块,并且那些将被错误地视为脚本。另一方面,这真的不常见。
或者,您可以使用Babel 7的"overrides"
选项将特定文件设置为脚本,例如
overrides: [{
test: "./vendor/something.umd.js",
sourceType: "script",
}],
这两种方法都允许Babel知道某些文件属于script
类型,因此不应将this
转换为undefined
。
ES6代码有两种处理模式:
<script>
或任何其他标准ES5加载文件的方式加载文件时使用Babel 6和babel-preset-es2015
(或Babel 5)时,Babel默认假定它处理的文件是ES6模块。导致您麻烦的是,在ES6模块中,this
为undefined
且文件都是严格的,而在“脚本”情况下,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进行包装的其他库造成了严重破坏。