React separate template
- Solution description
- TodoMVC example
- Installation
- Usage from command line
- Usage from code
- Additional features
- Gulp plugin
First problem of react is HTML inside our JS files and there is no way to make them separate.
Solution description
So I want to take out HTML from this class to separate file
var MenuExample = React;
But if we just take out everything after return
it's not what I want. I need absolutely clear HTML so I can write
my CSS and see results without running whole app. I want to se template like this
{m} Selected: {this.props.items[this.state.focused]}
Okay, first of all we need to put this.props.items.map(...)
in ul
. I thought, annotation is good enough to make link
to some function like this
@render
<!-- @render list --> Selected: {this.props.items[this.state.focused]}
But where should be that list
function? What if it will be right after our return
, where was this template?
var MenuExample = React;
But wait, not that again, HTML in code, maybe we can take out it, but it should be in same template file. Maybe we will make some annotation which will be replaced with HTML (with some unique id) from our template?
jsx-tpl
var MenuExample = React;
Annotation not in comment because it is a value, not just some meta information. Lets call attribute with this unique id just like annotation.
<!-- @render list --> {m} Selected: {this.props.items[this.state.focused]}
Lets say that all tags with attribute jsx-tpl
will be detached from template and can be used only in classes to replace
@jsx-tpl
annotations. So basically they can be anywhere in template.
jsx-class
Last thing, what if we want many templates in one html file? Lets add jsx-class
attribute with displayName value of
react class to element in template to join them
<!-- @render list --> {m} Selected: {this.props.items[this.state.focused]} ...
So we should add to our classes filed displayName:
var MenuExample = React; var x = React;
jsx-instance
If you define jsx-class
in another jsx-class
or jsx-tpl
then this definition will be replaced to the end of body, but what if you need instance of this class right in this place? Just add jsx-instance="true"
to it. All attributes with curly brackets will be with instance.
Example
{user.name}
Will be converted to
{user.name}
TodoMVC Example
Here original implementation of TodoMVC project on React and here same project but with separated html examples/todomvc. You can see that each component has it template. But wait, checkout one combined template components/index.html for all components. You can use it to compile all components. You can just open it and see how your app looks like without running js code. How cool is that?
Installation
npm install react-st
Usage from command line
Just run react-st -j test/js/menu.js
. It will take file test/js/menu.js, join with test/js/menu.html
and save to test/js/menu.jsx
To see all options run react-st -h
Usage from code
Example
var convert = ; ;
Additional features
- All
class
attributes will renamed toclassName
- All
jsx-spread="someVar"
attributes will be converted to Spread Attribute{...someVar}
- I added syntax like this
class="item {style}"
and it will be converted toclassName={"item " + style}
. Helpful for styling html without running js code
Notice
All attributes with curly brackets will be converted to react jsx version. If you will write something like this
data-bind="attr: {active: isActive}"
it will be converted to data-bind={'attr: ' + active: isActive}
, so be careful.
Gulp plugin
See https://github.com/redexp/gulp-react-st
Contribute!
I will be glad if you have any suggestions, just create an issue.