jsx-xml
v0.3.0
Published
Generate xml string from jsx
Downloads
1,436
Readme
jsx-xml
Generate xml string from jsx
Install
npm install jsx-xml
# or
yarn add jsx-xml
# or
pnpm add jsx-xml
Usage
import { render } from 'jsx-xml';
import { expect } from 'vitest';
let xml = render(<test />).end({ headless: true });
expect(xml).toBe(`<test/>`);
API
render(jsx, options): XMLBuilder
jsx
: JSX.Elementoptions
: XMLBuilderCreateOptions
The render
function returns an instance of XMLBuilder. You can call the end to get the XML string.
Components
You can define your own components by defining a function that returns a JSX.Element. Component name should start with a capital letter.
import { render } from 'jsx-xml';
function MyComponent(props) {
return <test>{props.children}</test>;
}
let xml = render(<MyComponent />).end({ headless: true });
Built-in Components
CData
import { CData } from 'jsx-xml';
const value = 1;
let xml = render(
<test>
<CData>some text and {value}</CData>
</test>,
).end({ headless: true });
expect(xml).toBe(`<test><![CDATA[some text and 1]]></test>`);
Comment
import { Comment } from 'jsx-xml';
let xml = render(
<test>
<Comment>some comment</Comment>
</test>,
).end({ headless: true });
expect(xml).toBe(`<test><!--some comment--></test>`);
Ins
import { Ins } from 'jsx-xml';
let xml = render(
<test>
<Ins target="target"></Ins>
<Ins target="other" content="value"></Ins>
</test>,
).end({ headless: true });
expect(xml).toBe(`<test><?target?><?other value?></test>`);
Fragment
import { Fragment } from 'jsx-xml';
let xml = render(
<root>
<Fragment>
<test />
<test />
</Fragment>
</root>,
).end({ headless: true });
expect(xml).toBe(`<root><test/><test/></root>`);
JSX Transformations
The jsx-xml supports multiple jsx transformations:
- React element
- automatic jsx transformation
- classic jsx transformation
React Element
jsx-xml render function accepts any React element as jsx argument. It helps you to use the jsx-xml in React projects without extra config.
Pros:
- No extra config is required
- it can be used jsx-xml and React in the same file
Cons:
- Order of the
key
andref
attrs is not preserved
let xml = render(<test before="1" ref="2" key="3" after="4" />).end({
headless: true,
});
console.log(xml); // <test key="3" ref="2" before="1" after="4"/>
- It is not possible to have the
children
attribute
let xml2 = render(<test children="attr">child</test>).end({ headless: true });
console.log(xml2); // <test>child</test>
- It logs some warnings in the console that do not apply to jsx-xml
const props = { key: '1', other: 'value' };
const xml = render(<test {...props} />).end({ headless: true });
// Warning: A props object containing a "key" prop is being spread into JSX:
Automatic JSX Transformation
jsx-xml provides automatic jsx transformation. It can be configured in the vite or esbuild config.
To config the whole files in the project:
export default defineConfig({
esbuild: {
jsxImportSource: 'jsx-xml',
},
});
Or to config a specific file:
// @jsxImportSource jsx-xml
Pros:
- No unrelated warnings in the console
Cons:
- it can not be used jsx-xml and React in the same file
- it needs per file config
- it is not possible to have the
children
attribute - order of the
key
attr is not preserved
let xml = render(<test before="1" ref="2" key="3" after="4" />).end({
headless: true,
});
console.log(xml); // <test key="3" before="1" ref="2" after="4"/>
Classic JSX Transformation
jsx-xml provides classic jsx transformation. It can be configured in the vite or esbuild config.
To config the whole files in the project:
export default defineConfig({
esbuild: {
jsx: 'transform',
jsxFactory: 'h',
jsxFragment: 'Fragment',
},
});
Or to config a specific file:
// @jsxRuntime classic
// @jsxFrag Fragment
// @jsx h
import { h, Fragment } from 'jsx-xml';
Pros:
- Preserve the order of the
key
andref
attrs
let xml = render(<test before="1" ref="2" key="3" after="4" />).end({
headless: true,
});
console.log(xml); // <test before="1" ref="2" key="3" after="4"/>
- It is possible to have the
children
attribute
let xml = render(<test children="attr">child</test>).end({ headless: true });
console.log(xml); // <test children="attr">child</test>
Cons:
- It can not be used jsx-xml and React in the same file
- It needs per file config
How to choose the transformation
- If your project is not a React project, it is better to use the classic jsx transformation.
- If your project is a React project, it is better to split the jsx-xml and React code into different files and use the classic jsx transformation for jsx-xml files.
- If your project is a React project, you can use the React element transformation. if you need
key
,ref
orchildren
attribute, you can use the classic jsx transformation per file.