Code Monkey home page Code Monkey logo

pug-as-jsx-loader's Introduction

pug-as-jsx loader for webpack

npm version

npm badge

Installation

npm install pug-as-jsx-loader --save-dev

Usage

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.pug$/,
        use: [ 'babel-loader', 'pug-as-jsx-loader' ]
      }
    ]
  }
}

pug | jade template (./file.pug)

div
  h1 {period.start} ~ {period.end}
  ul
    li(@repeat='items as item')
      i.ico(@if='item.icon', className='{"ico-" + item.icon}')
      ItemDetail(item='{item}')

→ transpiled function

import React from 'react';

export default function (params = {}) {
  const { items, period, ItemDetail } = params;
  return (
    <div>
      <h1>
        {period.start} ~ {period.end}
      </h1>
      <ul>
        {items.map((item, i) =>
          <li key={i}>
            {(item.icon) && (
            <i className={`ico ico-${item.icon}`} />
            )}
            <ItemDetail item={item} />
          </li>
        )}
      </ul>
    </div>
  );
};

import pug template

import React from 'react';

import template from './file.pug';      // ← import pug template
import ItemDetail from './ItemDetail';

class Report extends React.Component {
  render() {
    const {
      items,
      period,
    } = this.props;

    return template.call(this, {        // ← use transpiled function
      // variables
      items,
      period,
      // components
      ItemDetail,
    });
  }
};

integration with Typescript

// react-app-env.d.ts
const React = require('react');

declare module '*.pug' {
  const template: (params?: { [key: string]: any }) => React.ReactElement;
  export = template;
}

License

