EDIT: This is not about fat arrows. It's also not about passing this to an IIFE. It's a transpiler-related question.
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.
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
});
But no matter what I try (such as making this a variable and passing it) it sets it to undefined.
}(undefined, function() {
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?
UPDATE: Passing }((window || module || {}), function() {
instead of this seems to work. I'm not sure this is the best approach though.
The "es2015" preset wraps the Babel output in a commonJs wrapper by default. Use the "babel-preset-es2015-script" (you must
npm install --save babel-preset-es2015-script
first) to output for "script" (no modules). This was wreaking havoc on other libraries I was wrapping up using Babel.The preset: https://www.npmjs.com/package/babel-preset-es2015-script
For Babel >= 7.x
ES6 code has two processing modes:
<script>
, or any other standard ES5 way of loading a fileIn Babel 7.x, files are parsed as "module" by default. The thing that is causing you trouble is that in an ES6 module,
this
isundefined
, whereas in the"script"
case, this varies depending on the environment, likewindow
in a browser script orexports
in CommonJS code.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 setsourceType: "unambiguous"
in your Babel options, which essentially tells Babel to guess the type (scripts vs module), based on the presence ofimport
andexport
statements. The primary downside there being that it's technically fine to have an ES6 module that doesn't useimport
orexport
, and those would be incorrectly treated as scripts. On the other hand, that's really not that common.Alternatively, you can use Babel 7's
"overrides"
option to set specific files as scripts, e.g.Either approach allows Babel to know that some files are
script
types, and thus shouldn't havethis
converted toundefined
.For Babel < 7.x
ES6 code has two processing modes:
<script>
, or any other standard ES5 way of loading a fileWhen 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
isundefined
, whereas in the "script" case,this
varies depending on the environment, likewindow
in a browser script orexports
in CommonJS code.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.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 ofuse strict
since that is part of the ES6 spec too, you may want to add backbabel-plugin-transform-strict-mode
to keep your code strict automatically.As of
babel-core@6.13
presets are able to take options, so you can also doin your Babel config (
.babelrc
) to usebabel-preset-es2015
with module processing disabled.