babel-helper-decorate-react
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
detectComponentName
Should detect react component name?
App
is valid, app
is invalid.
-
Type:
boolean
-
Default:
true
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
wrapFunctionComponentDecorateTokens
should wrap function component decorator
// Input
const Button = forwardRef(() => {
// scope depth: 1
return <button>123</button>
})
// Output
const Button = decorate()(
forwardRef(() => {
// scope depth: 1
return <button>123</button>
})
)
-
Type:
string[]
-
Default:
['forwardRef', 'React.forwardRef']
Contributing
- Fork it!
- Create your new branch:
git checkout -b feature-new
orgit 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)'
orgit 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