MIT (http://www.opensource.org/licenses/mit-license.php)

pug-as-jsx-loader's People

Contributors

billypon avatar bluewings avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pug-as-jsx-loader's Issues

possible to use boolean shorthand?

I tried using the boolean shorthand as referenced in the Pug and React documentation, but it doesn't seem to work.

For example: react-router's exact boolean property only works if I explicitly set it to {true}.

Boolean Is Not Applied

BrowserRouter
  Nav
  Route(path="/"        component="{Home   }" exact) // 🡸
  Route(path="/about"   component="{About  }"      )
  Route(path="/contact" component="{Contact}"      )

Boolean Is Applied

BrowserRouter
  Nav
  Route(path="/"        component="{Home   }" exact="{true}") // 🡸
  Route(path="/about"   component="{About  }"               )
  Route(path="/contact" component="{Contact}"               )

how can I pass .map funciontion

Hi again,

I have one more problem. I need to pass a .map function to pug. How can I pass this code?

{
      this.state.listCards.map((data) => {
        return (
          <div className="card card-materia" key={data.id}>
            <div className="card-body">
              <div className="card-menu">
                <i className="fas fa-ellipsis-v" />
                <div className="cm-floating">
                  <a className="cmf-agenda" href="agendamento.html">
                    <i className="ti-agenda" />
                    <FormattedMessage {...messages.scheduled} />
                  </a>
                  <a className="cmf-copy" href="#">
                    <i className="pe-7s-copy-file" />
                    <FormattedMessage {...messages.copy} />
                  </a>
                  <a className="cmf-trash" href="#">
                    <i className="ti-trash" />
                    <FormattedMessage {...messages.delete} />
                  </a>
                </div>
              </div>
              <div className={`cm-icon ${data.icon}`}>
                <i />
              </div>
              <h2 className="cm-title">{data.disciplineAbbreviation}</h2>
              <span className="badge badge-warning">{data.status}</span>
              <p className="cm-questions">{data.questionNumber}</p>
              <div className="cm-info">
                <a href="#">{data.disciplineName}</a>
                <a href="#">{data.year}</a>
                <a href="#">{data.segment}</a>
              </div>
              <div className="cm-date">
                <i className="pe-7s-refresh-2" />
                {data.date}
              </div>
            </div>
        </div>
        );
      })
    }

thank you for this awesome work.

Custom filters

Hi, there is a way to use custom filters?

Example from PUG docs

options.filters = {
  'my-own-filter': function (text, options) {
    if (options.addStart) text = 'Start\n' + text;
    if (options.addEnd)   text = text + '\nEnd';
    return text;
  }
};
p
  :my-own-filter(addStart addEnd)
    Filter
    Body

It will produce

<p>
  Start
  Filter
  Body
  End
</p>

Thank you!

[question] Any idea on how to use with `preact`?

Hello! Well, this is awkward.

This is funny, because if I load the transpiled file instead, it works like a charm.

Options:

use: ['babel-loader', 'pug-as-jsx-loader?transpiledFile=true'],

Output

✖ ERROR ./src/routes/profile/index.pug
Module build failed: SyntaxError: Unexpected token (6:4)

  4 |   const { count, style, user } = __params;
  5 |   return (
> 6 |     <div class={style.profile}>
    |     ^
  7 |       <h1>Profile: {user}</h1>
  8 |       <p>This is the user profile for a user named {user}.</p>
  9 |       <p>

index.pug

div(class='{style.profile}')
  h1 Profile: {user}
  p
    button(onClick="{this.increment}") Click Me

  p Clicked {count} times.

index.js

import { h, Component } from 'preact';
import style from './style';
import template from './index.pug'; // <= error here
// import template from './index.pug.transpiled.jsx'; // here it just works

export default class Profile extends Component {
	state = {
		time: Date.now(),
		count: 0
	};

	// update the current time
	updateTime = () => {
		this.setState({ time: Date.now() });
	};

	increment = () => {
		this.setState({ count: this.state.count+1 });
	};

	// gets called when this route is navigated to
	componentDidMount() {
		// start a timer for the clock:
		this.timer = setInterval(this.updateTime, 1000);
	}

	// gets called just before navigating away from the route
	componentWillUnmount() {
		clearInterval(this.timer);
	}

	// Note: `user` comes from the URL, courtesy of our router
	render({ user }, { time, count }) {
		return template.call(this, {
			count,
			style,
			user,
		});
	}
}

Transpiled file:

import React from 'react';

export default function(__params = {}) {
  const { count, style, user } = __params;
  return (
    <div class={style.profile}>
      <h1>Profile: {user}</h1>
      <p>This is the user profile for a user named {user}.</p>
      <p>
        <button onClick={this.increment}>Click Me</button>
      </p>
      <p>Clicked {count} times.</p>
    </div>
  );
}


//  /* USAGE EXAMPLE */
//  // jsx
//  import template from './index.pug';
//  
//  class Sample extends React.Component {
//    render() {
//      const { count, style, user } = this;
//  
//      return template.call(this, {
//        // variables
//        count,
//        style,
//        user,
//      });
//    }
//  }
//  
//  /* // USAGE EXAMPLE */

Importing template from jade file

I used create-react-app to create a new react app that also uses Redux.
I imported the pug template as

import template from './help-modal.pug';

On importing the pug template, it gives a string instead of a function and fails saying that .call is not defined.
Following is the snippet for parent container :

class HelpModal extends React.Component{
  render(){
    const {
        showModal,
        closeModal
        } = this.props;
    return template.call(this, {
      showModal,
      closeModal
    });

  }
}

const mapStateToProps = ({helpModal})=> helpModal;

const mapDispatchToProps = (dispatch)=> ({
  closeModal: ()=> closeModal(dispatch)
});

I also see compile warning

  Line 1:  Definition for rule 'jsx-a11y/accessible-emoji' was not found                    jsx-a11y/accessible-emoji
  Line 1:  Definition for rule 'jsx-a11y/alt-text' was not found                            jsx-a11y/alt-text
  Line 1:  Definition for rule 'jsx-a11y/aria-activedescendant-has-tabindex' was not found  jsx-a11y/aria-activedescendant-has-tabindex
  Line 1:  Definition for rule 'jsx-a11y/iframe-has-title' was not found                    jsx-a11y/iframe-has-title
  Line 1:  Definition for rule 'jsx-a11y/no-distracting-elements' was not found             jsx-a11y/no-distracting-elements
  Line 1:  Definition for rule 'jsx-a11y/no-redundant-roles' was not found                  jsx-a11y/no-redundant-roles

support multi template functions

Now, this loader will export a default function for template rendering, like this:

// template.pug
div foo
import template from './template.pug';

export default function foo() {
  return template();
}

But can we export multi functions? like this:

// template.pug
block foo
  div bar

or

// template.pug
mixin foo()
  div bar

then we can use other functions:

import template from './template.pug';

export default function foo() {
  return template.foo();
}

codemod.js has some bugs

hi, when i run this loader, the terminal display error message:

Module build failed: /Users/xxx/works/React/react-pug/my_app/node_modules/pug-as-jsx-loader/lib/codemod.js:203 ) ^ SyntaxError: Unexpected token )

