Preact: General JSX Transformer

Created on 6 Jun 2016  路  13Comments  路  Source: preactjs/preact

Great project! I made a general JSX transformer, babel-plugin-transform-jsx if you are interested in recommending that and avoiding /* @jsx h */ comments and even repetitive imports.

documentation feedback needed question

Most helpful comment

I just had a PR merged into webpack to eliminate that extra file
https://github.com/webpack/webpack/pull/3597

So in the next webpack release you can just do:

new ProvidePlugin({
  jsx: ['preact', 'h']
})

All 13 comments

Nice work. Any chance you'd be interested in making the property names configurable? Preact VNodes use nodeName instead of elementName to match the DOM's API, but otherwise everything else would be identical. That would mean people could use the plugin without modification to their code:

{
  "plugins": [
    ["transform-jsx", { "function": "h", "useVariables": true }]
  ]
}

Or another thought - provide a "to hyperscript" option. Preact's h() is intentionally identical to the hyperscript spec in order to be interoperable. That way people could use babel-plugin-transform-jsx with preact, vhtml and hyperscript right out of the box! Perhaps that warrants a wrapper plugin, I'm not sure. Curious to hear your thoughts - I would love to encourage everyone to understand the relationship between JSX and hyperscript a bit better, this could be a neat way to promote that.

@calebmer

I do this in webpack:

Babel loader:

{
  loader: 'babel',
  test: /\.jsx?$/,
  exclude: /node_modules/,
  query: {
    cacheDirectory: true,
    presets: ['es2015'],
    plugins: [
      'transform-class-properties',
      ['transform-react-jsx', {
        pragma: 'jsx'
      }]
    ]
  }
}

Provide plugin:

new ProvidePlugin({
  jsx: resolve('src/jsx.js'),
})

and jsx.js:

const preact = require('preact');
module.exports = preact.h;

This way I don't need to define any pragma nor import Preact everytime when I need to use JSX. Probably makes sense to provide Component this way too.

Nice! Might steal that.

would be nice if you could inline that somehow, not requiring the extra file

but I don't think my IDE or ESLint would agree with providing Component that way

also is the resolve an alias for require.resolve?

I just had a PR merged into webpack to eliminate that extra file
https://github.com/webpack/webpack/pull/3597

So in the next webpack release you can just do:

new ProvidePlugin({
  jsx: ['preact', 'h']
})

@gdub22 very nice

would be nice if you could inline that somehow, not requiring the extra file

It can be this way right now:

new ProvidePlugin({
  preact: 'preact'
})
{
  loader: 'babel',
  test: /\.jsx?$/,
  exclude: /node_modules/,
  query: {
    cacheDirectory: true,
    presets: ['es2015'],
    plugins: [
      'transform-class-properties',
      ['transform-react-jsx', {
        pragma: 'preact.h'
      }]
    ]
  }
}

I just had a PR merged into webpack to eliminate that extra file

That's great!

But anyway, I'm totally fine with an additional file since it doesn't harm anything for me.

@developit

Nice! Might steal that.

Take it! Take it! 馃槃

but I don't think my IDE or ESLint would agree with providing Component that way

It was just a thought though, but I think such things are customizable in many tools. In my projects I use subclass of preact's Component so I almost never import preact directly. That's why I made that thing with ProvidePlugin. But I still do import Component from 'modules/Component' everywhere which I think I should also add to ProvidePlugin.

also is the resolve an alias for require.resolve?

It's path.resolve.

well, yeah, I'm currently using the imports-loader

['transform-react-jsx', { pragma: 'preact.h' }]
{
  test  : /\.jsx$/,
  loader: 'imports-loader',
  query : {
    preact: 'preact',
  },
}

but just h will be nice with the next version of webpack

and with the provide plugin I feel like this loader is kinda unnecessary

I think we can close this out now - there are 3 or 4 great solutions including the original posted here :)

Just to leave it here.
I used this to make it work:

{ "pragma": "require('preact').h" }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcosguti picture marcosguti  路  3Comments

youngwind picture youngwind  路  3Comments

philipwalton picture philipwalton  路  3Comments

k15a picture k15a  路  3Comments

adriaanwm picture adriaanwm  路  3Comments