# babel-plugin-hoist-constant-jsx-attributes

> Prevents unnecessary rerenders and GC pressure by hoisting constant objects out of JSX attributes and into the top-level scope, ex. for objects in a 'style' prop.

Latest version **1.0.0** (published 2021-03-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install babel-plugin-hoist-constant-jsx-attributes
pnpm add babel-plugin-hoist-constant-jsx-attributes
yarn add babel-plugin-hoist-constant-jsx-attributes
bun add babel-plugin-hoist-constant-jsx-attributes
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2021-03-18 |
| First published | 2021-03-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=10 |
| Dependencies | 7 |
| Unpacked size | 28.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Josh Wilson |
| Maintainers | joshwilsonvu |

## Links

- npm: https://www.npmjs.com/package/babel-plugin-hoist-constant-jsx-attributes
- Repository: https://github.com/joshwilsonvu/babel-plugin-hoist-constant-jsx-attributes
- npm.io page: https://npm.io/package/babel-plugin-hoist-constant-jsx-attributes

## Dependencies (7)

- [tslib](https://npm.io/package/tslib.md) ^2.1.0
- [deep-equal](https://npm.io/package/deep-equal.md) ^2.0.5
- [micromatch](https://npm.io/package/micromatch.md) ^4.0.2
- [@babel/template](https://npm.io/package/@babel/template.md) ^7.12.13
- [@types/micromatch](https://npm.io/package/@types/micromatch.md) ^4.0.1
- [@types/babel-types](https://npm.io/package/@types/babel-types.md) ^7.0.9
- [@types/babel-traverse](https://npm.io/package/@types/babel-traverse.md) ^6.25.5

## Recent versions

- 1.0.0 (latest) — 2021-03-18

## README

# babel-plugin-hoist-constant-jsx-attributes

![Version](https://img.shields.io/github/package-json/v/joshwilsonvu/babel-plugin-hoist-constant-jsx-attributes)
![NPM Version](https://img.shields.io/npm/v/babel-plugin-hoist-constant-jsx-attributes)
![License](https://img.shields.io/github/license/joshwilsonvu/babel-plugin-hoist-constant-jsx-attributes)
![Build Status](https://img.shields.io/github/workflow/status/joshwilsonvu/babel-plugin-hoist-constant-jsx-attributes/CI)
![Supported Node Version](https://img.shields.io/node/v/babel-plugin-hoist-constant-jsx-attributes)

This plugin can reduce React rerenders and garbage collection pressure by pulling
constant object attribute values (like `style={{ color: 'red' }}`) out of functions 
and into the highest possible scope. This means the objects will only get allocated once,
and they will keep the same identity across renders. 

Objects are only pulled out if they are plain old data and don't reference any 
variables, so more dynamic use cases will still work as written.

## Example

**In**

```js
const Component = () => <div style={{ color: 'red', fontSize: 14 }}>Text</div>;
```

**Out**

```js
const _style = { color: 'red', fontSize: 14 };
const Component = () => <div style={_style}>Text</div>;
```

## Install

```bash
# npm
npm i --save-dev babel-plugin-hoist-constant-jsx-attributes
# yarn
yarn add --dev babel-plugin-hoist-constant-jsx-attributes
```
```json
{
  "plugins": [
    ["babel-plugin-hoist-constant-jsx-attributes", { /* options (see below) */ }]
  ]
}
```

## Options

### `include`

`RegExp`, or `string` to be matched with [`micromatch`](https://github.com/micromatch/micromatch)

Only hoist attribute values if the *element* name matches.

### `exclude`

`RegExp`, or `string` to be matched with [`micromatch`](https://github.com/micromatch/micromatch)

Only hoist attributes values if the *element* name does not match.

### `includeAttributes`

`RegExp`, or `string` to be matched with [`micromatch`](https://github.com/micromatch/micromatch)

Only hoist attribute values if the *attribute* name matches.

### `excludeAttributes`

`RegExp`, or `string` to be matched with [`micromatch`](https://github.com/micromatch/micromatch)

Only hoist attributes values if the *attribute* name does not match.

### `lowerCaseOnly`

`boolean`, defaults to `false`

Only hoist object attribute values on primitive elements like `div` and `button`.

### `alwaysHoist`

`boolean`, defaults to `false`

By default, this plugin only hoists attribute values if the JSX element is contained
in a function or method. This is not recommended, since otherwise the problems this
plugin solves don't occur. Setting this option to `true` will hoist even if the JSX
element is at the top level.

### `freezeObjects`

`false`, `'development'`, or `'always'`, defaults to `false`.

If set to `'development'`, check at runtime to see if `process.env.NODE_ENV === 'development'`,
and if so deeply freeze hoisted objects. If set to `'always'`, deeply
freeze hoisted objects unconditionally.

Use this option for extra safety if you want to ensure that the attribute values 
are never mutated. If there is an attempt to mutate a hoisted attribute value, an
exception will be thrown. Slightly increases the compiled code size.

## Note

The React team considers this transformation unsafe to run by default, because it 
*is* possible to rely on object attribute values to have different identities every 
render. See [this GitHub issue](https://github.com/facebook/react/issues/3226) 
for more information. 

*However*, the vast majority of cases will benefit from this transformation. The
main reason they consider it unsafe is precisely because it can reduce the number
of times a component rerenders, which is likely to be what you want. Unless you were
to intentionally tinker with object referential equality, or mutate received `props`
—and you would know if you were—this transformation will be safe.

Still, to be extra careful, you can set the `lowerCaseOnly` plugin option to `true`.
You can also set the `freezeObjects` plugin option to `'development'` or `'always'`
to receive an error if a component tries to mutate its `props`.

---
_Source: https://npm.io/package/babel-plugin-hoist-constant-jsx-attributes · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
