Skip to content

MikeBild/racyjs

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Racy

A blazing fast zero-configuration async server-side React with GraphQL toolbelt.

Stack

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

CLI

  • racy dev - Develop an App
  • racy build - Build an App for dynamically serving
  • racy serve - Dynamically serve an App
  • racy export - Export an App for statically serving
  • racy static - Statically serve an App
  • racy graphql schema - Fetch and save GraphQL schema to a file
  • racy 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>
);