Kelex
Kelex is a plugable framework and companion tool for facilitating the development of server rendered React applications and libraries with no build configuration. With Kelex, you get the following out of the box:
- Automatic transpilation and bundling (with webpack and babel)
- Code splitting and Dynamic imports
- Hot code reloading
- Server rendering of
./app/pages
- Possibility to use the file-system as routing API (or not)
- Static file serving
- Automatic Linting and running of tests
- Support for creating both apps and libraries
- ES6/7 support everywhere
- Plugin support
- Little to no configuration needed (simply use the cli interface)
Installation
Install Kelex globally by doing
npm i -g kelex
or
yarn global add kelex
Creating a server rendered React app
Setup
With Kelex installed globally, run the following command from within the folder that will house your app files:
klx init app
This will generate all the necessary files, at which point you can then run klx dev --open
to startup a dev server (that supports hot code reloading) and open it in the browser.
See CLI Commands for the available commands.
For convenience, the following npm commands will be setup as part of initialising the app:
-
npm run dev
: To startup a dev server that supports hot code reloading -
npm run build
: `To build the production bundle -
npm run start
: To startup the production server -
npm run test
: 'Tun run tests'
and a few more...
Creating pages (a.k.a routing)
By the default, the file-system is setup to be the main routing API of the app. What this means is
that to create an new page / route, all you have to do is create a react component at the
corresponding location within the ./app/pages/
folder. So for instance, if you wanted to create a
page that would be served at 'http:yoursite.com/about/team', you would just create a
./app/pages/about/Team.js
file with contents similar to the following:
export default () => (
<div>
Some info about your team
</div>
)
To stop using the file-system as the routing api or to define routes that cannot be defined using
the file system, you can use the ./app/routing.js
. So for instance, lets say that in addition
to the 'http:yoursite.com/about/team' page, you also want an '/about/team/judy' or
'/about/team/james' page (i.e., a page to display information about specific team member), you
would edit the ./app/routing.js
file to become something like the following:
export default {
directoryBased: true,
routes: {
'/about/team/:member': { page: '/TeamMember', exact:true, strict: false }
}
}
This routing configuration is essentially saying that in addition to file-system based routing
(i.e., directoryBased: true
), a route with path of /about/team/:member
that will be render the
./app/pages/TeamMember.js
component with an exact and non strict match should also be setup.
For more information regarding the optional exact
and strict
properties (only the page
property is required), see the React Router
documentation. Note also that as React Router is being used under the hood, any path format
that is supported by React Router is also supported by kelex.
Adding styles / css
Kelex has support for styled-jsx which means styles can be defined by as follows:
export default () => (
<div class="Foo">
Some info about your team
<style jsx global>
{`
.Foo {
background: red;
}
`}
</style>
</div>
)
Note also that the class
attribute (as opposed to className
) is allowed along with the for
(as opposed to the htmlFor
) attribute. Please refer to the styled-jsx documentation
for more details on its usage.
<head>
Populating the To populate the <head>
portion of the html page, use react-helmet
as follows:
import {Helmet as Head} from "react-helmet"
export default () => (
<div class="SomePage">
<Head>
<meta charSet="utf-8" />
<title>Some Page</title>
</Head>
...
</div>
)
Note that only react-helmet is supported where server rendering is concerned. Please refer to the react-helmet documentation for details regarding its usage.
Fetching data before rendering
todo
Images and static assets
Images can be added by either simply importing them as follows:
import logo from "./images/logo.png"
export default () => (
<div>
<img src={logo} />
</div>
)
or by adding the image to the ./public
folder and then referencing it from there. So for
instance, if there is a ./public/path/to/logo.png
file, it can be referenced to as follows:
export default () => (
<div>
<img src="/path/to/logo.png" />
</div>
)
This is because anything that is added to the ./public/
folder will be become available to be
served as a static asset
CLI Commands
-
klx init <plugin>
: Initialise the target directory with the specified plugin -
klx dev
: Startup a development server that supports hot code reloading -
klx build
: Generates the javascript bundle -
klx serve
: Starts up a http server to serve the files generated byklx build
-
klx lint
: Run eslint on the target directory -
klx test
: Execute tests
For more detailed documentation on each command, including the available options, run any of the
commands with the flag -h
(as in klx build -h
for instance)
TODO
- Document the features at the beginning. Things like automatic code splitting, hot code reloading, sever rendering, CSS support and so on
- Document the options for each command?
- Rename
routing.directoryBased
torouting.fileSystemBased ?
- Wrap react-helmet so that the user imports
kelex/head
instead - Move
./public
to./app/public
or./app/static
?