bin | ||
docs | ||
examples | ||
lib | ||
test | ||
.gitignore | ||
.npmignore | ||
.npmrc | ||
.travis.yml | ||
index.js | ||
LICENSE.md | ||
package.json | ||
README.md |
x0
Zero-config React development environment and static site generator
npm install -g @compositor/x0
Features
- Zero-config
- Hot-loading development environment
- Works with virtually any React component*
- No confusing APIs
- Renders static HTML
- Renders JS bundles
- Works with CSS-in-JS libraries like styled-components and glamorous
- Support for routing with react-router
- Support for async data fetching
- Support for code splitting with React Loadable
* Components cannot rely on bundler features like webpack loaders
Isolated development environment
x0 dev src/App.js
Options:
-o --open Open dev server in default browser
-p --port Set custom port for dev server
x0 dev src/App.js -op 8080
Static Render
Render static HTML and client-side bundle
x0 build src/App.js --out-dir site
Render static HTML without bundle
x0 build src/App.js --out-dir site --static
Options
-d --out-dir Directory to save index.html and bundle.js to
-s --static Only render static HTML (no client-side JS)
Fetching Data
Use the getInitialProps
static method to fetch data for static rendering.
This method was inspired by Next.js but only works for static rendering.
const App = props => (
<h1>Hello {props.data}</h1>
)
App.getInitialProps = async ({
Component,
pathname
}) => {
const fetch = require('isomorphic-fetch')
const res = await fetch('http://example.com/data')
const data = await res.json()
return { data }
}
CSS-in-JS
x0 supports server-side rendering for styled-components, glamor, glamorous, and fela.
To enable CSS rendering for static output, use the cssLibrary
option
x0 build src/App.js --cssLibrary="styled-components"
Available options:
Head content
Head elements such as <title>
, <meta>
, and <style>
can be rendered at the beginning of a component.
Browsers should handle this correctly since the <head>
and <body>
elements are optional in HTML 5.
const App = props => (
<React.Fragment>
<title>Hello x0</title>
<style dangerouslySetInnerHTML={{
__html: 'body{font-family:-apple-system,BlinkMacSystemFont,sans-serif}'
}} />
<h1>Hello x0</h1>
</React.Fragment>
)
Configuration
Default props can be passed to x0 in a package.json
field named x0
.
"x0": {
"title": "Hello",
"count": 0
}
Routing
To render multiple pages and use routing, add a routes
array to the package.json
configuration object.
"x0": {
"routes": [
"/",
"/about"
]
}
x0 build src/App.js --static --out-dir site
The current route will be passed to the component as props.pathname
.
This can be used with react-router's StaticRouter and BrowserRouter components.
// Example with react-router
import React from 'react'
import {
StaticRouter,
BrowserRouter,
Route,
Link
} from 'react-router-dom'
import Home from './Home'
import About from './About'
// universal router component
const Router = typeof document !== 'undefined'
? BrowserRouter
: StaticRouter
const App = props => (
<Router
basename={props.basename}
location={props.pathname}>
<nav>
<Link to='/'>Home</Link>
<Link to='/about'>About</Link>
</nav>
<Route
exact
path='/'
render={() => <Home {...props} />}
/>
<Route
path='/about'
render={() => <About {...props} />}
/>
</Router>
)
Code Splitting
To split client side bundles when rendering a static site, x0 supports React Loadable with no additional setup needed.
// example of using React Loadable
import React from 'react'
import Loadable from 'react-loadable'
const About = Loadable({
loading: () => <div>loading...</div>,
loader: () => import('./About')
})
const App = props => (
<div>
<h1>Hello</h1>
<About />
</div>
)
Proxy
If you want to proxy requests you can configure it using the x0
key in your package.json
.
This can be useful when you're running a local api server during development.
The following example proxies all /api
requests to http://localhost:3000
.
"x0": {
"/api": "http://localhost:3000"
}