
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
express-engine-jsx
Advanced tools
Example of users.jsx
view file
const Layout = require('./layout');
<Layout>
<ul class="users">
{users.map(user => (
<li key={user}>{user.name}</li>
))}
</ul>
</Layout>
Example of layout.jsx
view file
<html lang={lang}>
<head>
<meta charset="UTF-8"/>
</head>
<body>{children}</body>
</html>
Example of router
app.get('/users', function (req, res) {
res.locals.lang = 'en';
res.render('users', {
users: [
{name: 'Max'},
{name: 'Bob'}
]
});
});
Output html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"/></head>
<body><ul class="users"><li>Max</li><li>Bob</li></ul></body>
</html>
When you render some view, this engine takes jsx
file like this
const Layout = require('./layout');
<Layout>
<ul class="users">
{users.map(user => (
<li key={user}>{user.name}</li>
))}
</ul>
</Layout>
and compiles it to js
file like this
const React = require('react');
const requireJSX = require('express-engine-jsx/require');
const Context = require('express-engine-jsx/Context');
module.exports = function (props) {
const __components = [];
const context = React.useContext(EngineContext);
const locals = context.locals || {};
with (locals) {
with (props) {
const Layout = requireJSX('./layout');
__components.push(
React.createElement(
Layout,
null,
React.createElement(
'ul',
{className: 'users'},
users.map(user => (
React.createElement(
'li',
{key: user},
user.name
)
))
)
)
);
}
}
return __components;
};
and now this component can be rendered to html with ReactDOM.renderToStaticMarkup()
.
As you can see, each jsx view file returns array of components and standard html attributes are converted to react attributes
<div class="first" tabindex="1"></div>
<div class="second" tabindex="2"></div>
//...
__components.push(React.createElement('div', {className: 'first', tabIndex: '1'}));
__components.push(React.createElement('div', {className: 'second', tabIndex: '2'}));
//...
return __components;
const express = require('express');
const app = express();
const engine = require('express-engine-jsx');
server.set('views', '/path/to/views');
server.set('view engine', 'jsx');
server.engine('jsx', engine);
// optionaly
engine.setOptions({
doctype: "<!DOCTYPE html>\n", // prepended string to every output html
templatePath: '/path/to/template.jsx', // path to base tamplete of component for all jsx templates. Default is "express-engine-jsx/template.jsx",
replace: (html) => {return html}, // Modify final html with this callback
parserOptions: {}, // See https://babeljs.io/docs/en/babel-parser#options
});
That's it, you no need to do app.set('views', 'views')
and so on, attachTo
will do that for you
const engine = require('express-engine-jsx');
It's a function which takes three arguments:
path
- path to jsx filelocals
- object with properties which will be local variables in jsx filecallback
- optional Node style callback which will receive html string as second argumentIf you pass to engine
only path and locals then it will return html.
engine('/path/to/view', {prop: 'value'}, (err, html) => console.log(html));
const html = engine('/path/to/view', {prop: 'value'});
Also, it has method engine.setOptions(options)
which can modify options
const options = require('express-engine-jsx/options');
Object with optional properties:
doctype
- string which will be prepended to output html, default value is "<!DOCTYPE html>\n"
replace
- function which will take output html (without doctype), and it should return new htmltemplatePath
- path to wrapper of compiled jsx, default value is express-engine-jsx/template.jsx
. Undefined variable BODY
will be replaced with your compiled jsx code.parserOptions
- options for babel.parsertemplateOptions
- options for babel.templateconst requireJSX = engine.require || require('express-engine-jsx/require');
This is a function which you can use as regular require
but this one can run jsx files. It checks if path is jsx file and if it is then requireJSX
will convert this file to js code and then run it.
It also can take optional second parameter - currentWorkingDir
which should be an absolute path to file directory which calls require
in case when you call require
from some unusual place like debugger console.
Every compiled jsx file will be cached to requireJSX.cache
object where key will be path to jsx file and value will be value of module.exports
inside jsx file, usually react component.
You can delete any key in this cache, requireJSX will recompile jsx file on next call.
const convert = engine.convert || require('express-engine-jsx/convert');
It is a function which can convert jsx template code to js code.
Arguments:
code
- string of jsx codeoptions
addOnChange
- boolean, default true
. Will add onChnage={() => false}
to every <input>
with value
or checked
attribute. Used to omit ReactDOM warning about value
prop without onChange
handler.parserOptions
- options for babel.parsertemplate
- string of jsx code wrapper. You can pass false
if you don't want to wrap your code with template
templatePath
- string, path to jsx code wrappertemplateOptions
- options for babel.templateIt also has convert.cache
object for compiled templates where keys are templatePath
and values are functions created by babel.template
const run = engine.run || require('express-engine-jsx/run');
Function which can execute js code with independent context and returns result of module.exports
inside js code.
Arguments:
code
- string of js codeoptions
path
- string, path to file, usually path to jsx filecontext
- object which properties will be global variables inside js codescriptOptions
- object options for vm.Scriptconst Context = engine.Context || require('express-engine-jsx/Context');
React context which used to bypass locals to components
const attrMap = require('express-engine-jsx/attr-map');
This is an object where keys are names of html attributes in lower case like class
and values are valid React html attributes like className
.
You can modify this object if I forget about some attributes.
For example how to integrate to ejs
const express = require('express');
const app = express();
const engine = require('express-engine-jsx');
const {dirname, resolve} = require('path');
app.locals.component = function (path, props = {}) {
props = Object.assign({}, this, props);
return engine(resolve(dirname(this.filename), path), props);
};
Now we can use component()
in ejs files like this
<div><%- component('path/to/jsx-view', {prop: 'value'}) %></div>
In javascript you can omit ;
and write like this
"first"
"second"
It does nothing, but it's valid code. In JSX you can't do same thing with elements
<div>first</div>
<div>second</div>
It will throw compilation error. It's waiting for ;
after first element. You have three options to solve this problem.
First - use ;
<div>first</div>;
<div>second</div>;
Second - use <Fragment>
<Fragment>
<div>first</div>
<div>second</div>
</Fragment>
Third - use short Fragment notation <>...</>
<>
<div>first</div>
<div>second</div>
</>
MIT, see LICENSE
file
FAQs
JSX engine for ExpressJS
The npm package express-engine-jsx receives a total of 21 weekly downloads. As such, express-engine-jsx popularity was classified as not popular.
We found that express-engine-jsx demonstrated a healthy version release cadence and project activity because the last version was released less than 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.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.