preact-view-engine
This is an [Express][express] view engine forked from express-react-views which renders [Preact][preact] components on server.
This is intended to be used as a replacement for existing server-side view solutions, like [jade][jade], [ejs][ejs], or [handlebars][hbs].
Usage
npm install preact-view-engine preact
Add it to your app.
const renderEngine = require('preact-view-engine')
const app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', renderEngine.createEngine());
Options
option | values | default |
---|
doctype | any string that can be used as a doctype, this will be prepended to your document | "<!DOCTYPE html>" |
beautify | true : beautify markup before outputting (note, this can affect rendering due to additional whitespace) | false |
transformViews | true : use babel to apply JSX, ESNext transforms to views. Note: if already using babel-register in your project, you should set this to false | true |
babel | any object containing valid Babel options Note: does not merge with defaults | {presets: ['preact', [ 'env', {'targets': {'node': 'current'}}]]} |
The defaults are sane, but just in case you want to change something, here's how it would look:
const options = { beautify: true };
app.engine('jsx', renderEngine.createEngine(options));
Views
Under the hood, [Babel][babel] is used to compile your views to code compatible with your current node version, using the [preact][babel-preset-preact] and [env][babel-preset-env] presets by default. Only the files in your views
directory (i.e. app.set('views', __dirname + '/views')
) will be compiled.
Your views should be node modules that export a preact component. Let's assume you have this file in views/index.jsx
:
import { h } from 'preact';
const HelloMessage = (name) => {
return <div>Hello {name}</div>
}
export default HelloMessage;
Routes
Your routes would look identical to the default routes Express gives you out of the box.
import index from './routes';
app.get('/', index);
export default function(req, res){
res.render('index', { name: 'Some Name' });
};
That's it! Layouts follow really naturally from the idea of composition.
Layouts
Simply pass the relevant props to a layout component.
views/layouts/default.jsx
:
import { h } from 'preact';
const DefaultLayout = (props) => {
const {title, children} = props
return (
<html>
<head><title>{title}</title></head>
<body>{children}</body>
</html>
);
}
export default DefaultLayout;
views/index.jsx
:
import { h } from 'preact';
import DefaultLayout from './layouts/default';
const HelloMessage = () => {
return (
<DefaultLayout title={'title'}>
<div>Hello</div>
</DefaultLayout>
);
}
export default HelloMessage;