demo | ||
docs | ||
examples | ||
lib | ||
src | ||
test | ||
.gitignore | ||
.npmignore | ||
.npmrc | ||
.travis.yml | ||
CHANGELOG.md | ||
cli.js | ||
components.js | ||
index.js | ||
LICENSE.md | ||
package.json | ||
README.md |
x0
Zero-config React development environment and static site generator
npm install -g @compositor/x0
![](/c8r/x0/media/commit/8fe228619b02eb0e0fcbbdc89af1a7721bf9ecb4/docs/hello-x0.gif)
Features
- Zero-config
- Hot-loading development environment
- Works with virtually any React component*
- No confusing APIs
- Automatic file system based routing
- Exports static HTML
- Exports JS bundles
- Works with CSS-in-JS libraries like styled-components and emotion
- Support for async data fetching
Read more about x0 in our blog post.
* Custom webpack configuration is required for components that rely on webpack-based features
Isolated development environment
x0 components
Options:
-o --open Open dev server in default browser
-p --port Custom port for dev server
-t --template Path to custom HTML template
--webpack Path to custom webpack configuration
x0 components -op 8080
Static Build
Export static HTML and client-side bundle
x0 build components
Export static HTML without bundle
x0 build components --static
Options
-d --out-dir Output directory (default dist)
-s --static Output static HTML without JS bundle
-t --template Path to custom HTML template
--webpack Path to custom webpack configuration
Fetching Data
Use the async getInitialProps
static method to fetch data for static rendering.
This method was inspired by Next.js.
const Index = props => (
<h1>Hello {props.data}</h1>
)
Index.getInitialProps = async () => {
const fetch = require('isomorphic-fetch')
const res = await fetch('http://example.com/data')
const data = await res.json()
return { data }
}
Custom App
A custom App
component can be provided by including an _app.js
file.
The App
component uses the render props pattern to provide additional state and props to its child routes.
// example _app.js
import React from 'react'
export default class extends React.Component {
state = {
count: 0
}
update = fn => this.setState(fn)
render () {
const { render, routes } = this.props
return render({
...this.state,
decrement: () => this.update(s => ({ count: s.count - 1 })),
increment: () => this.update(s => ({ count: s.count + 1 }))
})
}
}
Layouts
The App
component can also be used to provide a common layout for all routes.
// example _app.js
import React from 'react'
import Nav from '../components/Nav'
import Header from '../components/Header'
import Footer from '../components/Footer'
export default class extends React.Component {
render () {
const {
render,
routes
} = this.props
const route = routes.find(route => route.path === props.location.pathname)
return (
<React.Fragment>
<Nav />
<Header
route={route}
/>
{render()}
<Footer />
</React.Fragment>
)
}
}
CSS-in-JS
x0 supports server-side rendering for styled-components and emotion with zero configuration.
Styled Components
To enable CSS rendering for static export, ensure that styled-components
is installed as a dependency in your package.json
"dependencies": {
"styled-components": "^3.2.6"
}
Emotion
Ensure emotion
is installed as a dependency in your package.json
"dependencies": {
"emotion": "^9.1.3"
}
Configuration
Default options can be set in the x0
field in package.json
.
"x0": {
"static": true,
"outDir": "site",
"title": "Hello",
}
Head content
Head elements such as <title>
, <meta>
, and <style>
can be configured with the x0
field in package.json
.
"x0": {
"title": "My Site",
"meta": [
{ "name": "twitter:card", "content": "summary" }
{ "name": "twitter:image", "content": "kitten.png" }
],
"links": [
{
"rel": "stylesheet",
"href": "https://fonts.googleapis.com/css?family=Roboto"
}
]
}
Custom HTML Template
A custom HTML template can be passed as the template
option.
"x0": {
"template": "./html.js"
}
// example template
module.exports = ({
html,
css,
scripts,
title,
meta = [],
links = [],
static: isStatic
}) => `<!DOCTYPE html>
<head>
<title>{title}</title>
${css}
</head>
<div id=root>${html}</div>
${scripts}
`
Routing
x0 creates routes based on the file system, using react-router.
To set the base URL for static builds, use the basename
option.
"x0": {
"basename": "/my-site"
}
Links
To link between different components, install react-router-dom
and use the Link
component.
npm i react-router-dom
import React from 'react'
import { Link } from 'react-router-dom'
export default () => (
<div>
<h1>Home</h1>
<nav>
<Link to='/'>Home</Link>
<Link to='/about'>About</Link>
</nav>
</div>
)
JSX Format
x0 includes support for the Compositor JSX file format.
---
title: Hello
---
import { Box, Heading } from 'rebass'
<Box px={2} py={4}>
<Heading>
{frontMatter.title}
</Heading>
</Box>
MDX Format
x0 includes support for the MDX file format.
import { Box } from 'rebass'
# Hello MDX
<Box p={4} bg='tomato'>
Beep Boop
</Box>
webpack
Webpack configuration files named webpack.config.js
will automatically be merged with the built-in configuration, using webpack-merge.
To use a custom filename, pass the file path to the --webpack
flag.
// webpack.config.js example
module.exports = {
module: {
rules: [
{ test: /\.txt$/, loader: 'raw-loader' }
]
}
}
See the example.
Related
- Compositor JSX
- MDX
- React Router
- Mini HTML Webpack Plugin
- Styled Components
- Emotion
- webpack
- Create React App
- Next.js
- Gatsby
- React-Static
Made by Compositor | MIT License
To Do
REMOVE BEFORE MERGING
- require.context
_app
- props.Component/children in custom apps
- peer deps
- Head component with react helmet
- changelog/docs
- props.ignore
- default layout for mdx/md
- default route sorting
- route dirname/full path
- pass front-matter as props
- markdown scope
- deep require context
- minimatch
- move client modules to src
- adjust resolve
Breaking
- .jsx imports/scope
- .jsx props