• Stars
    star
    806
  • Rank 54,474 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A plugin for transpiling pug templates to jsx

babel-plugin-transform-react-pug

Use Pug templates to write react components.

npm version Build Status Codecov

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 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 const ReactComponent = props => (
  <div className="wrapper">
    {props.shouldShowGreeting ? (
      <p className="greeting">Hello World!</p>
    ) : null}
    <button onClick={props.notify}>Click Me</button>
  </div>
)

Usage

Syntax

Full information of the syntax you can find in official documentation: pugjs.org.

Basic example

const Component = props => pug`          //- const Component = props => (
  div                                    //-   <div>
    if props.amount > MAX_AMOUNT         //-     {props.amount > MAX_AMOUNT ? (
      OtherComponent(fluid crucial)      //-       <OtherComponent fluid={true} crucial={true} />
    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>
                                         //- )
`;

How to pass functions and other primitives

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={true}
      data-array=[1, 2, 3]               //-       data-array={[1, 2, 3]}
    )                                    //-     />
                                         //-   </div>
                                         //- )
`;

Define local variables and use javascript in attributes

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>
                                         //- )
`;

Interpolation

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}`)}
`;

Eslint integration

Install eslint-plugin-react-pug if you use eslint-plugin-react.

CSS Modules

Whether you use babel plugin to turn on CSS Modules specifically for JSX (e.g. babel-plugin-react-css-modules) or use webpack loader for that to transform styles into key-value object, it's possible to use it with pug.

  • With babel-plugin-react-css-modules you need to set classAttribute option to styleName value and that's it.

    {
      "plugins": [
        ["transform-react-pug", {
          "classAttribute": "styleName"
        }]
      ]
    }
    
    import './styles.css' // .hello{color:red}
    
    const withCorrectStyles = pug`
      div.hello I am a red text
    `
  • With webpack loader or other approaches which transform styles into object

    import classes from './styles.css' // .hello{color:green}
    
    const withCorrectStyles = pug`
      div(className=classes.hello) I am a green text
    `

    The developer experience can be improved here by setting classAttribute option to styleName value and adding babel-plugin-transform-jsx-css-modules

    {
      "plugins": [
        ["transform-react-pug", {
          "classAttribute": "styleName"
        }],
        "transform-jsx-css-modules"
      ]
    }
    
    import './styles.css' // .hello{color:green}
    
    const withCorrectStyles = pug`
      div.hello I am a green text
    `

Install

  1. Install via yarn or npm

    yarn add --dev babel-plugin-transform-react-pug
    
    npm install --save-dev babel-plugin-transform-react-pug
    
  2. Add to babel configuration before transpiling jsx (usually in .babelrc)

    {
      "plugins": [
        "transform-react-pug",
        "transform-react-jsx"
      ]
    }
    
  3. Now all your templates written with pug are understood by react and browsers.

Configuration

Name Type Default Description
classAttribute String className Attribute name which considered by PUG as "class"

classAttribute

Default:

pug`p.one`

=>
<p className="one" />

With "styleName" as value:

pug`p.one`

=>
<p styleName="one" />

create-react-app

Integrating with create-react-app is tricky because it does not allow you to modify babel configuration. There are two documented possibilities:

  • eject

    That is easy, you will get .babelrc file in your root directory, just add transform-react-pug before transform-react-jsx there.

  • react-app-rewired

    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;
      }

React Native

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.

How it works

Coming soon...

Limitations

  • 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"]
        }]
      ]
    }
    
  • We don't support html language in pug templates. This is different than what Pug promises.

    However, you can still use tag interpolation:

    p Good #[strong Morning]

FAQ

Can I import template from other files?

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).

How to get syntax highlighting in IDE (or text editors)?

WebStorm

  1. Open settings

  2. "Editor" -> "Language Injections"

  3. Click on Add new "Generic Js" injection

    See how to find this section (youtrack.jetbrains.com/issue/WEB-22106#focus=streamItem-27-2451611-0-0)

    • 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")
  4. Click "OK" and "Apply"

Atom

  1. 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.

  2. Open settings of language-babel in atom

  3. Find the field under "JavaScript Tagged Template Literal Grammar Extensions"

  4. Enter: pug:source.pug

    More details: gandm/language-babel#javascript-tagged-template-literal-grammar-extensions

  5. Restart the atom

Visual Studio Code

  1. Open settings of extensions

  2. Search "vscode-react-pug" by the search field

  3. Click "Install" and "Reload"

  4. If you use any grammar other than default one (e.g. Babel JavaScript which is quite popular), you might need to add supporting of Atom's Grammar (Microsoft/vscode-js-atom-grammar).

    Check out the history beyond that: kaminaly/vscode-react-pug#4.

License

MIT

More Repositories

1

pug

Pug – robust, elegant, feature rich template engine for Node.js
JavaScript
21,482
star
2

react-jade

DEPRECATED, see
JavaScript
552
star
3

pug-loader

Pug loader module for Webpack
JavaScript
425
star
4

pug-cli

Pug's CLI interface
JavaScript
255
star
5

pug-lint

An unopinionated and configurable linter and style checker for Pug
JavaScript
227
star
6

babel-walk

Lightweight Babylon AST traversal tools.
TypeScript
44
star
7

then-pug

**EXPERIMENTAL** Async promise based Jade
JavaScript
42
star
8

pug-lexer

The pug lexer (converts a string into an array of tokens)
JavaScript
41
star
9

pug-zh-cn

The Simplified Chinese documentation for Pug.
32
star
10

with

Compile time `with` for strict mode JavaScript
TypeScript
28
star
11

pug-parser

JavaScript
26
star
12

void-elements

Object of "void elements" as defined by the WHATWG HTML Standard.
JavaScript
24
star
13

js-stringify

Stringify an object so it can be safely inlined in JavaScript code
JavaScript
19
star
14

constantinople

Determine whether a JavaScript expression evaluates to a constant (using Acorn)
TypeScript
18
star
15

pug-www

The website for Pug.
CSS
14
star
16

pug-en

The English documentation for Pug.
13
star
17

token-stream

Take an array of token and produce a more useful API to give to a parser
JavaScript
11
star
18

pug-logo

Pug logo and branding materials
10
star
19

pug-walk

10
star
20

doctypes

Shorthands for commonly used doctypes
JavaScript
10
star
21

pug-runtime

The runtime for the Pug compiler
JavaScript
10
star
22

pug-ast-spec

Specification of the Pug AST
10
star
23

is-expression

Validates a string as a JavaScript expression
JavaScript
9
star
24

pug-code-gen

7
star
25

babel-plugin-transform-with

Babel plugin to convert "with" statements into strict mode-compatible JavaScript.
JavaScript
7
star
26

pug-source-gen

Generate Pug source from a Pug AST.
JavaScript
6
star
27

pug-filters

6
star
28

pug-load

The Pug loader is responsible for loading the dependencies of a given Pug file.
JavaScript
5
star
29

pug-plugin-dynamic-include

WIP, UNPUBLISHED. Pug plugin adding support for dynamic inclusion.
JavaScript
4
star
30

pug-attrs

3
star
31

pug-linker

2
star
32

pug-plugin-debug-line

WIP, UNPUBLISHED. Add location information to all tags.
JavaScript
2
star
33

brjade

Inline jade templates when browserifying
JavaScript
2
star
34

pug-fr

French documentation for Pug
1
star
35

pug-lint-config-migration-v2

pug-lint configuration to help migrate projects to Pug 2.0.0.
JavaScript
1
star
36

pug-error

Standard error objects for pug
JavaScript
1
star
37

pug-strip-comments

1
star