i find the codemod.js has many extra commas, when i clear there commas then webpack run successful.

Unexpected token "..."

Hi

When I try to use this loader, I get this error:

Module build failed (from ./node_modules/pug-as-jsx-loader/index.js):
F:\pug-react-example\node_modules\pug-as-jsx-loader\pug-as-jsx-loader.js:489
                ...options,
    SyntaxError: Unexpected token … 

Webpack.config.js:

module.exports = (env, argv) => {
    return [{
        stats: { modules: false },
        entry: { 'main': './src/main.jsx' },
        resolve: {
            extensions: ['.js', '.jsx']
        },
        output: {
            path: path.join(__dirname, bundleOutputDir),
            filename: 'app.js',
            publicPath: 'dist/'
        },
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    query: {
                        presets: ['env', 'react']
                    }
                },
                {
                    test: /\.pug$/,
                    use: [
                        require.resolve('babel-loader'),
                        require.resolve('pug-as-jsx-loader')
                    ]
                }
            ]
        }
    }];
};

P.S.: I thought that this error may caused by 'resolve' section of config, but removing this one gave absolutely nothing.

add option to support Mithril.js

Now I edit the source of pug-as-jsx-utils and change in the index.js line 167
result.useFragment ? "import React, { Fragment } from 'react';" : "import React from 'react';",
to
result.useFragment ? "import m, { Fragment } from 'mithril';" : "import m from 'mithril';",
it can work, but I think it's better to expose an option, like
'@babel/plugin-transform-react-jsx', {"pragma": "m"}
it's more convenient and useful. May consider.

can't import simple pug templates

Every time I tried importing simple pug templates, I get this error:


react-dom.production.min.js:4408

TypeError: h.a.call is not a function
at n.value (App.js:10)
at Oo (react-dom.production.min.js:3785)
at No (react-dom.production.min.js:3776)
at Do (react-dom.production.min.js:3960)
at Qi (react-dom.production.min.js:5514)
at Ki (react-dom.production.min.js:5536)
at Oa (react-dom.production.min.js:5958)
at Pa (react-dom.production.min.js:5925)
at Ta (react-dom.production.min.js:5860)
at Ji (react-dom.production.min.js:5787)

I don't know what the issue is, I already changed the webpack files. and I have this on my app.js;

import React from 'react';
import './App.css';
import { translate} from 'react-multi-lang'
import homeTemplate from './views/home.pug'

class App extends React.Component {

render() {

		return homeTemplate.call({}, {
		});
}

}

export default App;

How use ifs with React variables

Hi!
How to use if for some state variable from React?

aside.sidebar
    .sidebar-header
        {@if=this.state.show === true}
            .avatar-profile.mt-4
                img.avatar-image(src="{avatarProfile}", alt="")
                .avatar-country {this.state.country}
            .sidebar-name {this.state.firstName}
            NavLink.btn.btn-outline-warning.btn-sm(to="configuracoes.html")
                 FormattedMessage(__jsx='{...messages.edit}')
         {/if}

Sorry, I did't find the documentation.
Tks

Error when importing pug

I have a funny feeling it could be due to the version of webpack I am using ...

Thanks for your help.

Pug:

div
    div Hello this is a test for testing
    div this is another thing I am writing ... trying to find out what this mysterious token is

Error Message:

Module build failed: SyntaxError: Unexpected token, expected ; (2:8)
    1 | div
