Use Pug templates to write react components.
babel-plugin-transform-react-pug
is a plugin for babel which transpiles pug syntax within template literals to jsx.
Write your components this way:
export default const ReactComponent = props => pug`
.wrapper
if props.shouldShowGreeting
p.greeting Hello World!
button(onClick=props.notify) Click Me
`
And it will be transpiled into:
export default const ReactComponent = props => (
<div className="wrapper">
{props.shouldShowGreeting && (
<p className="greeting">Hello World</p>
)}
<button onClick={props.notify}>Click Me</button>
</div>
)
Full information of the syntax you can find in official documentation: pugjs.org.
const Component = props => pug` //- const Component = props => (
div //- <div>
if props.amount > MAX_AMOUNT //- {props.amount > MAX_AMOUNT ? (
OtherComponent(fluid crucial) //- <OtherComponent fluid crucial />
else //- ) : (
p You can set bigger amount ;) //- <p>You can set bigger amount ;)</p>
//- )}
each item, index in props.items //- {props.items.map((item, index) => (
div(key=item.id) //- <div key={item.id}>
h3 Header #{index + 1} //- <h3>Header {index + 1}</h3>
= item.body //- {item.body}
//- </div>
//- )}
//- </div>
//- )
`;
const Component = props => pug` //- const Component = props => (
div //- <div>
button( //- <button
type="button" //- type="button"
onClick=props.onClick //- onClick={props.onClick}
) Click Me //- >Click Me</button>
//-
OtherComponent( //- <OtherComponent
...props.objectWithPropsForChild //- {...props.objectWithPropsForChild}
fluid //- fluid
data-array=[1, 2, 3] //- data-array={[1, 2, 3]}
) //- />
//- </div>
//- )
`;
const Component = props => pug` //- const Component = props => (
Fragment //- <Fragment>
button( //- <button
...one //- {...one}
...two //- {...two}
onClick=() => alert('Hello') //- onClick={() => alert('Hello')}
text='number ' + 10 //- text={'number ' + 10}
condition=foo === bar ? foo : bar //- condition={foo === bar ? foo : bar}
) //- ></button>
//-
- const variable = format(props.no) //-
p Variable is #{variable} //- <p>Variable is {format(props.no)}</p>
//- </Fragment>
//- )
`;
If you'd prefer to use interpolation, you can. This is possible by using ${}
within your template.
const Component = props => pug`
ul(className=${props.modifier})
${props.items.map((item, index) => pug`li(key=${index}) ${item}`)}
`;
Install eslint-plugin-react-pug if you use eslint-plugin-react.
It's not supported well yet.
-
Install via yarn or npm
yarn add --dev babel-plugin-transform-react-pug
npm install --save-dev babel-plugin-transform-react-pug
-
Add to babel configuration before transpiling jsx (usually in
.babelrc
){ "plugins": [ "transform-react-pug", "transform-react-jsx" ] }
-
Now all your templates written with pug are understood by react and browsers.
Integrating with create-react-app is tricky because it does not allow you to modify babel configuration. There are two documented possibilities:
-
That is easy, you will get
.babelrc
file in your root directory, just addtransform-react-pug
beforetransform-react-jsx
there. -
Go through official instruction to rewire your application. Then modify your
config-overrides.js
:+ const {injectBabelPlugin} = require('react-app-rewired'); module.exports = function override(config, env) { - //do stuff with the webpack config... + config = injectBabelPlugin('transform-react-pug', config); return config; }
Just add this plugin to the list in .babelrc
file.
{
- "presets": ["react-native"]
+ "presets": ["react-native"],
+ "plugins": ["transform-react-pug"]
}
We don't need transform-react-jsx
here because it's coming with react-native
preset.
Coming soon...
-
We can't use dots in component names because pugjs treats everything after dot as a className. For example,
React.Fragment
becomes<React className="Fragment" />
, not<React.Fragment />
A nice workaround is made by babel-plugin-transform-jsx-classname-components. Just add it to
.babelrc
:{ "plugins": [ ["transform-jsx-classname-components", { "objects": ["React"] }] ] }
The short answer is no and we are not going to implement that in near future. Take a look at initial request with small explanation (#15).
-
Open settings
-
"Editor" -> "Language Injections"
-
Click on Add new "Generic Js" injection
- Name:
Pug In Template Literals (JavaScript)
- ID:
Vue (Vue.js template)
(current version of pug plugin is created in HTML scope, so we use workaround here) - Prefix:
<template lang="pug">
- Suffix:
</template>
- Places Patterns:
+ taggedString("pug")
- Name:
-
Click "OK" and "Apply"
-
Install language-babel and language-pug-jade
I suggest language-pug-jade because it works better for me. But there are more approaches for building pugjs grammar: language-pug and atom-pug, and you can try them too.
-
Open settings of language-babel in atom
-
Find the field under "JavaScript Tagged Template Literal Grammar Extensions"
-
Enter:
pug:source.pug
More details: gandm/language-babel#javascript-tagged-template-literal-grammar-extensions
-
Restart the atom
- Open settings of extensions
- Search "vscode-react-pug" by the search field
- Click "Install" and "Reload"
MIT