npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

babel-plugin-jsx-simple

v1.6.0

Published

Babel plugin for simple JSX to JS transformation

Downloads

11

Readme

babel-plugin-jsx-simple CircleCI

Babel plugin for simple JSX to JS transformation.

Meant as basis for anyone looking to:

  • understand or demistify JSX
  • see what JSX is all about in it's most basic form
  • use JSX in own code with zero deps (needing this plugin in translipation step of course).
  • create new library that uses JSX (adding your own specific rules and extra transformations)

Based on babel-plugin-transform-vue-jsx by simplifying it, and removing all but basic JSX transformation.

ES6 syntax is used intentionally because current browsers are already ok with ES6 code (at the time of creation of this plugin: Edge, Chrome, FF). Additionally, tools like babel enable a simple bridge for all cases where older ES is needed. Babel easily will transpile the code for older browsers if you use preset es2015.

Can be combined with babel-plugin-jsx-inject and babel-plugin-jsx-translate

What is JSX all about(the basic idea)

You want to write code that combines HTML and JS and do it sometimes inside a JS file too.

var person = {name:'Somebody', city: 'Mordor'}

var def = <div>
  <div class="name"><b>Name: </b>{person.name}</div>
  <div class="city"><b>City: </b>{person.city}</div>
</div>

applyHtml(document.getElementById('person-data'), def);

The JSX is tranformed to function calls and then the code looks like this

var person = {name:'Somebody', city: 'Mordor'}

var def = h('div', null,
  h('div', {'class':'name'}, h('b', null, 'Name: '), person.name),
  h('div', {'class':'city'}, h('b', null, 'City: '), person.city),
)

applyHtml(document.getElementById('person-data'), def);

the function h is implemented in such way that these calls to h result in def being:

{
  "tag": "div",
  "attr": null,
  "children": [
    {
      "tag": "div",
      "attr": { "class": "name" },
      "children": [
        { "tag": "b", "attr": null,  "children": [ "Name: " ] },
        "Somebody"
      ]
    },
    {
      "tag": "div",
      "attr": { "class": "city" },
      "children": [
        { "tag": "b", "attr": null,  "children": [ "City: " ] },
        "Mordor"
      ]
    }
  ]
}

the applyHtml function is implemented to generate HTML based on data structured like that so the final result in HTML is:

<div>
  <div class="name"><b>Name: </b>Somebody</div>
  <div class="city"><b>City: </b>Mordor</div>
</div>

Example code

First exmaple in example/example.js is written on this principle, and is principally very similar to rendering in Vue and React (to simplify the code no diff is done, instead simple clear + add is used). You can find sample implementation of applyHtml and h there.

Second exmaple in example-arrow/example.js showcases how wrapping dynamic parts into arrow functions can enable dynamic changes (but with static structure) that uses JSX but with principles closer to templating approach (You create mostly static structure, where dynamic parts have special handling so they can be updated when needed).

If you run and inspect second example you will see specific parts changing inspect

These two approaches can be combined in more fine grained manner than just global flag to achieve interesting things.

Requirements

  • This is mutually exclusive with babel-plugin-transform-react-jsx and babel-plugin-transform-vue-jsx.

AST explorer

There is a very nice way to play with AST using AST explorer. And you can play with this plugin and JSX on this snippet. The code from index.js is pasted there but one line is commented out: //inherits: require('babel-plugin-syntax-jsx'),.

Ast explorer is an excellent way to inspect AST produced from original code, and test how different code (with JSX) is transformed into pure JS. This way you get a better picture of what can be done with JSX and understand the connection between what you type in the original file and what the browser will see.

You will also see from there how a plugin can transform AST to give such nice features like JSX->JS in a reliable way.

Usage

Create an empty folder with package.json containing only empty object like this:

{}

run npm install:

npm install babel-plugin-syntax-jsx babel-plugin-jsx-simple babel-preset-env --save-dev

You can skip babel-preset-env in step above and remove "presets": ["env"], in step below if you are running your code in enviroment that can execute ES6 code.

create .babelrc:

{
  "presets": ["env"],
  "plugins": ["jsx-simple"]
}
  • Make a file test.js
  • put some of example code from below in it
  • run babel test.js

The plugin transpiles the following JSX:

<div id="foo">{text}</div>

To the following JavaScript:

h('div', {
  id: 'foo'
}, text)

Note the h function, which is something that you need to provide in the scope. A simple function like this can be sufficient for many use cases:

  function h(tag, attr, ...children){
    return {tag, attr, children };
  }

Difference from JSX in React and Vuejs

React and Vue add extra transformations that allows usefull shortcuts for their own use-cases.

This plugin takes a basic principle of converting tags to function calls that can be easily converted to html nodes later. Child nodes are sent as extra parameters to he called function.

the function that will be called is h and it your responsibility to have it visible in the scope where JSX is used.

There is one simple extra transform that is done in this plugin:

  • tag names that start with uppercase are passed as identifier instead as string literal.

Tag Name Tip

If a tag name starts with lowercase, it will be treated as a string . If it starts with uppercase, it will be treated as an identifier, which allows you to do:

export default {
  render (h, state) {
    const Todo = state.numbered ? 'ol':'ul'
    return <Todo> 
      <li> first </li>
      <li> second </li>
    </Todo> 
  }
}

The transformed code will be:

export default {
  render (h, state) {
    const Todo = state.numbered ? 'ol':'ul'
    return h(Todo, null,
      h('li', null, 'first'),
      h('li', null, 'second')
    ) 
  }
}

JSX Spread

JSX spread is simply translated to javascript spread.

const data = {
  href: 'b',
  id: 'id1'
}
const vnode = <div class="a" {...data}/>

The transformed code will be:

const data = {
  href: 'b',
  id: 'id1'
}
const vnode = h('div', {class: 'a', ...data })