1 | # @babel/plugin-transform-runtime
|
2 |
|
3 | > Externalise references to helpers and built-ins, automatically polyfilling your code without polluting globals. (This plugin is recommended in a library/tool)
|
4 |
|
5 | NOTE: Instance methods such as `"foobar".includes("foo")` will not work since that would require modification of existing built-ins (Use [`@babel/polyfill`](http://babeljs.io/docs/usage/polyfill) for that).
|
6 |
|
7 | ## Why?
|
8 |
|
9 | Babel 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 |
|
11 | This is where the `@babel/plugin-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 |
|
13 | Another 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 |
|
15 | The transformer will alias these built-ins to `core-js` so you can use them seamlessly without having to require the polyfill.
|
16 |
|
17 | See 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 |
|
23 | In most cases, you should install `@babel/plugin-transform-runtime` as a development dependency (with `--save-dev`).
|
24 |
|
25 | ```sh
|
26 | npm install --save-dev @babel/plugin-transform-runtime
|
27 | ```
|
28 |
|
29 | and `@babel/runtime` as a production dependency (with `--save`).
|
30 |
|
31 | ```sh
|
32 | npm install --save @babel/runtime
|
33 | ```
|
34 |
|
35 | The 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 |
|
41 | Add the following line to your `.babelrc` file:
|
42 |
|
43 | Without options:
|
44 |
|
45 | ```json
|
46 | {
|
47 | "plugins": ["@babel/plugin-transform-runtime"]
|
48 | }
|
49 | ```
|
50 |
|
51 | With options:
|
52 |
|
53 | ```json
|
54 | {
|
55 | "plugins": [
|
56 | ["@babel/plugin-transform-runtime", {
|
57 | "helpers": false,
|
58 | "polyfill": false,
|
59 | "regenerator": true,
|
60 | "moduleName": "@babel/runtime"
|
61 | }]
|
62 | ]
|
63 | }
|
64 | ```
|
65 |
|
66 | ### Via CLI
|
67 |
|
68 | ```sh
|
69 | babel --plugins @babel/plugin-transform-runtime script.js
|
70 | ```
|
71 |
|
72 | ### Via Node API
|
73 |
|
74 | ```javascript
|
75 | require("@babel/core").transform("code", {
|
76 | plugins: ["@babel/plugin-transform-runtime"]
|
77 | });
|
78 | ```
|
79 |
|
80 | ## Options
|
81 |
|
82 | ### `helpers`
|
83 |
|
84 | `boolean`, defaults to `true`.
|
85 |
|
86 | Toggles whether or not inlined Babel helpers (`classCallCheck`, `extends`, etc.) are replaced with calls to `moduleName`.
|
87 |
|
88 | For more information, see [Helper aliasing](#helper-aliasing).
|
89 |
|
90 | ### `polyfill`
|
91 |
|
92 | `boolean`, defaults to `true`.
|
93 |
|
94 | Toggles whether or not new built-ins (`Promise`, `Set`, `Map`, etc.) are transformed to use a non-global polluting polyfill.
|
95 |
|
96 | For more information, see [`core-js` aliasing](#core-js-aliasing).
|
97 |
|
98 | ### `regenerator`
|
99 |
|
100 | `boolean`, defaults to `true`.
|
101 |
|
102 | Toggles whether or not generator functions are transformed to use a regenerator runtime that does not pollute the global scope.
|
103 |
|
104 | For more information, see [Regenerator aliasing](#regenerator-aliasing).
|
105 |
|
106 | ### `moduleName`
|
107 |
|
108 | `string`, defaults to `"@babel/runtime"`.
|
109 |
|
110 | Sets the name/path of the module used when importing helpers.
|
111 |
|
112 | Example:
|
113 |
|
114 | ```json
|
115 | {
|
116 | "moduleName": "flavortown/runtime"
|
117 | }
|
118 | ```
|
119 |
|
120 | ```js
|
121 | import extends from 'flavortown/runtime/helpers/extends';
|
122 | ```
|
123 |
|
124 | ### `useBuiltIns`
|
125 |
|
126 | `boolean`, defaults to `false`.
|
127 |
|
128 | When enabled, the transform will use helpers that do not use _any_ polyfills
|
129 | from `core-js`.
|
130 |
|
131 | For example, here is the `instance` helper with `useBuiltIns` disabled:
|
132 |
|
133 | ```js
|
134 | exports.__esModule = true;
|
135 |
|
136 | var _hasInstance = require("../core-js/symbol/has-instance");
|
137 |
|
138 | var _hasInstance2 = _interopRequireDefault(_hasInstance);
|
139 |
|
140 | var _symbol = require("../core-js/symbol");
|
141 |
|
142 | var _symbol2 = _interopRequireDefault(_symbol);
|
143 |
|
144 | exports.default = function (left, right) {
|
145 | if (right != null && typeof _symbol2.default !== "undefined" && right[_hasInstance2.default]) {
|
146 | return right[_hasInstance2.default](left);
|
147 | } else {
|
148 | return left instanceof right;
|
149 | }
|
150 | };
|
151 |
|
152 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
153 | ```
|
154 |
|
155 | And, with it enabled:
|
156 |
|
157 | ```js
|
158 | exports.__esModule = true;
|
159 |
|
160 | exports.default = function (left, right) {
|
161 | if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
162 | return right[Symbol.hasInstance](left);
|
163 | } else {
|
164 | return left instanceof right;
|
165 | }
|
166 | };
|
167 | ```
|
168 |
|
169 | ### `useESModules`
|
170 |
|
171 | `boolean`, defaults to `false`.
|
172 |
|
173 | When enabled, the transform will use helpers that do not get run through
|
174 | `@babel/plugin-transform-modules-commonjs`. This allows for smaller builds in module
|
175 | systems like webpack, since it doesn't need to preserve commonjs semantics.
|
176 |
|
177 | For example, here is the `classCallCheck` helper with `useESModules` disabled:
|
178 |
|
179 | ```js
|
180 | exports.__esModule = true;
|
181 |
|
182 | exports.default = function (instance, Constructor) {
|
183 | if (!(instance instanceof Constructor)) {
|
184 | throw new TypeError("Cannot call a class as a function");
|
185 | }
|
186 | };
|
187 | ```
|
188 |
|
189 | And, with it enabled:
|
190 |
|
191 | ```js
|
192 | export default function (instance, Constructor) {
|
193 | if (!(instance instanceof Constructor)) {
|
194 | throw new TypeError("Cannot call a class as a function");
|
195 | }
|
196 | }
|
197 | ```
|
198 |
|
199 | ## Technical details
|
200 |
|
201 | The `runtime` transformer plugin does three things:
|
202 |
|
203 | * Automatically requires `@babel/runtime/regenerator` when you use generators/async functions.
|
204 | * Automatically requires `@babel/runtime/core-js` and maps ES6 static methods and built-ins.
|
205 | * Removes the inline Babel helpers and uses the module `@babel/runtime/helpers` instead.
|
206 |
|
207 | What 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.
|
208 |
|
209 | Make sure you include `@babel/runtime` as a dependency.
|
210 |
|
211 | ### Regenerator aliasing
|
212 |
|
213 | Whenever you use a generator function or async function:
|
214 |
|
215 | ```javascript
|
216 | function* foo() {
|
217 |
|
218 | }
|
219 | ```
|
220 |
|
221 | the following is generated:
|
222 |
|
223 | ```javascript
|
224 | "use strict";
|
225 |
|
226 | var _marked = [foo].map(regeneratorRuntime.mark);
|
227 |
|
228 | function foo() {
|
229 | return regeneratorRuntime.wrap(function foo$(_context) {
|
230 | while (1) {
|
231 | switch (_context.prev = _context.next) {
|
232 | case 0:
|
233 | case "end":
|
234 | return _context.stop();
|
235 | }
|
236 | }
|
237 | }, _marked[0], this);
|
238 | }
|
239 | ```
|
240 |
|
241 | This isn't ideal since it relies on the regenerator runtime being included, which
|
242 | pollutes the global scope.
|
243 |
|
244 | With the `runtime` transformer, however, it is compiled to:
|
245 |
|
246 | ```javascript
|
247 | "use strict";
|
248 |
|
249 | var _regenerator = require("@babel/runtime/regenerator");
|
250 |
|
251 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
252 |
|
253 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
254 |
|
255 | var _marked = [foo].map(_regenerator2.default.mark);
|
256 |
|
257 | function foo() {
|
258 | return _regenerator2.default.wrap(function foo$(_context) {
|
259 | while (1) {
|
260 | switch (_context.prev = _context.next) {
|
261 | case 0:
|
262 | case "end":
|
263 | return _context.stop();
|
264 | }
|
265 | }
|
266 | }, _marked[0], this);
|
267 | }
|
268 | ```
|
269 |
|
270 | This means that you can use the regenerator runtime without polluting your current environment.
|
271 |
|
272 | ### `core-js` aliasing
|
273 |
|
274 | Sometimes you may want to use new built-ins such as `Map`, `Set`, `Promise` etc. Your only way
|
275 | to use these is usually to include a globally polluting polyfill.
|
276 |
|
277 | What the `runtime` transformer does is transform the following:
|
278 |
|
279 | ```javascript
|
280 | var sym = Symbol();
|
281 |
|
282 | var promise = new Promise;
|
283 |
|
284 | console.log(arr[Symbol.iterator]());
|
285 | ```
|
286 |
|
287 | into the following:
|
288 |
|
289 | ```javascript
|
290 | "use strict";
|
291 |
|
292 | var _getIterator2 = require("@babel/runtime/core-js/get-iterator");
|
293 |
|
294 | var _getIterator3 = _interopRequireDefault(_getIterator2);
|
295 |
|
296 | var _promise = require("@babel/runtime/core-js/promise");
|
297 |
|
298 | var _promise2 = _interopRequireDefault(_promise);
|
299 |
|
300 | var _symbol = require("@babel/runtime/core-js/symbol");
|
301 |
|
302 | var _symbol2 = _interopRequireDefault(_symbol);
|
303 |
|
304 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
305 |
|
306 | var sym = (0, _symbol2.default)();
|
307 |
|
308 | var promise = new _promise2.default();
|
309 |
|
310 | console.log((0, _getIterator3.default)(arr));
|
311 | ```
|
312 |
|
313 | This means is that you can seamlessly use these native built-ins and static methods
|
314 | without worrying about where they come from.
|
315 |
|
316 | **NOTE:** Instance methods such as `"foobar".includes("foo")` will **not** work.
|
317 |
|
318 | ### Helper aliasing
|
319 |
|
320 | Usually Babel will place helpers at the top of your file to do common tasks to avoid
|
321 | duplicating the code around in the current file. Sometimes these helpers can get a
|
322 | little bulky and add unnecessary duplication across files. The `runtime`
|
323 | transformer replaces all the helper calls to a module.
|
324 |
|
325 | That means that the following code:
|
326 |
|
327 | ```javascript
|
328 | class Person {
|
329 | }
|
330 | ```
|
331 |
|
332 | usually turns into:
|
333 |
|
334 | ```javascript
|
335 | "use strict";
|
336 |
|
337 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
338 |
|
339 | var Person = function Person() {
|
340 | _classCallCheck(this, Person);
|
341 | };
|
342 | ```
|
343 |
|
344 | the `runtime` transformer however turns this into:
|
345 |
|
346 | ```javascript
|
347 | "use strict";
|
348 |
|
349 | var _classCallCheck2 = require("@babel/runtime/helpers/classCallCheck");
|
350 |
|
351 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
352 |
|
353 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
354 |
|
355 | var Person = function Person() {
|
356 | (0, _classCallCheck3.default)(this, Person);
|
357 | };
|
358 | ```
|