> 2 |     div Hello this is a test for testing
      |         ^
   3 |     div this is another thing I am writing ... trying to find out what this mysterious token is

Current Dev Dependencies:

"devDependencies": {
    "@storybook/addon-actions": "^3.0.0",
    "@storybook/react": "^3.0.0",
    "@webpack-blocks/dev-server2": "^0.4.0",
    "@webpack-blocks/webpack2": "^0.4.0",
    "babel-core": "^6.24.1",
    "babel-eslint": "^8.0.1",
    "babel-jest": "^22.1.0",
    "babel-loader": "^7.0.0",
    "babel-plugin-styled-components": "^1.1.4",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.0",
    "babel-preset-env": "^1.3.3",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-1": "^6.24.1",
    "copyfiles": "^1.0.0",
    "cross-env": "^5.0.0",
    "delay": "^2.0.0",
    "enzyme": "^3.1.0",
    "enzyme-adapter-react-16": "^1.0.1",
    "eslint": "^4.9.0",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-import-resolver-webpack": "^0.8.1",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.0.1",
    "file-loader": "^1.1.5",
    "jest-cli": "^22.1.4",
    "opn-cli": "^3.1.0",
    "pug-as-jsx-loader": "^1.0.41",
    "raw-loader": "^0.5.1",
    "react-test-renderer": "^16.0.0",
    "redux-mock-store": "^1.2.3",
    "rimraf": "^2.6.1",
    "url-loader": "^0.6.2",
    "webpack": "^3.10.0",
    "webpack-assets-by-type-plugin": "^0.1.0",
    "webpack-blocks-happypack": "^0.1.3",
    "webpack-blocks-server-source-map": "^0.2.0",
    "webpack-blocks-split-vendor": "^0.2.1",
    "webpack-child-config-plugin": "^0.1.2",
    "webpack-dev-server": "^2.3.0",
    "webpack-node-externals": "^1.5.4",
    "webpack-spawn-plugin": "^0.1.1"
  }

Using &attributes

I was wondering if there was a way to pass objects into &attributes. As this would be really useful.

Thanks

How to define handlers

Hi, i have some troubles figuring out what the suggested syntax for eventhandlers would be?

was a mixup on my side never mind :) can be closed

CSS Modules aren't "puggy"

I think you've created an awesome loader. At the very least, it gives me an excuse to enforce the separation of presentation and container components.

I really like that you added a way to do imports. It actually works for things like images really well.

For its intended use case, however, the usability could be improved.

  1. In a simple app, maybe I don't want css modules:
// @import ./button-theme.css

button.btn.btnPrimary ...
  1. It also doesn't feel right when classes usually come before attributes and I have to write:
div(className='{classnames("btn", styles.btnPrimary)}')

Perhaps it could be another macro:

// @styles ./button-theme.css

button.btn.btn-primary ...

This would need to template ${ styles['btn'] || 'btn' } ${ styles['btn-primary'] || 'btn-primary' } under the hood at runtime, right?

Default "renders without crashing" test fails

I have projects that runs without problem that uses pug-as-jsx-loader.

However when running npm test, no matter I am using cra-rewired or manually ejecting and modifying webpack config, I cannot get the default npm test passes.

