bluewings/pug-as-jsx-loader

Unexpected token "..."

Closed this issue · 10 comments

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.

@demeshchik

pug-as-jsx-loader uses some es6 expressions.
(It appears that your current version of nodejs does not support destructuring assignment)
https://node.green/#ES2015-syntax-destructuring--declarations-with-objects

It looks like you are using an older version of nodejs.
If you use nodejs 6 or higher, it will work. but I recommend you to use the latest version as possible.

ps. I'll modify it to support lower versions of nodejs, but it will take some time.

@bluewings

Hmm.. My current version of nodejs is 8.2.1
node_version

BTW: error line is 489, that means previous destructuring assignments were resolves successfully. I noticed that this code is responsible for js autoupdate feature. Maybe this info will help.

@demeshchik

I modified the code to use Object.assjgn.
and uploaded to version 1.0.50. Please try this version and let me know.

https://github.com/bluewings/pug-as-jsx-loader/pull/18/files

@bluewings

It works now, thanks!

@bluewings
I'm sorry, I have another question, but open issue for it is unnecessary.

Can I import styles in pug file in case of importing pug file in jsx?

And if yes, can you provide a short example of this thing?

@demeshchik

I just updated the example.

Style can be used for css-loader or inline-style.
To use the css-loader, first check the webpack.config file.

{
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[local]',
},
},

Then add the following at the top of the pug file:
// @import [css or scss file] => [variable name to use]

You can use derived class names as shown below.

// @import .css => styles
.App
h3(className='{styles.custom}') styled component
h3(style='{{ color: "blue", backgroundColor: "silver" }}') inline style

.custom {
background: yellow;
}

@bluewings

Hi
Sorry for the delay.
Unfortunately, I have a strange error while importing styles directly to pug file. I'll check it later, cuz importing via JSX works fine for me.
The last question, before I'll want to close issue, how I can set 2 classes for one element?

@demeshchik

You can use more than one class for an element.
Use it as shown below.

div
  // case 1
  .btn(className='{styles.btnPrimary}')
  // case 2
  div(className='{"btn " + styles.btnPrimary}')
  // case 3: using classnames module
  div(className='{classnames("btn", styles.btnPrimary)}')
<div>
  { /* case 1 */ }
  <div className={'btn ' + (styles.btnPrimary)} />
  { /* case 2 */ }
  <div className={'btn ' + styles.btnPrimary} />
  { /* case 3: using classnames module */ }
  <div className={classnames('btn', styles.btnPrimary)} />
</div>

To use the classname module, you must pass it from a jsx file.
Alternatively, you can use the resolveVariables option in webpack config.

webpack.config.js

{
  test: /\.pug$/,
  use: [
    require.resolve('babel-loader'),
    {
      loader: require.resolve('pug-as-jsx-loader'),
      options: {
        resolveVariables: {
          // If the 'cx' variable is found in the pug file,
          // import cx from 'classnames'; will be automatically added.
          cx: 'classnames',  
        },
      },
    },
  ],
},

pug

div(className='{cx("btn", styles.btnPrimary)}')

transpiled content

import React from 'react';
import cx from 'classnames';

export default function (params = {}) {
  const { styles } = params;
  return (
    <div className={cx('btn', styles.btnPrimary)} />
  );
}

@bluewings

Thanks a lot, man! Gave you my star for a pretty good job!
I think you can close an issue.