All Projects → motiz88 → babel-plugin-transform-hoist-nested-functions

motiz88 / babel-plugin-transform-hoist-nested-functions

Licence: MIT license
Babel plugin to move nested functions to outer scopes

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to babel-plugin-transform-hoist-nested-functions

babel-plugin-tailwind-rn
Allows you to use className="w-full md:w-1/2" syntax in your react native projects.
Stars: ✭ 31 (-3.12%)
Mutual labels:  babel-plugin
babel-plugin-solid-labels
Simple, reactive labels for SolidJS
Stars: ✭ 127 (+296.88%)
Mutual labels:  babel-plugin
babel-plugin-transform-amd-to-commonjs
✨ Babel plugin that transforms AMD to CommonJS
Stars: ✭ 44 (+37.5%)
Mutual labels:  babel-plugin
babel-plugin-hyperscript-to-jsx
This plugin transforms react-hyperscript into JSX. Intended to be used as codemod.
Stars: ✭ 20 (-37.5%)
Mutual labels:  babel-plugin
babel-plugin-transform-for-of-as-array
Transform all for-of loops into the equivalent array for loop
Stars: ✭ 14 (-56.25%)
Mutual labels:  babel-plugin
babel-plugin-transform-rename-properties
A Babel plugin for renaming JavaScript properties
Stars: ✭ 19 (-40.62%)
Mutual labels:  babel-plugin
Xwind
Tailwind CSS as a templating language in JS and CSS-in-JS
Stars: ✭ 249 (+678.13%)
Mutual labels:  babel-plugin
babel-plugin-object-styles-to-template
Babel plugin to transpile object styles to template literal
Stars: ✭ 33 (+3.13%)
Mutual labels:  babel-plugin
babel-plugin-feature-flags
A babel transform for managing feature flags
Stars: ✭ 57 (+78.13%)
Mutual labels:  babel-plugin
babel-plugin-react-directives
A babel plugin that provides some directives for react(JSX), similar to directives of vue.
Stars: ✭ 80 (+150%)
Mutual labels:  babel-plugin
nornj
More exciting JS/JSX based on Template Engine, support control flow tags, custom directives, two-way binding, filters and custom operators.
Stars: ✭ 97 (+203.13%)
Mutual labels:  babel-plugin
idomizer
An HTML template parser compiling an incremental-dom render factory.
Stars: ✭ 15 (-53.12%)
Mutual labels:  babel-plugin
babel-plugin-storybook-csf-title
A Babel plugin to generate titles for Storybook CSF stories at compile time, typically based on the story file's file name.
Stars: ✭ 17 (-46.87%)
Mutual labels:  babel-plugin
babel-plugin-rewire-exports
Babel plugin for stubbing [ES6, ES2015] module exports
Stars: ✭ 62 (+93.75%)
Mutual labels:  babel-plugin
babel-plugin-transform-react-qa-classes
Add component's name in `data-qa` attributes to React Components
Stars: ✭ 41 (+28.13%)
Mutual labels:  babel-plugin
S2s
Coding time Compile. A tool to write code fastest.
Stars: ✭ 254 (+693.75%)
Mutual labels:  babel-plugin
babel-plugin-solid-undestructure
A Babel plugin for SolidJS that allows you to destructure component props without losing reactivity.
Stars: ✭ 45 (+40.63%)
Mutual labels:  babel-plugin
sprockets-bumble d
Sprockets plugin to transpile modern javascript using Babel, useful while migrating to ES6 modules
Stars: ✭ 32 (+0%)
Mutual labels:  babel-plugin
babel-plugin-detective
Babel plugin that scans the AST for require calls and import statements
Stars: ✭ 26 (-18.75%)
Mutual labels:  babel-plugin
babel-plugin-console-source
Add the file name and line numbers to all console logs.
Stars: ✭ 38 (+18.75%)
Mutual labels:  babel-plugin

babel-plugin-transform-hoist-nested-functions

Greenkeeper badge circle npm coverage

semantic release js-semistandard-style MIT License

Babel plugin to hoist nested functions to the outermost scope possible without changing their contract.

Examples

Example 1 - basic hoisting

In

function renderApp () {
  return renderStateContainer(
    ({value}) => renderValue(value)
  );
}

Out

var _hoistedAnonymousFunc = ({ value }) => renderValue(value);

function renderApp () {
  return renderStateContainer(_hoistedAnonymousFunc);
}

Example 2 - nested method hoisting

To enable this transformation, pass the methods: true option to the plugin (see below). The output code depends on the ES2015 Symbol feature and the stage 2 class properties proposal. You will most likely want to run babel-plugin-transform-class-properties after transform-hoist-nested-function.

In

class Foo {
  bar () {
    return () => this;
  }
}

Out

const _hoistedMethod = new Symbol("_hoistedMethod"),

class Foo {
  [_hoistedMethod] = () => this;

  bar() {
    return this[_hoistedMethod];
  }
}

Motivation

Patterns like React "render callbacks", that make heavy use of nested functions, incur the nonzero runtime cost of creating those functions over and over. JavaScript engines don't always optimize this cost away.

To mitigate this cost, this plugin moves functions out of inner scopes wherever possible. A function can be moved up through any scope that it does not reference explicitly. This is somewhat analogous to what babel-plugin-transform-react-constant-elements does (and in fact some of the same Babel machinery is applied).

Caveats

Experimental

This is a new, experimental plugin. Expect changes (adhering religiously to semver), and please, please, PLEASE test and benchmark your code very thoroughly before using this in anything important.

Not 100% transparent

While the plugin aims not to change the behavior of hoisted functions, the fact that they are reused rather than recreated does have some visible consequences.

Consider the following code:

function factory () {
  return function foo () {}; // foo() will be hoisted right above factory()
}
factory() === factory(); // ⬅ value depends on whether foo() is hoisted

That last expression evaluates to false in plain JavaScript, but is true if foo() has been hoisted.

More fundamentally, references to hoisted inner functions are allowed to escape their enclosing scopes. You should determine whether this is appropriate for your code before using this plugin.

Benchmarks

Here are benchmark results from the latest successful build on master using Node v4 (make your own with npm run benchmark). The benchmark code is here - each file exports a single function that is repeatedly run and timed by [Benchmark.js] (https://benchmarkjs.com).

From these preliminary results, it appears that hoisting functions this way can in fact improve performance, at least in principle; but the benefit may not always be significant.

Installation

$ npm install --save-dev babel-plugin-transform-hoist-nested-functions

Usage

Via .babelrc (Recommended)

.babelrc

// without options
{
  "plugins": ["transform-hoist-nested-functions"]
}

// with options
// NOTE: transform-class-properties is required in order to run the code
{
  "plugins": [
    ["transform-hoist-nested-functions", {
      "methods": true
    }],
    "transform-class-properties"
  ]
}

Via CLI

$ babel --plugins transform-hoist-nested-functions script.js

Via Node API

require("babel-core").transform("code", {
  plugins: ["transform-hoist-nested-functions"]
});

Development

Use npm v3: npm install -g npm@3

git clone https://github.com/motiz88/babel-plugin-transform-hoist-nested-functions
cd babel-plugin-transform-hoist-nested-functions
npm install
# ... hackity hack hack ...
npm run test:local # Including tests (mocha), code coverage (nyc), code style (eslint), type checks
                   # (flow) and benchmarks.

See package.json for more dev scripts you can use.

Contributing

PRs are very welcome. Please make sure that test:local passes on your branch.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].