Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime docs #1714

Merged
merged 4 commits into from
Aug 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 49 additions & 95 deletions docs/plugin-transform-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,37 @@ title: babel-plugin-transform-runtime
sidebar_label: transform-runtime
---

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).
A plugin that enables the re-use of Babel's injected helper code to save on codesize.

## Why?

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.

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.

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.

The transformer will alias these built-ins to `core-js` so you can use them seamlessly without having to require the polyfill.

See the [technical details](#technical-details) section for more information on how this works and the types of transformations that occur.
> NOTE: Instance methods such as `"foobar".includes("foo")` will not work since that would require modification of existing built-ins (you can use [`@babel/polyfill`](polyfill.md) for that).

## Installation

**NOTE - Production vs. development dependencies**

In most cases, you should install `@babel/plugin-transform-runtime` as a development dependency (with `--save-dev`).
Install it as development dependency.

```sh
npm install --save-dev @babel/plugin-transform-runtime
```

and `@babel/runtime` as a production dependency (with `--save`).
and [`@babel/runtime`](runtime.md) as a production dependency (since it's for the "runtime").
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering - can this somehow be made obvious? Like maybe we should validate it? This thing is really confusing for newcomers and it's easy to miss installing this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logan was thinking about what we can do here but not sure what we can do for v7.


```sh
npm install --save @babel/runtime
```

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.
The transformation plugin is typically used only in development, but the runtime itself will be depended on by your deployed code. See the examples below for more details.

## Why?

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.

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.

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.

The transformer will alias these built-ins to `core-js` so you can use them seamlessly without having to require the polyfill.

See the [technical details](#technical-details) section for more information on how this works and the types of transformations that occur.

## Usage

Expand All @@ -50,21 +50,23 @@ Without options:
}
```

With options:
With options (and their defaults):

```json
{
"plugins": [
["@babel/plugin-transform-runtime", {
"helpers": false,
"polyfill": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"moduleName": "@babel/runtime"
"useESModules": false
}]
]
}
```

The plugin defaults to assuming that all polyfillable APIs will be provided by the user. Otherwise the [`corejs`](#corejs) option needs to be specified.

### Via CLI

```sh
Expand All @@ -81,6 +83,20 @@ require("@babel/core").transform("code", {

## Options

### `corejs`

`boolean` or `number` , defaults to `false`.

e.g. `['transform-runtime', { corejs: 2 }],`

Specifying a number will rewrite the helpers that need polyfillable APIs to reference `core-js` instead.

This requires changing the dependency used to be `@babel/runtime-corejs2` instead of `@babel/runtime`.

```sh
npm install --save @babel/runtime-corejs2
```

### `helpers`

`boolean`, defaults to `true`.
Expand All @@ -91,11 +107,7 @@ For more information, see [Helper aliasing](#helper-aliasing).

### `polyfill`

`boolean`, defaults to `true`.

Toggles whether or not new built-ins (`Promise`, `Set`, `Map`, etc.) are transformed to use a non-global polluting polyfill.

For more information, see [`core-js` aliasing](#core-js-aliasing).
> This option was removed in v7 by just making it the default.

### `regenerator`

Expand All @@ -105,68 +117,9 @@ Toggles whether or not generator functions are transformed to use a regenerator

For more information, see [Regenerator aliasing](#regenerator-aliasing).

### `moduleName`

`string`, defaults to `"@babel/runtime"`.

Sets the name/path of the module used when importing helpers.

Example:

```json
{
"moduleName": "flavortown/runtime"
}
```

```js
import extends from 'flavortown/runtime/helpers/extends';
```

### `useBuiltIns`

`boolean`, defaults to `false`.

When enabled, the transform will use helpers that do not use _any_ polyfills
from `core-js`.

For example, here is the `instance` helper with `useBuiltIns` disabled:

```js
exports.__esModule = true;

var _hasInstance = require("../core-js/symbol/has-instance");

var _hasInstance2 = _interopRequireDefault(_hasInstance);

var _symbol = require("../core-js/symbol");

var _symbol2 = _interopRequireDefault(_symbol);

exports.default = function (left, right) {
if (right != null && typeof _symbol2.default !== "undefined" && right[_hasInstance2.default]) {
return right[_hasInstance2.default](left);
} else {
return left instanceof right;
}
};

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
```

And, with it enabled:

```js
exports.__esModule = true;

exports.default = function (left, right) {
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
return right[Symbol.hasInstance](left);
} else {
return left instanceof right;
}
};
```
> This option was removed in v7 by just making it the default.

### `useESModules`

Expand Down Expand Up @@ -200,11 +153,11 @@ export default function (instance, Constructor) {

## Technical details

The `runtime` transformer plugin does three things:
The `transform-runtime` transformer plugin does three things:

* Automatically requires `@babel/runtime/regenerator` when you use generators/async functions.
* Automatically requires `@babel/runtime/core-js` and maps ES6 static methods and built-ins.
* Removes the inline Babel helpers and uses the module `@babel/runtime/helpers` instead.
* Automatically requires `@babel/runtime/regenerator` when you use generators/async functions (toggleable with the `regenerator` option).
* Can use `core-js` for helpers if necessary instead of assuming it will be polyfilled by the user (toggleable with the `corejs` option)
* Automatically removes the inline Babel helpers and uses the module `@babel/runtime/helpers` instead (toggleable with the `helpers` option).

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.

Expand Down Expand Up @@ -276,7 +229,9 @@ This means that you can use the regenerator runtime without polluting your curre
Sometimes you may want to use new built-ins such as `Map`, `Set`, `Promise` etc. Your only way
to use these is usually to include a globally polluting polyfill.

What the `runtime` transformer does is transform the following:
This is with the `corejs` option.

The plugin transforms the following:

```javascript
var sym = Symbol();
Expand All @@ -291,15 +246,15 @@ into the following:
```javascript
"use strict";

var _getIterator2 = require("@babel/runtime/core-js/get-iterator");
var _getIterator2 = require("@babel/runtime-corejs2/core-js/get-iterator");

var _getIterator3 = _interopRequireDefault(_getIterator2);

var _promise = require("@babel/runtime/core-js/promise");
var _promise = require("@babel/runtime-corejs2/core-js/promise");

var _promise2 = _interopRequireDefault(_promise);

var _symbol = require("@babel/runtime/core-js/symbol");
var _symbol = require("@babel/runtime-corejs2/core-js/symbol");

var _symbol2 = _interopRequireDefault(_symbol);

Expand Down Expand Up @@ -358,4 +313,3 @@ var Person = function Person() {
(0, _classCallCheck3.default)(this, Person);
};
```

49 changes: 48 additions & 1 deletion docs/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,52 @@ title: babel-runtime
sidebar_label: babel-runtime
---

TODO
`@babel/runtime` is a library that contain's Babel modular runtime helpers and a version of `regenerator-runtime`.

## Installation

```sh
npm install --save @babel/runtime
```

> See also: `@babel/runtime-corejs2`.

## Usage

This is meant to be used as a runtime `dependency` along with the Babel plugin [`@babel/plugin-transform-runtime`](plugin-transform-runtime.md). Please check out the documentation in that package for usage.

## Why

Sometimes Babel may inject some code in the output that is the same and thus can be potentially re-used.

For example, with the class transform (without loose mode):

```js
class A {}
```

turns into:

```js
function _classCallCheck(instance, Constructor) {
//...
}

var Circle = function Circle() {
_classCallCheck(this, Circle);
};
```

this means every file that contains a class would have the `_classCallCheck` function repeated each time.

With `@babel/plugin-transform-runtime`, it would replace the reference to the function to the `@babel/runtime` version.

```js
var _classCallCheck = require("@babel/runtime/helpers/classCallCheck");

var Circle = function Circle() {
_classCallCheck(this, Circle);
};
```

`@babel/runtime` is just the package that contains the implementations of the functions in a modular way.