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

xml-jsx-runtime

v0.1.1

Published

A custom automatic JSX runtime that transforms JSX into xml-js's non-compact objects that can be converted into plain XML strings.

Downloads

5

Readme

xml-jsx-runtime

npm GitHub Repo stars

A custom automatic JSX runtime that transforms JSX into xml-js's non-compact objects that can be converted into plain XML strings.


Installation:

Install the runtime from npm:

npm install xml-jsx-runtime -D

You also need to install xml-js independently in order to convert your XML non-compact objects into strings:

npm install xml-jsx-runtime -S

Usage:

Method 1: with a configuration file.

Pass the following options to @babel/plugin-transform-react-jsx (or whatever JSX transformer you're using):

{
  "throwIfNamespace": false,
  "runtime": "automatic",
  "importSource": "xml-jsx-runtime/runtime"
}

Note that you might not be using @babel/plugin-transform-react-jsx directly, as it is included in other presets such as @babel/preset-react or @vitejs/plugin-react. Or you might be using esbuild's own JSX loader instead. Either way, you should figure out how to configure your JSX loader by yourself.

Method 2: with a @jsxImportSource pragma comment (recommanded).

You may add the following comment to the top of your .jsx file:

/** @jsxImportSource xml-jsx-runtime/runtime */

And the runtime will be explicitly enabled for that file (only).

This method allows you to keep using React JSX in your project, and only use xml-jsx-runtime where you need it.

You'll still need to set throwIfNamespace to false from your configuration file if you want XML namespace support. Also you should add /** @jsxRuntime automatic */ as well if it's not already set by default.

Examples & Features

Quick start:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'


const src = <book category='WEB'>
  <title lang='en'>Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

console.log(src)
/** Output:
 * XMLElement {
 *   elements: [
 *     XMLElement {
 *       type: 'element',
 *       name: 'book',
 *       attributes: [Object],
 *       elements: [Array]
 *     }
 *   ]
 * }
 */

const xml = js2xml(src) // to xml string

console.log(xml)
/** Output:
 * <book category="WEB"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book>
 */

Fragments are supported:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const xml = js2xml(
  <>
    <book id='1' />
    <book id='2' />
    <>
      <book id='3' />
      <>
        <book id='4' />
      </>
    </>
  </>
)

console.log(xml)
/** Output:
 * <book id="1"/><book id="2"/><book id="3"/><book id="4"/>
 */

Unlike React, the key attribute isn't concidered special:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const xml = js2xml(
  <>
    <elm key='1' />
    <elm key='2' {...undefined} />
    <elm {...undefined} key='3' />
  </>
)

console.log(xml)
/** Output:
 * <elm key="1"/><elm key="2"/><elm key="3"/>
 */

Note that internally the 3rd element will fallback to the lagecy createElement function instead of the jsx function. Thankfully, xml-jsx-runtime handles that case correctly. See more about this issue here.

The children attribute is reserved by JSX to pass child elements, however you may still specify it by adding the $: namespace prefix:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const xml = js2xml(
  <room adults={2} $:children={1} />
  /**
   * Or
   * <room adults={2} {...{'$:children': 1}} />
   * if you environment doesn't support XML namespaces
   */
)

console.log(xml)
/** Output:
 * <room adults="2" children="1"/>
 */

Keep in mind that the $ character is not valid as an xml namespace prefix. However, JSX supports it, so I have decided to use it as a way to bypass such limitations. It will always gets ignored in the result.

JSX always treat tags with capitalized names as value-based elements, but you still may have capitalized elements by defining a variable then assigning a string to it:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const Element = 'Element'

const xml = js2xml(
  <Element />
)

console.log(xml)
/** Output:
 * <Element />
 */

Or, you may completely avoid that pattren by adding the $: prefix 😁:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const xml = js2xml(
  <$:Element />
)

console.log(xml)
/** Output:
 * <Element />
 */

Function elements (value-based elements) are supported, just like in React:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const Element = ({ attribute } : { attribute: string }) => (
  <element attribute={attribute} />
)

const xml = js2xml(
  <Element attribute='value' />
)

console.log(xml)
/** Output:
 * <element attribute="value"/>
 */

For children, the values undefined, null, false, true will be ignored in the result. Multidimensional arrays will get flattened automatically. Passing objects that are not instances of XMLElement, or types other than string or number will cause xml-jsx-runtime to throw an error. For attributes, all values will get converted into strings, even objects:

/** @jsxImportSource xml-jsx-runtime/runtime */
import { js2xml } from 'xml-js'

const text = <text>Lorem {undefined} ipsum {null} dolor {false} sit {true} amet</text>

const xml = js2xml(
  <>
    {text}
    {[<a />, [<b />, false, 1337, [<c />]], <d attribute={{}} />]}
  </>
)

console.log(xml)
/** Output:
 * <text>Lorem  ipsum  dolor  sit  amet</text><a/><b/>1337<c/><d attribute="[object Object]"/>
 */

License

MIT © ${Mr.DJA}