
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
babel-plugin-hyperscript-to-jsx
Advanced tools
It's a quite complex codemod to migrate from hyperscript to JSX.
import h from "react-hyperscript";
import hx from "shit"
const StatelessComponent = props => h("h1");
const StatelessWithReturn = props => {
return h(".class");
};
function HyperscriptAsRegularFunction(props) {
return h("h1");
}
const HyperscriptAsVariable = h("div.lol", {
someProp: "lol"
});
const HyperscriptWithExpressionAsChildren = h(
AnotherComponent,
{ foo: "bar", bar: () => ({}), shouldRender: thing.length > 0 },
[arr.map(() => h('h1'))]
)
// Should be ignored from transforming
const FirstArgTemplateLiteralWithComputedExpressions = h(`div.lol${stuff}`, {
someProp: "lol"
});
// Not computed so should be fine
const FirstArgTemplateLiteral = h(`div.lol`, {
someProp: "lol"
});
// Should be ignored
const WhenFirstArgumentIsFunctionThatIsCalled = () => h(getLoadableAnimation('pageCareersDeliver'), [h(fn())])
const ComputedRootWithObjectPropertyDeclaration = () =>
h(
ANIMATIONS[country],
{
className: "lol",
content: h(".selectItem", [
h("div", label),
h(".flag", [
h(RoundFlag, {
mix: "flag",
size: "xs",
code: currencyData.countryCode
}),
// Computed not root should be wrapped in {}
h(ANIMATIONS[country], { className: "lol" })
])
])
},
[h(ANIMATIONS[country], { className: "lol" }), h("h1"), kek && mem, surreal ? lol : kek, t.tabName, lol, <div/>]
);
const ThirdArgOnIgnoredIsNotArray = () =>
h(
ANIMATIONS[country],
{
className: "lol",
},
// This first children in array will be ignored FOR THIS UGLY HACK IN INDEX
children
);
h(isCanada ? doStuff : doAnotherStuff, { someProp: true })
h('div', isCanada ? someProps : anotherProps)
h('div', isCanada ? someProps : anotherProps, "SomeChildren")
const SecondArgOnIgnoredIsNotArray = () =>
h(ANIMATIONS[country], children);
const MultiMemberExpressionWithClosingTag = () => h(Pricing.lol.kek, { className }, [ h('h1') ])
// to handle h(Abc, { [kek]: 0, ["norm"]: 1 }) to < Abc {...{ [kek]: 0 }} {...{ ["norm" + lol]: 1 }} norm={1} />
const ComplexComputedAttibutesHandling = () => h(Abc, { [kek]: 0, ["norm" + lol]: 1, ["ok"]: 2 })
// Should process children but ignore computed parent
h(`calcualted ${stuff}`, { amazing: "stuff" }, [
h("h1"),
h("h2"),
h("h3"),
h("div", [ h("div") ])
])
class Comp extends React.Component {
render() {
return h("div.example", [
isStuff && h("h1#heading", { ...getProps, ...getKnobs(), stuff: "" }),
isStuff
? h("h1#heading", { ...getProps, ...getKnobs(), stuff: "" })
: h("h1#heading", "heading"),
h("h1#heading", { ...getProps, ...getKnobs(), stuff: "" }),
h("h1#heading", getChildren),
h(ANIMATIONS[country], {
className: "lol"
}),
h("h1#heading", getChildren(), [h("div")]),
h("div", [h("div", "Some content")]),
h("h1#heading", "This is hyperscript"),
h("h2", "creating React.js markup"),
h(
AnotherComponent,
{ foo: "bar", bar: () => ({}), shouldRender: thing.length > 0 },
[
h("li", [h("a", { href: "http://whatever.com" }, "One list item")]),
h("li", "Another list item")
]
)
]);
}
}
import React from 'react'
import h from 'react-hyperscript'
import hx from 'shit'
const StatelessComponent = props => <h1 />
const StatelessWithReturn = props => {
return <div className="class" />
}
function HyperscriptAsRegularFunction(props) {
return <h1 />
}
const HyperscriptAsVariable = <div className="lol" someProp="lol" />
const HyperscriptWithExpressionAsChildren = (
<AnotherComponent foo="bar" bar={() => ({})} shouldRender={thing.length > 0}>
{arr.map(() => <h1 />)}
</AnotherComponent>
)
// Should be ignored from transforming
const FirstArgTemplateLiteralWithComputedExpressions = h(`div.lol${stuff}`, {
someProp: 'lol'
})
// Not computed so should be fine
const FirstArgTemplateLiteral = <div className="lol" someProp="lol" />
// Should be ignored
const WhenFirstArgumentIsFunctionThatIsCalled = () =>
h(getLoadableAnimation('pageCareersDeliver'), [h(fn())])
const ComputedRootWithObjectPropertyDeclaration = () =>
h(
ANIMATIONS[country],
{
className: 'lol',
content: (
<div className="selectItem">
<div>{label}</div>
<div className="flag">
<RoundFlag mix="flag" size="xs" code={currencyData.countryCode} />
{// Computed not root should be wrapped in {}
h(ANIMATIONS[country], { className: 'lol' })}
</div>
</div>
)
},
[
h(ANIMATIONS[country], { className: 'lol' }),
<h1 />,
kek && mem,
surreal ? lol : kek,
t.tabName,
lol,
<div />
]
)
const ThirdArgOnIgnoredIsNotArray = () =>
h(
ANIMATIONS[country],
{
className: 'lol'
},
// This first children in array will be ignored FOR THIS UGLY HACK IN INDEX
children
)
h(isCanada ? doStuff : doAnotherStuff, { someProp: true });
<div>{isCanada ? someProps : anotherProps}</div>;
<div {...(isCanada ? someProps : anotherProps)}>SomeChildren</div>;
const SecondArgOnIgnoredIsNotArray = () => h(ANIMATIONS[country], children)
const MultiMemberExpressionWithClosingTag = () => (
<Pricing.lol.kek className={className}>
<h1 />
</Pricing.lol.kek>
)
// to handle h(Abc, { [kek]: 0, ["norm"]: 1 }) to < Abc {...{ [kek]: 0 }} {...{ ["norm" + lol]: 1 }} norm={1} />
const ComplexComputedAttibutesHandling = () => (
<Abc {...{ [kek]: 0 }} {...{ ['norm' + lol]: 1 }} ok={2} />
)
// Should process children but ignore computed parent
h(`calcualted ${stuff}`, { amazing: 'stuff' }, [
<h1 />,
<h2 />,
<h3 />,
<div>
<div />
</div>
])
class Comp extends React.Component {
render() {
return (
<div className="example">
{isStuff && <h1 id="heading" {...getProps} {...getKnobs()} stuff="" />}
{isStuff ? (
<h1 id="heading" {...getProps} {...getKnobs()} stuff="" />
) : (
<h1 id="heading">heading</h1>
)}
<h1 id="heading" {...getProps} {...getKnobs()} stuff="" />
<h1 id="heading">{getChildren}</h1>
{h(ANIMATIONS[country], {
className: 'lol'
})}
<h1 id="heading" {...getChildren()}>
<div />
</h1>
<div>
<div>Some content</div>
</div>
<h1 id="heading">This is hyperscript</h1>
<h2>creating React.js markup</h2>
<AnotherComponent
foo="bar"
bar={() => ({})}
shouldRender={thing.length > 0}
>
<li>
<a href="http://whatever.com">One list item</a>
</li>
<li>Another list item</li>
</AnotherComponent>
</div>
)
}
}
Install codemod npm install -g @codemod/cli
Then install in root of your project npm install babel-plugin-hyperscript-to-jsx
Run it like that from node_modules:
codemod --plugin ./node_modules/babel-plugin-hyperscript-to-jsx/src/index.js ./src
Also, you may like to pretty print it immediately using prettier
codemod --plugin ./node_modules/babel-plugin-hyperscript-to-jsx/src/index.js ./src --printer prettier
Remove babel-plugin-hyperscript-to-jsx
from package.json
If there is any issues, let me know in the issues tab here at GitHub.
You can run it against exact file too e.g. ./src/index.js
codemod --plugin ./node_modules/babel-plugin-hyperscript-to-jsx/src/index.js ./src/index.js --printer prettier
h
is called this wayh("FirstThing", this.getSomePropsOrChildren());
Second argument will be a children (to break everything), cause to get whether second argument expression is returning children or props of object is almost impossible.
h
like h(STUFF[computed])
or h(
.stuff ${anotherClass})
is impossible to codemod, so they will be ignored, and you will need to fix it yourself, they will be kept
as is, but their array second and third arguments will be processed with the same approach.Fix all that by yourself :)
(it's possible but will require further analysis of AST with hardcore traversal and I don't think it worth it)
Preconditions:
npm i -g @codemod/cli babel-plugin-hyperscript-to-jsx
Name: h to JSX
Program: codemod
Arguments: -p <your global node_modules location>/babel-plugin-hyperscript-to-jsx/src/index.js $FilePathRelativeToProjectRoot$
Working directory: $ProjectFileDir$
In advanced settings:
Tick on: Sync file after execution
Right Click -> External Tools -> h to JSX -> Apply prettier/code formatting -> Enjoy
Preferences -> Keymap -> External Tools -> External Tools -> h to JSX -> Attach some key combination
>Tasks: Configure Task
Task from tasks.json template
(or something like that){
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "H to JSX",
"type": "shell",
"command": "codemod -p <your global node_modules location>/babel-plugin-hyperscript-to-jsx/src/index.js ${file}"
}
]
}
keybindings.json
{
"key": "cmd+e",
"command": "workbench.action.tasks.runTask",
"args": "H to JSX"
}
keybindings.json
just open Command pallete and type.
Run task -> Enter -> Find in the list "H to JSX" -> Enter
(Usually will be on top)-o index={\"revolut\":true}
before the $FilePathRelativeToProjectRoot$
-o index='{\"revolut\":true}'
before the ${file}
FAQs
This plugin transforms react-hyperscript into JSX
The npm package babel-plugin-hyperscript-to-jsx receives a total of 0 weekly downloads. As such, babel-plugin-hyperscript-to-jsx popularity was classified as not popular.
We found that babel-plugin-hyperscript-to-jsx demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.