bluewings / pug-as-jsx-loader

MIT License
188 stars 15 forks source link

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

Closed douggr closed 5 years ago

douggr commented 5 years ago

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 */
douggr commented 5 years ago

Hacking a bit further, I think that is something wrong with preactjs-templates/default. Not sure though.

I was able to get it up and running with preactjs-templates/typescript. Since this is a new and small project, I will give it a try. BUT(!), if you have any clue about the original post, please let me know ;)

Cheers.

P.S.: Great transformer! I loved the __macro thingie :)

bluewings commented 5 years ago

@douggr I have added an example for preactjs-templates/default below. https://github.com/bluewings/pug-as-jsx-loader/tree/master/examples/preact-default

In preact.config.js, you need to set babel preset for the .pug file. and npm install babel-preset-react --save-dev https://github.com/bluewings/pug-as-jsx-loader/blob/b74ad079b8fd8c80d1ad487203c14834b1591a77/examples/preact-default/preact.config.js#L12-L26

If you are using Babel 7 or higher, try the options below

  loader: require.resolve('babel-loader'),
  options: {
    presets: ['@babel/preset-env', '@babel/preset-react'],
  },

Enjoy using the following Pug template!, Thank you! https://github.com/bluewings/pug-as-jsx-loader/tree/b74ad079b8fd8c80d1ad487203c14834b1591a77/examples/preact-default/src/routes/home