JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1183
  • Score
    100M100P100Q103482F
  • License MIT

Turn JSX into static objects.

Package Exports

  • babel-plugin-transform-jsx

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (babel-plugin-transform-jsx) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

babel-plugin-transform-jsx

What most people don‘t remember about JSX, which Facebook popularized with React, is that JSX is an open standard. JSX is not exclusive to React and should be experimented with by other framework authors. This Babel plugin aims to provide the most general and un-opionated transformation of JSX as possible.

This plugin accomplishes this by eliminating the need for middleman functions and outputs plain JavaScript objects, which may then be mapped over to the appropriate format. For example, refer to the following JSX (from the spec):

var dropdown = (
  <Dropdown>
    A dropdown list
    <Menu>
      <MenuItem>Do Something</MenuItem>
      <MenuItem>Do Something Fun!</MenuItem>
      <MenuItem>Do Something Else</MenuItem>
    </Menu>
  </Dropdown>
);

This will roughly be transformed into the following JavaScript object:

var dropdown = {
  elementName: 'Dropdown',
  attributes: {},
  children: [
    'A dropdown list',
    {
      elementName: 'Menu',
      attributes: {},
      children: [
        {
          elementName: 'MenuItem',
          attributes: {},
          children: ['Do Something']
        },
        {
          elementName: 'MenuItem',
          attributes: {},
          children: ['Do Something Fun!']
        },
        {
          elementName: 'MenuItem',
          attributes: {},
          children: ['Do Something Else']
        }
      ]
    }
  ]
};

No JSX pragma needed and no /* @jsx */ comments needed (although constructor functions are supported).

A JSX Object

The names of properties in a JSX object are taken directly from the spec. What the spec may call JSXElementName, in an object it is called elementName and so on. Currently properties to be expected are:

  • elementName: A string specifying the JSX element’s name. Most often a string, but might be a variable if it is considered a valid expression by the JSX spec.
  • attributes: An object of key/value attributes for the JSX object. Supports spread attributes.
  • children: An array of various variables. Most often it will contain strings and JSX objects. If the JSX element was self closing this property will be null.

Options

This plugin accepts options in the standard babel fashion, such as the following:

  • module: The module to be imported and default export used to construct JSX objects.
  • function: The function name to be used for constructing JSX objects.
  • useNew: Instead of calling a constructor function (as defined using an earlier option) use new.

Examples

Basic

JSX

var object = (
  <article>
    <h1>Hello, kitten!</h1>
    <img href="http://placekitten.com/200/300" alt="A cute kitten"/>
    It is soooo cute.
  </article>
)

JavaScript

var object = {
  elementName: 'article',
  attributes: {},
  children: [
    {
      elementName: 'h1',
      attributes: {},
      children: ['Hello, kitten!']
    },
    {
      elementName: 'img',
      attributes: {
        href: 'http://placekitten.com/200/300',
        alt: 'A cute kitten'
      },
      children: null
    },
    'It is soooo cute.'
  ]
}

Spread

If you want a JSX element to get a lot of properties, a spread attribute is an easy and convenient way to accomplish this. Just use ... with an object with all the key/value pairs you want to pass on as attributes.

JSX

var foo = {
  bar: 1,
  buz: 2
}

var object = <div hello="world" {...foo} goodbye="moon">Nice!</div>

JavaScript

var foo = {
  bar: 1,
  buz: 2
}

var object = {
  elementName: 'div',
  attributes: assign({
    hello: 'world'
  }, foo, {
    goodbye: 'moon'
  }),
  children: ['Nice!']
}

Self Closing

Self closing JSX elements work just like self closing HTML elements. As they have no children, the children array will be null.

JSX

var object = <br/>

JavaScript

var object = {
  elementName: 'br',
  attributes: {},
  children: null
}

Constructor Function

If you want your JSX object to have a constructor function use Babel options to specify a function name.

Options

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

JSX

var object = (
  <p>
    <strong>Hello,</strong> world!
  </p>
)

JavaScript

var object = jsx({
  elementName: 'p',
  attributes: {},
  children: [
    jsx({
      elementName: 'string',
      attributes: {},
      children: ['Hello,']
    }),
    ' world!'
  ]
})

Constructor Module

Sometimes it is annoying to have to import your constructor function in every file, so this plugin provides a way to automagically import your constructor function.

A couple things to consider: First, instead of using the NodeJS only require function this plugin adds an ES2015 module import declaration. So in a import … from '…' format. Therefore, you will also need a transformation plugin for this style of import if your platform does not support it.

Second, this plugin uses the default export. If you are using CommonJS module.exports you should be fine as long as the constructor is the value of module.exports.

Options

{
  "plugins": [["transform-jsx", { "module": "jsx-module-thing" }]]
}

JSX

var object = (
  <p>
    <strong>Hello,</strong> world!
  </p>
)

JavaScript

import _jsx from 'jsx-module-thing'

var object = _jsx({
  elementName: 'p',
  attributes: {},
  children: [
    _jsx({
      elementName: 'string',
      attributes: {},
      children: ['Hello,']
    }),
    ' world!'
  ]
})

Differences with babel-plugin-transform-react-jsx and babel-plugin-transform-react-inline-elements

  • No more createElement or other pragma or file import required (but is supported).
  • No $$typeof or other extraneous JSX object information.
  • No props, key, ref, or other specific React lingo.
  • Does not support component element names. See more information below.

No variable element names

With the React JSX transformer one might do the following:

import MyFirstComponent from './MyFirstComponent'

function MySecondComponent() {
  return (
    <div>
      <MyFirstComponent/>
    </div>
  )
}

…where MyFirstComponent was a variable. This is not a defined behavior in the JSX spec and only a React specific feature. Therefore it is not allowed in this plugin. Instead it is recommended to just use functions, for example:

import MyFirstComponent from './MyFirstComponent'

function MySecondComponent() {
  return (
    <div>
      {MyFirstComponent()}
    </div>
  )
}

One may however use a member expression which is a defined behavior by the spec. See the following example:

var foo = {
  bar: 'div'
}

function MyComponent() {
  return (
    <div>
      <foo.bar/>
    </div>
  )
}

In the transformed object instead of having the string foo.bar for elementName, it would instead reference foo.bar the object property.

Credits

If you like this plugin, follow me, @calebmer, on Twitter. It will be great seeing you there and you can get updates of all the stuff I will be doing.

Thanks and enjoy 👍