Racy
A blazing fast zero-configuration async server-side React with GraphQL toolbelt.
Stack
- Babel 7 + Polyfill
- Parcel Bundler
- React
- Styled-Components
- Helmet-Async
- React-Router v4 + React-Router-DOM + React-Router-Config
- Express
- GraphQL Apollo React & Apollo Server
Setup
npm init -f
yarn add racy
package.json
"scripts": {
"dev": "racy dev",
"build": "racy build",
"serve": "racy serve",
"export": "racy export",
"start": "NODE_ENV=production racy build && racy serve",
"static": "NODE_ENV=production npm run export && racy static"
}
How to
- How to create a simple React-App?
- How to customize the default configuration?
- How to map a component to a route?
- How to use dynamic imports and code splitting?
- How to use GraphQL on the client?
- How to use customize Apollo links?
- How to extend Express with additional middleware?
- How to create a GraphQL server?
- How to add GraphQL subscriptions on the client?
CLI
racy dev
- Develop an Appracy build
- Build an App for dynamically servingracy serve
- Dynamically serve an Appracy export
- Export an App for statically servingracy static
- Statically serve an Appracy graphql schema
- Fetch and save GraphQL schema to a fileracy graphql fragments
- Fetch and save GraphQL fragment types to a file
How to create a simple React-App?
Just enter yarn add react
and create a App.js
in your project root folder.
App.js
import React, { Fragment as F } from 'react';
import Helmet from 'react-helmet';
import styled from 'styled-components';
const Headline = styled.h1`
color: blue;
`;
export default async ({ name, version, port }) => (
<F>
<Helmet>
<meta charSet="utf-8" />
<title>React-App</title>
</Helmet>
<Headline>
Racy Basic App Example {name} {version}
</Headline>
</F>
);
How to customize the default configuration?
Just create a config.js
in your project root folder.
config.js
export default {
// Listen on port?
port: process.env.PORT || 8080,
// GraphQL prefetch on server?
shouldPrefetch: false,
// SSR mode only?
ssrMode: false,
};
How to map a component to a route?
App.js
import React from 'react';
import Home from './components/Home';
import About from './components/About';
import NotFound from './components/NotFound';
export default async () => [
{ path: '/', exact: true, component: Home },
{ path: '/about', exact: true, component: About },
{ component: NotFound },
];
How to use dynamic imports and code splitting?
App.js
import React from 'react';
export default async () => {
const { default: Home } = await import('./components/Home');
const { default: About } = await import('./components/About');
return [
{ path: '/', exact: true, component: Home },
{ path: '/about', exact: true, component: About },
];
};
How to use GraphQL on the client?
App.js
import React, { Fragment as F } from 'react';
import { Query } from 'react-apollo';
import GITHUB_QUERY from './Github.gql';
export default async ({ name, version }) => {
return (
<F>
<h1>
App: {name} {version}
</h1>
<Query query={GITHUB_QUERY}>
{({ data, error, loading }) => {
if (loading) return <div>loading ...</div>;
if (error) return <div>{error.message}</div>;
return <pre>{JSON.stringify(data, null, 4)}</pre>;
}}
</Query>
</F>
);
};
config.js
export default {
// Listen on port
port: process.env.PORT || 8080,
// GraphQL URL for GraphQL queries
graphqlUrl: process.env.GRAPHQLURL || 'https://www.graphqlhub.com/graphql',
// Import fragment types file to resolve union and interface types
createFragmentTypes: async () => await import('./fragmentTypes.json'),
// Enable prefetching on server-side
shouldPrefetch: true,
};
How to use customize Apollo links?
config.js
import { withClientState } from 'apollo-link-state';
import resolvers from './resolvers';
export default {
port: process.env.PORT || 8080,
createLink: async ({ cache }) =>
withClientState({
cache,
resolvers,
defaults: {
visible: false,
},
}),
};
How to extend Express with additional middleware?
Just create a express-server.js
in your project root folder.
express-server.js
import morgan from 'morgan';
import cors from 'cors';
import compression from 'compression';
import examples from './examples';
export default ({ config, app }) => {
app.use(morgan('combined'));
app.use(cors());
app.use(compression());
app.use('/api/examples', examples);
};
How to create a GraphQL server?
Just create a graphql-server.js
in your project root folder.
graphql-server.js
export default ({ config }) => ({
context: ({ req }) => ({ req, config }),
typeDefs: `type Todo {
id: ID!
description: String!
done: Boolean
}
type Query {
todos: [Todo]
}`,
resolvers: {
Query: {
todos: () => [{ id: 1, description: 'Demo 1', done: false }],
},
},
});
How to add GraphQL subscriptions on the client?
config.js
import { split } from 'apollo-link';
import { HttpLink } from 'apollo-link-http';
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
export default {
port: 8080,
createLink,
};
function createLink({ isServer }) {
const httpLink = new HttpLink({
uri: `http://localhost:8080/graphql`,
});
const wsLink = isServer
? null
: new WebSocketLink({
uri: `ws://localhost:8080/graphql`,
options: {
reconnect: true,
},
});
return isServer
? httpLink
: split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === 'OperationDefinition' && operation === 'subscription';
},
wsLink,
httpLink,
);
}
App.js
import React, { Fragment as F } from 'react';
import { Subscription } from 'react-apollo';
import gql from 'graphql-tag';
const GRAPHQL_SUBSCRIPTION = gql`
subscription OnChanged {
changed {
id
name
}
}
`;
export default async () => (
<Subscription subscription={GRAPHQL_SUBSCRIPTION}>
{({ data }) => <pre>{JSON.stringify(data, null, 2)}</pre>}
</Subscription>
);