Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
@babel/plugin-transform-runtime
Advanced tools
Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals
The @babel/plugin-transform-runtime package is a Babel plugin that enables the re-use of Babel's injected helper code to save on codesize. It also allows you to use built-ins such as Promise or WeakMap, static methods like Array.from or Object.assign, instance methods like Array.prototype.includes, and generator functions in environments that do not natively support them.
Helpers
This feature allows Babel to transform code by extracting common helper functions into shared modules to reduce code duplication in the output.
"use strict";\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Foo = function Foo() {\n _classCallCheck(this, Foo);\n};
Polyfills for instance methods
This feature enables the use of instance methods like 'includes' on arrays, which are part of the ECMAScript specifications but may not be available in all environments.
import \"core-js/stable\";\nimport \"regenerator-runtime/runtime\";\n\n[1, 2, 3].includes(2);
Built-ins
This feature allows the use of new built-in objects like Promise, which are part of the ECMAScript specifications but may not be natively supported in all environments.
import \"core-js/stable\";\nimport \"regenerator-runtime/runtime\";\n\nvar promise = new Promise();
Generator functions
This feature allows the use of generator functions, which can be used to perform asynchronous operations in a synchronous-like manner.
import \"core-js/stable\";\nimport \"regenerator-runtime/runtime\";\n\nfunction* aGenerator() {\n yield 1;\n yield 2;\n yield 3;\n}
Core-js is a modular standard library for JavaScript, which includes polyfills for ECMAScript up to 2021. It's similar to @babel/plugin-transform-runtime in that it provides polyfills for features not available in older environments, but it's more comprehensive and can be used without Babel.
Regenerator-runtime is a standalone runtime for Regenerator-compiled generator and async functions. It's similar to the generator function handling part of @babel/plugin-transform-runtime but does not include other transformations or helpers.
Babel-polyfill is now deprecated in favor of @babel/preset-env and core-js. It used to provide a full set of polyfills for Babel users. It was similar to @babel/plugin-transform-runtime but included the polyfills in the global scope, which could lead to conflicts.
Externalise references to helpers and built-ins, automatically polyfilling your code without polluting globals. (This plugin is recommended in a library/tool)
NOTE: Instance methods such as "foobar".includes("foo")
will not work since that would require modification of existing built-ins (Use @babel/polyfill
for that).
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 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 section for more information on how this works and the types of transformations that occur.
NOTE - Production vs. development dependencies
In most cases, you should install @babel/plugin-transform-runtime
as a development dependency (with --save-dev
).
npm install --save-dev @babel/plugin-transform-runtime
and @babel/runtime
as a production dependency (with --save
).
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.
.babelrc
(Recommended)Add the following line to your .babelrc
file:
Without options:
{
"plugins": ["@babel/plugin-transform-runtime"]
}
With options:
{
"plugins": [
["@babel/plugin-transform-runtime", {
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "@babel/runtime"
}]
]
}
babel --plugins @babel/plugin-transform-runtime script.js
require("@babel/core").transform("code", {
plugins: ["@babel/plugin-transform-runtime"]
});
helpers
boolean
, defaults to true
.
Toggles whether or not inlined Babel helpers (classCallCheck
, extends
, etc.) are replaced with calls to moduleName
.
For more information, see 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.
regenerator
boolean
, defaults to true
.
Toggles whether or not generator functions are transformed to use a regenerator runtime that does not pollute the global scope.
For more information, see Regenerator aliasing.
moduleName
string
, defaults to "@babel/runtime"
.
Sets the name/path of the module used when importing helpers.
Example:
{
"moduleName": "flavortown/runtime"
}
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:
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:
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;
}
};
useESModules
boolean
, defaults to false
.
When enabled, the transform will use helpers that do not get run through
@babel/plugin-transform-modules-commonjs
. This allows for smaller builds in module
systems like webpack, since it doesn't need to preserve commonjs semantics.
For example, here is the classCallCheck
helper with useESModules
disabled:
exports.__esModule = true;
exports.default = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
And, with it enabled:
export default function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
The runtime
transformer plugin does three things:
@babel/runtime/regenerator
when you use generators/async functions.@babel/runtime/core-js
and maps ES6 static methods and built-ins.@babel/runtime/helpers
instead.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.
Make sure you include @babel/runtime
as a dependency.
Whenever you use a generator function or async function:
function* foo() {
}
the following is generated:
"use strict";
var _marked = [foo].map(regeneratorRuntime.mark);
function foo() {
return regeneratorRuntime.wrap(function foo$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
case "end":
return _context.stop();
}
}
}, _marked[0], this);
}
This isn't ideal since it relies on the regenerator runtime being included, which pollutes the global scope.
With the runtime
transformer, however, it is compiled to:
"use strict";
var _regenerator = require("@babel/runtime/regenerator");
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _marked = [foo].map(_regenerator2.default.mark);
function foo() {
return _regenerator2.default.wrap(function foo$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
case "end":
return _context.stop();
}
}
}, _marked[0], this);
}
This means that you can use the regenerator runtime without polluting your current environment.
core-js
aliasingSometimes 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:
var sym = Symbol();
var promise = new Promise;
console.log(arr[Symbol.iterator]());
into the following:
"use strict";
var _getIterator2 = require("@babel/runtime/core-js/get-iterator");
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _promise = require("@babel/runtime/core-js/promise");
var _promise2 = _interopRequireDefault(_promise);
var _symbol = require("@babel/runtime/core-js/symbol");
var _symbol2 = _interopRequireDefault(_symbol);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var sym = (0, _symbol2.default)();
var promise = new _promise2.default();
console.log((0, _getIterator3.default)(arr));
This means is that you can seamlessly use these native built-ins and static methods without worrying about where they come from.
NOTE: Instance methods such as "foobar".includes("foo")
will not work.
Usually Babel will place helpers at the top of your file to do common tasks to avoid
duplicating the code around in the current file. Sometimes these helpers can get a
little bulky and add unnecessary duplication across files. The runtime
transformer replaces all the helper calls to a module.
That means that the following code:
class Person {
}
usually turns into:
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Person = function Person() {
_classCallCheck(this, Person);
};
the runtime
transformer however turns this into:
"use strict";
var _classCallCheck2 = require("@babel/runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Person = function Person() {
(0, _classCallCheck3.default)(this, Person);
};
FAQs
Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals
The npm package @babel/plugin-transform-runtime receives a total of 10,182,284 weekly downloads. As such, @babel/plugin-transform-runtime popularity was classified as popular.
We found that @babel/plugin-transform-runtime demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.