TypeError: (0 , _App2.default) is not a function

       6 | class App extends Component {
       7 |   render() {
    >  8 |     return template({
         |            ^
       9 |       // variables
      10 |       logo,
      11 |     });

      at App.render (src/App.js:8:12)
      at finishClassComponent (node_modules/react-dom/cjs/react-dom.development.js:14301:31)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:14264:10)

Do we have suggested ways to do testing if we use pug-as-jsx-loader?

P.S. For the cra-rewired version, I tried cra-rewired -s react-scripts -m test -c webpack.custom.js but that seems to be an entrance to a a deeper hole.

Include CSS files directly from pug

In some cases js does not need to know about css files.

Most css files are deeply involved with pugs, and js does not need to handle css.

//- sample.pug
// @import .scss => styles
.root(className='{styles.a}')
  h1.greeting hello world!
//- sample.pug.transpiled.jsx
import React from 'react';
import styles from './sample.scss';

export default function () {
  return (
    <div className={`root ${styles.a}`}>
      <h1 className="greeting">hello world!</h1>
    </div>
  );
}

Thanks for you work

I have two questions.

  1. can i use mixins like bemto
  2. can i use inline styles in a style tag?
    image
    i also tryied this variants
style
  .lolo { background: red; }
style
  ='.lolo { background: red; }'
style
  !='.lolo { background: red; }'
style
  |'.lolo { background: red; }'

Improvement: if else in atrribute

Can we have if else in attribute. like this :
a( className=if(foo===bar) foo else bar @if=${} // also string interpolation like github.com/pugjs/babel-plugin-trans )

Also an inline if and tagged literal template would be great (like babel-plugin-transform-react-pug)

How to properly use variable with inline syntax

I can't figure out the proper syntax to render variables from my react props into the pug template syntax. I'm not using external pug files, but rather the inline pug syntax within my react .js files.

Example: my Home.js file looks something like this

import React, {component} from 'react'
import {Card, CardBody, CardTitle} from 'reactstrap'

export default class Home extends Component {
   constructor(props) {
     super(props)
     this.data = props.data
   }

    render() {
       return pug`
          Card
               CardBody
                   CardTitle '{props.data.title}'
       `
    }

}

And that works just fine, but the problem is that quotes appear around my title. So if
props.data.title = "Hello world"

then it comes out as 'Hello world' on the page.

I tried different combinations of syntax like ${props.data.title} and CardTitle= #{props.data.title}

but all of them end up with an error either by the pug-lexer or the pug-as-jsx-loader

add resolveComponents options

For some components, you do not have to pass a reference to the template from component js.

//- pug file
p
  FormattedMessage#welcome

The above pug file is converted as below and you have to pass the FormattedMessage reference value to use template function.

import React from 'react';

export default function (params = {}) {
  const { FormattedMessage } = params;
  return (
    <p>
      <FormattedMessage id="welcome" />
    </p>
  );
}

Setting resolveComponents mappings in webpack.config, you do not have to pass a reference to the component separately.

// webpack.config.js
module.exports = {
  entry: ...
  output: ...
  module: {
    rules: [
      ...
      {
        test: /\.pug$/,
        use: [
          require.resolve('babel-loader'),
          {
            loader: require.resolve('pug-as-jsx-loader'),
            options: {
              resolveComponents: {
                FormattedMessage: 'i18n/FormattedMessage',
              },
            },
          },
        ],
      },
      ...
    ],
  },
};

The import statement for the component has been added automatically.

import React from 'react';
import FormattedMessage from 'i18n/FormattedMessage';

export default function () {
  return (
    <p>
      <FormattedMessage id="welcome" />
    </p>
  );
}

Pug + react-boilerplate + i18n - custom tag

Hi,

I trying to use i18n with pug, but I always receive this error:

Uncaught (in promise) TypeError: Cannot read property 'index' of undefined

This is my code:

import React from react;
import { FormattedMessage } from react-intl;
import messages from ./messages;

import template from ./index.pug;
import ../../assets/scss/main.scss;


export default class Home extends React.PureComponent { 
  render() {
    return template.call();
  }
}

My pug file:
div h1 FormattedMessage( __jsx='{...messages.index}')

Can you help me with this?

throws error on `{props.children}`

Is there a way to make this work with {props.children} as shown in the docs?

I tried using the following pug layout:

.test-component
  {props.children}

and this error was thrown:

Uncaught Error: Module build failed (from D:/TestProject/node_modules/pug-as-jsx-loader/dist/pug-as-jsx-loader.cjs.js):
Error: D:/TestProject/src/Components/TestComponent/Layout.pug:3:5
    1| .test-component
  > 2|   {__archived_ejbuz7h__}
-----------^

unexpected text "{__ar"

How to pass a function and return ReactNode?

How to pass a function and return ReactNode?

Like this example, how to transform it to pug file?

render() {
  return (
    <MyComponent renderFunction={ data => <div>{ data }</div> } />
  );
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.