Add exactGlobals option to transform-es2015-modules-umd plugin

to enable more flexibility specifying global names
This commit is contained in:
Richard Macklin
2016-06-19 02:32:24 -07:00
parent 8b0179e2d5
commit c252d3dae6
13 changed files with 252 additions and 5 deletions

View File

@@ -34,6 +34,104 @@ as `global.Promise` rather than `global.es6Promise`. This can be accommodated by
}
```
#### Default semantics
There are a couple things to note about the default semantics.
_First_, this transform uses the
[basename](https://en.wikipedia.org/wiki/Basename) of each import to generate
the global names in the UMD output. This means that if you're importing
multiple modules with the same basename, like:
```js
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
```
it will transpile into two references to the same browser global:
```js
factory(global.fooBar, global.fooBar);
```
If you set the plugin options to:
```json
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
}
}
```
it will still transpile both to one browser global:
```js
factory(global.fooBAR, global.fooBAR);
```
because again the transform is only using the basename of the import.
_Second_, the specified override will still be passed to the `toIdentifier`
function in [babel-types/src/converters](../babel-types/src/converters.js).
This means that if you specify an override as a member expression like:
```json
{
"globals": {
"fizzbuzz": "fizz.buzz"
}
}
```
this will _not_ transpile to `factory(global.fizz.buzz)`. Instead, it will
transpile to `factory(global.fizzBuzz)` based on the logic in `toIdentifier`.
#### More flexible semantics with `exactGlobals: true`
Both of these behaviors can limit the flexibility of the `globals` map. To
remove these limitations, you can set the `exactGlobals` option to `true`.
Doing this instructs the plugin to:
1. always use the full import string instead of the basename when generating
the global names
2. skip passing `globals` overrides to the `toIdentifier` function. Instead,
they are used exactly as written, so you will get errors if you do not use
valid identifiers or valid uncomputed (dot) member expressions.
Thus, if you set `exactGlobals` to `true` and do not pass any overrides, the
first example of:
```js
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
```
will transpile to:
```js
factory(global.fooBar, global.mylibFooBar);
```
And if you set the plugin options to:
```json
{
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar"
},
"exactGlobals": true
}
```
then it'll transpile to:
```js
factory(global.fooBAR, global.mylib.fooBar)
```
### Via CLI
```sh

View File

@@ -65,12 +65,32 @@ export default function ({ types: t }) {
} else if (arg.value === "exports") {
return t.memberExpression(t.identifier("mod"), t.identifier("exports"));
} else {
let requireName = basename(arg.value, extname(arg.value));
let globalName = browserGlobals[requireName] || requireName;
let memberExpression;
return t.memberExpression(t.identifier("global"), t.identifier(
t.toIdentifier(globalName)
));
if (state.opts.exactGlobals) {
let globalRef = browserGlobals[arg.value];
if (globalRef) {
if (globalRef.indexOf(".") > -1) {
memberExpression = globalRef.split(".").reduce(
(accum, curr) => t.memberExpression(accum, t.identifier(curr)), t.identifier("global")
);
} else {
memberExpression = t.memberExpression(t.identifier("global"), t.identifier(globalRef));
}
} else {
memberExpression = t.memberExpression(
t.identifier("global"), t.identifier(t.toIdentifier(arg.value))
);
}
} else {
let requireName = basename(arg.value, extname(arg.value));
let globalName = browserGlobals[requireName] || requireName;
memberExpression = t.memberExpression(
t.identifier("global"), t.identifier(t.toIdentifier(globalName))
);
}
return memberExpression;
}
});

View File

@@ -0,0 +1,3 @@
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
import fizzBuzz from "fizzbuzz";

View File

