babel-helper-decorate-react

Babel Helper for custom decorator for React Component

Usage no npm install needed!

<script type="module">
  import babelHelperDecorateReact from 'https://cdn.skypack.dev/babel-helper-decorate-react';
</script>

README

babel-helper-decorate-react

Build status Test coverage NPM version NPM Downloads Prettier Conventional Commits

Babel Helper for custom decorator for React Component

Input

export const Button = () => {
  return <button>button</button>
}

// decorate-enable-next-line { "argument": 123 }
export default class ButtonDefault extends React.Component {
  // ...
}

// decorate-disable-next-line
export class Button2 extends React.Component {
  // ...
}

Output

import hoc from '/your/hoc/path'

export const Button = hoc()(() => {
  return <button>button</button>
})

// decorate-enable-next-line { "argument": 123 }
export default
@hoc({ argument: 123 })
class ButtonDefault extends React.Component {
  // ...
}

// decorate-disable-next-line
export class Button2 extends React.Component {
  // ...
}

Why?

It's useful for decorate react component for react component, like use mobx-react observer.

babelConfig

{
  plugins: [
  +  'babel-helper-decorate-react/mobx'
  ]
}

babel-helper-decorate-react/mobx/decorate

const mobx = require('mobx-react')

module.exports = () => {
  return (Component) => {
    return mobx.observer(Component)
  }
}

Input

export const Button = () => {
  return <button>button</button>
}

/* mobx-observer-disable */
export const ButtonDisable = () => {
  return <button>button</button>
}
/* mobx-observer-enable */

export default class ButtonDefault extends React.Component {
  // ...
}

Output

import decorate from 'babel-helper-decorate-react/mobx/decorate'

// To be observer component
export const Button = decorate()(() => {
  return <button>button</button>
})

export const ButtonDisable = () => {
  return <button>button</button>
}

// To be observer component
export default
@decorate()
class ButtonDefault extends React.Component {
  // ...
}

Installation

npm install babel-helper-decorate-react
# or use yarn
yarn add babel-helper-decorate-react

Usage

import babel from '@babel/core'
import createDecorateReactVisitor from 'babel-helper-decorate-react'

babel.transform(code, {
  plugins: [
    {
      visitor: createDecorateReactVisitor({
        // ...opts
      })
    }
  ]
})

API

createDecorateReactVisitor(options?)

Options

extends createDecorateVisitor#Options

detectClassComponent

Should detect react class component?

  • Type: boolean
  • Default: true
detectFunctionComponent

Should detect react function component?

  • Type: boolean
  • Default: true
reactClassMemberTokens

The MemberExpression or Identifier tokens for Detecting React class component

  • Type: string[]
  • Default: ['React.Profiler', 'React.Suspense', 'React.StrictMode', 'React.Fragment', 'Profiler', 'Suspense', 'StrictMode', 'Fragment']
reactClassSuperTokens

The super class tokens for Detecting React class component

  • Type: string[]
  • Default: ['React.Component', 'React.PureComponent', 'Component', 'PureComponent']
reactClassCallTokens

The CallExpression tokens for Detecting React class component

  • Type: string[]
  • Default: ['React.createRef', 'React.createFactory', 'React.createElement', 'React.cloneElement', 'createRef', 'createFactory', 'createElement', 'cloneElement']
reactClassMethodsTokens

The ClassMethod tokens for Detecting React class component

  • Type: string[]
  • Default: ['componentDidUpdate', 'componentDidCatch', 'componentDidMount', 'componentWillMount', 'componentWillReceiveProps', 'componentWillUnmount', 'componentWillUpdate', 'UNSAFE_componentWillMount', 'UNSAFE_componentWillReceiveProps', 'UNSAFE_componentWillUpdate', 'getSnapshotBeforeUpdate', 'shouldComponentUpdate', 'render']
reactFunctionCallTokens

The ClassMethod tokens for Detecting React function component

  • Type: string[]
  • Default: ['React.createRef', 'React.createFactory', 'React.createElement', 'React.cloneElement', 'createRef', 'createFactory', 'createElement', 'cloneElement', 'React.useCallback', 'React.useEffect', 'React.useMemo', 'React.useImperativeHandle', 'React.useLayoutEffect', 'React.useReducer', 'React.useContext', 'React.useState', 'React.useDebugValue', 'React.useRef', 'useCallback', 'useEffect', 'useMemo', 'useImperativeHandle', 'useLayoutEffect', 'useReducer', 'useContext', 'useState', 'useDebugValue', 'useRef']

createDecorateVisitor

Options

prefix

Comment prefix for enable or disable decoration like eslint comment

/* decorate-disable */
/* decorate-enable */

// decorate-disable-next-line
// decorate-disable-line

// decorate-enable-next-line
// decorate-enable-line
  • Type: string
  • Default: 'decorate'
decorateLibPath

The Path of decoration library.

  • Type: string
  • Default: null
moduleInteropPath

You may not use it.

  • Type: string | null
  • Default: require.resolve('module-interop')
defaultEnable

The decoration's status by default

you can use // decorate-enable-next-line to enable when is disabled by default

  • Type: boolean
  • Default: true
detectScopeDepth

The visitorType matched scope depth.
-1 means allow any depth.

const Button = () => {
  // scope depth: 2
  const Inner = () => <button>inner</button>

  // scope depth: 1
  return <button>123</button>
}
  • Type: number
  • Default: -1

Contributing

  • Fork it!
  • Create your new branch:
    git checkout -b feature-new or git checkout -b fix-which-bug
  • Start your magic work now
  • Make sure npm test passes
  • Commit your changes:
    git commit -am 'feat: some description (close #123)' or git commit -am 'fix: some description (fix #123)'
  • Push to the branch: git push
  • Submit a pull request :)

Authors

This library is written and maintained by imcuttle, imcuttle@163.com.

License

MIT - imcuttle 🐟