Use JSX as a template engine in Node.
This module enables requiring .jsx
files in Node. It does this by usingbabel andbabel-plugin-transform-react-jsxto first transform jsx intohyperscript, and then transformall h()
calls in the resulting hyperscript into more efficient stringconcatenations.
Warning! This is a Proof of Concept
This module is still in a very early phase. Any production use shouldbe approached with caution.
Basic Use
To be able to simply require .jsx
files, you needto tell Node what to do with them. Running the following code makes youable to require('./SomeFile.jsx')
:
require('jsx-node').install({
replace:{
preact:'jsx-node',
}
});
As you can see, you are able to pass some options. The default options are:
constdefaultOptions={
extension:'.jsx',
presets:['es2015-node6'],
plugins:[
'add-module-exports',
],
See AlsoHow does JSX differ from HTML ? - GeeksforGeeksDo browsers understand JSX code?Using TypeScript – ReactReact JSX - GeeksforGeeks};
options
passed to the install
method are assigned/extended withdefaultOptions
, not (deeply) merged. If you want to add a new plugin orpreset, but still use the default ones you have to explicitly send all defaultsin your array.
Stateless & ES6 Components recommended
To make the the most efficient and simplest use of this library, make sure youonly use stateless or ES6 class components.
For ES6 Class Modules, make sure the initial state is set in the constructor andnowhere else.
Compatible With Preact
This module is designed to be compatible with Preact.
className
prop is aliased toclass
, andclass
can be a plain object.any keys with truthy values will be used as a class.
Usage With Express
server.js
'usestrict';
//makenodeunderstand`*.jsx`files
require('jsx-node/node-require').install();
constchalk=require('chalk');
constexpress=require('express');
constserver=express();
//overridedefaultresponserendermethod
server.response.render=require('./render.jsx');
//loadroutes
server.use(require('./router'));
//getportfromenvorusedefault
constport=process.env.PORT||1337;
//startserver,savereferencetoHTTPServerinstancereturned
server.http=server.listen(port,()=>{
console.info(`[${chalk.cyan('INIT')}]HTTPServerlisteningonport${chalk.magenta(port)}(${chalk.yellow(server.get('env'))})`);
});
//exportinstanceofserverifneededbyothermodules
module.exports=server;
render.jsx
If all our jsx files adhere to stateless and ES6 Classes, the following code worksgreat to override the default express rendering logic.
'usestrict';
module.exports=function(Component,Master){
if(typeofComponent!=='function')thrownewError('NotaComponent');
constlocals=Object.assign({},this.app.locals,this.locals);
if(typeofMaster==='function'){
this.send('<!doctypehtml>'+(
<Master{...locals}>
<Component{...locals}/>
</Master>
));
}elseif(Component.prototype&&Component.prototype.render){
consti=newComponent(locals);
this.send(i.render(i.props,i.state));
}else{
this.send(Component(this.props));
}
};
router.js
'usestrict';
constContact=require('./Contact.jsx');
constIndex=require('./Index.jsx');
constMaster=require('./Master.jsx');
constrouter=new(require('express')).Router();
router.get('/',(req,res,next)=>{
res.render(Index,Master);
});
router.get('/contact',(req,res,next)=>{
res.render(Contact,Master);
});
module.exports=router;
TODO
- Write tests
babel plugin
- Escape unsafe code insert, but enable injecting of html from variables like
regions
- Use custom Component class (needs to be done in babel plugin)
- Remove all methods on class components except constructor and render, butkeep all methods used in those
- Remove all dependencies not used in methods from above point