@@ -0,0 +1,21 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["foo-bar", "./mylib/foo-bar", "fizzbuzz"], factory);
} else if (typeof exports !== "undefined") {
factory(require("foo-bar"), require("./mylib/foo-bar"), require("fizzbuzz"));
} else {
var mod = {
exports: {}
};
factory(global.fooBAR, global.fooBAR, global.fizzBuzz);
global.actual = mod.exports;
}
})(this, function (_fooBar, _fooBar3, _fizzbuzz) {
"use strict";
var _fooBar2 = babelHelpers.interopRequireDefault(_fooBar);
var _fooBar4 = babelHelpers.interopRequireDefault(_fooBar3);
var _fizzbuzz2 = babelHelpers.interopRequireDefault(_fizzbuzz);
});

View File

@@ -0,0 +1,12 @@
{
"plugins": [
"external-helpers",
["transform-es2015-modules-umd", {
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar",
"fizzbuzz": "fizz.buzz"
}
}]
]
}

View File

@@ -0,0 +1,3 @@
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
import fizzBuzz from "fizzbuzz";

View File

@@ -0,0 +1,21 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["foo-bar", "./mylib/foo-bar", "fizzbuzz"], factory);
} else if (typeof exports !== "undefined") {
factory(require("foo-bar"), require("./mylib/foo-bar"), require("fizzbuzz"));
} else {
var mod = {
exports: {}
};
factory(global.fooBar, global.fooBar, global.fizzbuzz);
global.actual = mod.exports;
}
})(this, function (_fooBar, _fooBar3, _fizzbuzz) {
"use strict";
var _fooBar2 = babelHelpers.interopRequireDefault(_fooBar);
var _fooBar4 = babelHelpers.interopRequireDefault(_fooBar3);
var _fizzbuzz2 = babelHelpers.interopRequireDefault(_fizzbuzz);
});

View File

@@ -0,0 +1,3 @@
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
import fizzBuzz from "fizzbuzz";

View File

@@ -0,0 +1,21 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["foo-bar", "./mylib/foo-bar", "fizzbuzz"], factory);
} else if (typeof exports !== "undefined") {
factory(require("foo-bar"), require("./mylib/foo-bar"), require("fizzbuzz"));
} else {
var mod = {
exports: {}
};
factory(global.fooBAR, global.mylib.fooBar, global.fizz.buzz);
global.actual = mod.exports;
}
})(this, function (_fooBar, _fooBar3, _fizzbuzz) {
"use strict";
var _fooBar2 = babelHelpers.interopRequireDefault(_fooBar);
var _fooBar4 = babelHelpers.interopRequireDefault(_fooBar3);
var _fizzbuzz2 = babelHelpers.interopRequireDefault(_fizzbuzz);
});

View File

@@ -0,0 +1,13 @@
{
"plugins": [
"external-helpers",
["transform-es2015-modules-umd", {
"globals": {
"foo-bar": "fooBAR",
"./mylib/foo-bar": "mylib.fooBar",
"fizzbuzz": "fizz.buzz"
},
"exactGlobals": true
}]
]
}

View File

@@ -0,0 +1,3 @@
import fooBar1 from "foo-bar";
import fooBar2 from "./mylib/foo-bar";
import fizzBuzz from "fizzbuzz";

View File

@@ -0,0 +1,21 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["foo-bar", "./mylib/foo-bar", "fizzbuzz"], factory);
} else if (typeof exports !== "undefined") {
factory(require("foo-bar"), require("./mylib/foo-bar"), require("fizzbuzz"));
} else {
var mod = {
exports: {}
};
factory(global.fooBar, global.mylibFooBar, global.fizzbuzz);
global.actual = mod.exports;
}
})(this, function (_fooBar, _fooBar3, _fizzbuzz) {
"use strict";
var _fooBar2 = babelHelpers.interopRequireDefault(_fooBar);
var _fooBar4 = babelHelpers.interopRequireDefault(_fooBar3);
var _fizzbuzz2 = babelHelpers.interopRequireDefault(_fizzbuzz);
});

View File

@@ -0,0 +1,8 @@
{
"plugins": [
"external-helpers",
["transform-es2015-modules-umd", {
"exactGlobals": true
}]
]
}