UNPKG

6.96 kBMarkdownView Raw
1# babel-plugin-transform-runtime
2
3> Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals. (This plugin is recommended in a library/tool)
4
5NOTE: Instance methods such as `"foobar".includes("foo")` will not work since that would require modification of existing builtins (Use [`babel-polyfill`](http://babeljs.io/docs/usage/polyfill) for that).
6
7## Why?
8
9Babel uses very small helpers for common functions such as `_extend`. By default this will be added to every file that requires it. This duplication is sometimes unnecessary, especially when your application is spread out over multiple files.
10
11This is where the `transform-runtime` plugin comes in: all of the helpers will reference the module `babel-runtime` to avoid duplication across your compiled output. The runtime will be compiled into your build.
12
13Another purpose of this transformer is to create a sandboxed environment for your code. If you use [babel-polyfill](http://babeljs.io/docs/usage/polyfill/) and the built-ins it provides such as `Promise`, `Set` and `Map`, those will pollute the global scope. While this might be ok for an app or a command line tool, it becomes a problem if your code is a library which you intend to publish for others to use or if you can't exactly control the environment in which your code will run.
14
15The transformer will alias these built-ins to `core-js` so you can use them seamlessly without having to require the polyfill.
16
17See the [technical details](#technical-details) section for more information on how this works and the types of transformations that occur.
18
19## Installation
20
21**NOTE - Production vs. development dependencies**
22
23In most cases, you should install `babel-plugin-transform-runtime` as a development dependency (with `--save-dev`).
24
25```sh
26npm install --save-dev babel-plugin-transform-runtime
27```
28
29and `babel-runtime` as a production dependency (with `--save`).
30
31```sh
32npm install --save babel-runtime
33```
34
35The transformation plugin is typically used only in development, but the runtime itself will be depended on by your deployed/published code. See the examples below for more details.
36
37## Usage
38
39### Via `.babelrc` (Recommended)
40
41Add the following line to your `.babelrc` file:
42
43```js
44// without options
45{
46 "plugins": ["transform-runtime"]
47}
48
49// with options
50{
51 "plugins": [
52 ["transform-runtime", {
53 "helpers": false, // defaults to true
54 "polyfill": false, // defaults to true
55 "regenerator": true, // defaults to true
56 "moduleName": "babel-runtime" // defaults to "babel-runtime"
57 }]
58 ]
59}
60```
61
62### Via CLI
63
64```sh
65babel --plugins transform-runtime script.js
66```
67
68### Via Node API
69
70```javascript
71require("babel-core").transform("code", {
72 plugins: ["transform-runtime"]
73});
74```
75
76## Technical details
77
78The `runtime` transformer plugin does three things:
79
80* Automatically requires `babel-runtime/regenerator` when you use generators/async functions.
81* Automatically requires `babel-runtime/core-js` and maps ES6 static methods and built-ins.
82* Removes the inline babel helpers and uses the module `babel-runtime/helpers` instead.
83
84What does this actually mean though? Basically, you can use built-ins such as `Promise`, `Set`, `Symbol` etc as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries.
85
86Make sure you include `babel-runtime` as a dependency.
87
88### Regenerator aliasing
89
90Whenever you use a generator function or async function:
91
92```javascript
93function* foo() {
94
95}
96```
97
98the following is generated:
99
100```javascript
101"use strict";
102
103var _marked = [foo].map(regeneratorRuntime.mark);
104
105function foo() {
106 return regeneratorRuntime.wrap(function foo$(_context) {
107 while (1) switch (_context.prev = _context.next) {
108 case 0:
109 case "end":
110 return _context.stop();
111 }
112 }, _marked[0], this);
113}
114```
115
116This isn't ideal as then you have to include the regenerator runtime which
117pollutes the global scope.
118
119Instead what the `runtime` transformer does it compile that to:
120
121```javascript
122"use strict";
123
124var _regenerator = require("babel-runtime/regenerator");
125
126var _regenerator2 = _interopRequireDefault(_regenerator);
127
128function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
129
130var _marked = [foo].map(_regenerator2.default.mark);
131
132function foo() {
133 return regeneratorRuntime.wrap(function foo$(_context) {
134 while (1) switch (_context.prev = _context.next) {
135 case 0:
136 case "end":
137 return _context.stop();
138 }
139 }, _marked[0], this);
140}
141```
142
143This means that you can use the regenerator runtime without polluting your current environment.
144
145### `core-js` aliasing
146
147Sometimes you may want to use new built-ins such as `Map`, `Set`, `Promise` etc. Your only way
148to use these is usually to include a globally polluting polyfill.
149
150What the `runtime` transformer does is transform the following:
151
152```javascript
153var sym = Symbol();
154
155var promise = new Promise;
156
157console.log(arr[Symbol.iterator]());
158```
159
160into the following:
161
162```javascript
163"use strict";
164
165var _getIterator2 = require("babel-runtime/core-js/get-iterator");
166
167var _getIterator3 = _interopRequireDefault(_getIterator2);
168
169var _promise = require("babel-runtime/core-js/promise");
170
171var _promise2 = _interopRequireDefault(_promise);
172
173var _symbol = require("babel-runtime/core-js/symbol");
174
175var _symbol2 = _interopRequireDefault(_symbol);
176
177function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
178
179var sym = (0, _symbol2.default)();
180
181var promise = new _promise2.default();
182
183console.log((0, _getIterator3.default)(arr));
184```
185
186This means is that you can seamlessly use these native built-ins and static methods
187without worrying about where they come from.
188
189**NOTE:** Instance methods such as `"foobar".includes("foo")` will **not** work.
190
191### Helper aliasing
192
193Usually babel will place helpers at the top of your file to do common tasks to avoid
194duplicating the code around in the current file. Sometimes these helpers can get a
195little bulky and add unnecessary duplication across files. The `runtime`
196transformer replaces all the helper calls to a module.
197
198That means that the following code:
199
200```javascript
201class Person {
202}
203```
204
205usually turns into:
206
207```javascript
208"use strict";
209
210function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
211
212var Person = function Person() {
213 _classCallCheck(this, Person);
214};
215```
216
217the `runtime` transformer however turns this into:
218
219```javascript
220"use strict";
221
222var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
223
224var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
225
226function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
227
228var Person = function Person() {
229 (0, _classCallCheck3.default)(this, Person);
230};
231```