Skip to content
This repository has been archived by the owner on Apr 11, 2019. It is now read-only.

merge recent fixes into branch Sans apollo #90

Merged
merged 23 commits into from
Mar 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9e4dc16
add deploy to netlify button
bdougie Dec 27, 2016
1750345
Merge pull request #58 from bdougie/master
RyanCCollins Dec 27, 2016
c374061
Remove html-webpack-plugin from production config. This stops an inde…
Jan 15, 2017
5a4aa29
Feat: add react hot loader app container
RyanCCollins Jan 16, 2017
23e12bf
Merge branch 'master' of https://github.com/RyanCCollins/scalable-rea…
RyanCCollins Jan 16, 2017
22b3c6d
Merge branch 'production-ssr-fix' of https://github.com/daan-nguyen/s…
RyanCCollins Jan 16, 2017
9f07dc5
Feat: fix ssr for index.html
RyanCCollins Jan 16, 2017
4be0b6b
Feat: install flow-types
RyanCCollins Jan 18, 2017
86406d8
Feat: reorganize putting flow-types in confugration folder
RyanCCollins Jan 18, 2017
cb33cad
Feat: update flow configuration and add a few flow components
RyanCCollins Jan 18, 2017
299fff6
Feat: update readme and related files with instructions for flowconfig
RyanCCollins Jan 18, 2017
ac81ecf
Feat: update eslint and fix broken rules
RyanCCollins Jan 18, 2017
aa53612
Merge pull request #66 from RyanCCollins/feat_rc_flow_configuration
RyanCCollins Jan 18, 2017
628aeee
Merge commit 'aa53612b7767858937d510007b3a701cfc836d67' into sans-apollo
monte-hayward Mar 21, 2017
141540c
#88 update sans-apollo branch with recent fixes
monte-hayward Mar 21, 2017
9994fde
#88 update sans-apollo branch with recent fixes
monte-hayward Mar 21, 2017
132a02a
#88 update sans-apollo branch with recent fixes
monte-hayward Mar 21, 2017
bc5c58b
remove some graphql refs
monte-hayward Mar 21, 2017
aff6d56
remove some graphql refs
monte-hayward Mar 21, 2017
89550c2
prevent eslint-plugin-react expects default props
monte-hayward Mar 21, 2017
50a3656
#89 fix TypeError: createLogger is not a function
monte-hayward Mar 21, 2017
fbe742f
#88 update sans-apollo. fix test 4 NavBar
monte-hayward Mar 21, 2017
e8f3ab6
add back erroneously .gitignored file
monte-hayward Mar 22, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BASE_URL='http://localhost:1337/'
API_URL='http://localhost:3000/'
DEBUG=false
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
app/build/
app/dist/
webpack.config.*.js
webpack.config.js
config/
node_modules
server/
config/
14 changes: 9 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ module.exports = {
"node": true,
"jest": true
},
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.config.js"
}
}
},
"rules": {
"func-names": 0,
"eol-last": 0,
"react/no-unused-prop-types": 0,
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"react/jsx-no-bind": [ 2, {
"ignoreRefs": false,
"allowArrowFunctions": true,
"allowBind": true
}],
"graphql/template-strings": ['error', {
env: 'apollo',
schemaJsonFilepath: path.resolve(__dirname, './config/schema/schema.json'),
}]
},
"plugins": [
"import",
"react",
"graphql",
"jsx-a11y"
]
}
25 changes: 25 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[ignore]
.*/node_modules/.*
config/

[include]
./app/src/
./app/src/components/
./app/src/containers/
./app

[libs]
config/flow-typed/npm

[options]
suppress_comment=.*\\$FlowFixMe
suppress_comment=.*\\$FlowInvalidInputTest
module.name_mapper='\(react-redux\)' -> '<PROJECT_ROOT>/config/flow-typed/GeneralStub.js'
module.name_mapper='\(redux\)' -> '<PROJECT_ROOT>/config/flow-typed/GeneralStub.js'
module.name_mapper='.*\(.scss\|.png\|.md\)' -> '<PROJECT_ROOT>/config/flow-typed/GeneralStub.js'
module.name_mapper='^containers\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/containers/\1'
module.name_mapper='^containers$' -> '<PROJECT_ROOT>/app/src/containers'
module.name_mapper='^components\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/components/\1'
module.name_mapper='^components$' -> '<PROJECT_ROOT>/app/src/components'
module.name_mapper='^utils\/\(.*\)$' -> '<PROJECT_ROOT>/app/src/utils/\1'
module.name_mapper='^utils$' -> '<PROJECT_ROOT>/app/src/utils'
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ jspm_packages

# Optional REPL history
.node_repl_history
.env
.vscode
/server/public/**/*.js
/server/public/**/*.css
/server/public/**/*.map
/server/public/**/*.json
/server/public/__offline_serviceworker
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Change Log

## 1.1.0
- Remove dependency to Grommet Udacity and replace with Grommet
- Update test suite and linting to deal with recent issues with both
- Update generators to use flowtypes, functions vs const, et. al.

## 1.0.6
- Flow static type-checking

## 1.0.5
- SSR improvements

## 1.0.4
Styled components were added as an option to containers and components when generated

Expand Down
66 changes: 49 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ You can read more about the organizational strategy used in this app in [this Me

We incorporate an ESLint configuration and follow strictly the [AirBnb JS & JSX style guides](https://github.com/airbnb/javascript).

# TypeScript Version
We now have a TypeScript version of this project. [See here](https://github.com/RyanCCollins/scalable-react-ts-boilerplate).

# What is Feature First?
In most projects and frameworks, files are organized in a File type first fashion. For example, your tests exist in a test folder, your styles in a styles folder. This boilerplate takes a different approach.

Expand Down Expand Up @@ -43,14 +46,47 @@ Below are a few example apps that have been built with this project

__NOTE: if you are using this boilerplate in production, we want to know! Leave an issue, or submit a PR and we will merge it in. Thanks!__

# Main Features
### Styled Components
This framework employs both css-modules and styled-components. We feel that [styled-components](https://github.com/styled-components/styled-components) is the best css-in-js library available.

### Grommet
[Grommet](https://grommet.github.io/) is the world's most advanced UX framework. It contains hundreds of reusable UI components that you can use right away.

### GraphQL / Apollo
This branch excludes GraphQL and ApolloClient. If you need to use graphql, take a look at the [master](https://github.com/RyanCCollins/scalable-react-boilerplate/) branch for a reference implementation with GraphQL / Apollo.

## Experimental Features

### GraphQL / Apollo Features
This boilerplate includes some basic setup for GraphQL and ApolloClient. You will have to setup your own GraphQL Server. Alternatively, take a look at the [GraphQL Anywhere](https://github.com/apollostack/graphql-anywhere) package (not installed), which would allow you to process GraphQL queries client-side.
### Flow
Static types are all the rage in Front End JavaScript land right now.

We feel that the use of Static types is paramount in the evolution of JavaScript and as such have integrated the Flow static type-checking library.

The nice thing about Flow is that you can gradually introduce it into your app, much like we have done with the example code of this boilerplate. You can see a couple of examples of Flow in use in the project in the components directory. If this is not a feature you desire, then do not add the `// @flow` comment in any files.

We have provided library definitions within the [`config/flow-typed`](https://github.com/RyanCCollins/scalable-react-boilerplate/tree/master/config/flow-typed) folder and have also provided some useful configuration within the `.flowconfig` file.

## Performance Optimizations
This framework takes performance very seriously and includes a whole slew of performance optimizations out of the box. We have benchmarked the initial time to first byte at under 20ms! Below is a brief enumeration of the main performance optimizations we employ by default.

1. Webpack code chunking

2. Lazy React Router Route Loading

3. Serverside Rendering

4. Reselect
- Memoization and React.PureComponent

The setup includes the ability to generate the boilerplate to create GraphQL / ApolloClient queries and mutations within your containers. It also adds the eslint-graphql-plugin to lint your collocated GraphQL queries / mutations. The way it works is to load a schema.json file to create an AST of your GraphQL schema. You will need to provide your own schema.json file and leave it in the `/config/schema/` folder.
5. GraphQL
- GraphQL increases performance by eliminating expensive over-fetching

Take a look at the [Example Apps](https://github.com/RyanCCollins/scalable-react-boilerplate#example-apps) section to see examples of GraphQL configuration in practice.
6. Service Worker / Offline First
- The only requirement to go offline first is using SSL.

7. Immutable JS
- Immutable JS is installed by default, but not used in the example application. By combining React.PureComponent, reselect and immutable.js, you will get some serious rendering performance enhancements.

# Documentation

Expand All @@ -72,26 +108,23 @@ There are two options for installation:
With Yarn installed globally, run
`npm run setup:yarn`

4. **Create environment file**
In order for the server and client to know which urls to connect to, we ask that you make a `.env` file. We've included a `.env.example` file that you can rename to get started with the default values.

`cp .env.example .env`

3. **Run development server**

`npm run start`

Your app will be served at: http://localhost:1337

or, you can install it using Slush via the npm package
```
npm install -g slush slush-generator-scalable-react
```

cd into the folder where you want to create your project and run:
```
slush generator-scalable-react
```

Follow the onscreen instructions to create your app.

## Deployment

<a href="https://app.netlify.com/start/deploy?repository=https://github.com/RyanCCollins/scalable-react-boilerplate">
<img src="https://www.netlify.com/img/deploy/button.svg" title="Deploy to Netlify">
</a>

<a href="https://myrskyt.com/container/deploy/https://github.com/RyanCCollins/scalable-react-boilerplate"><img src="https://myrskyt.com/static/img/button.jpg" height="40" width="155"></a>

A demo ExpressJS setup is included with the app. The express server will serve up the production minified bundle.js, index.html and any other assets that are located in the `/server/public` folder.
Expand Down Expand Up @@ -241,7 +274,6 @@ npm run test

which will pick up any file with the .test.js postfix and run it through Jest.


## Technologies / Libraries

- [Node](https://nodejs.org/en/) - JS runtime environment
Expand Down
111 changes: 54 additions & 57 deletions app/src/components/About/index.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,59 @@
import React, { PropTypes } from 'react';
import Box from 'grommet-udacity/components/Box';
import Paragraph from 'grommet-udacity/components/Paragraph';
import Article from 'grommet-udacity/components/Article';
import Heading from 'grommet-udacity/components/Heading';
import Markdown from 'grommet-udacity/components/Markdown';
import Section from 'grommet-udacity/components/Section';
import List from 'grommet-udacity/components/List';
import ListItem from 'grommet-udacity/components/ListItem';
import Anchor from 'grommet-udacity/components/Anchor';
// @flow
import React from 'react';
import Box from 'grommet/components/Box';
import Paragraph from 'grommet/components/Paragraph';
import Article from 'grommet/components/Article';
import Heading from 'grommet/components/Heading';
import Markdown from 'grommet/components/Markdown';
import Section from 'grommet/components/Section';
import List from 'grommet/components/List';
import ListItem from 'grommet/components/ListItem';
import Anchor from 'grommet/components/Anchor';
import { Divider } from 'components';
import readme from './_readme.md';

const About = ({
links,
}) => (
<Box align="center">
<Article align="center" className="panel" pad="large">
<Section align="center" justify="center">
<Heading>
Scalable React Boilerplate
</Heading>
<Divider />
</Section>
<Section align="center" justify="center">
<Paragraph>
This project was created to give the Udacity Alumni development team an
incredibly optimized and easy to use React starter project. Included
below is the documentation for the project.
</Paragraph>
<Heading tag="h4" align="center">
Since making this boilerplate, it has been used in dozens of projects.
</Heading>
<Box align="center" pad="medium">
<List>
{links.map((link, i) =>
<ListItem key={i}>
<Anchor href={link.url}>
{link.name}
</Anchor>
</ListItem>,
)}
</List>
</Box>
</Section>
{typeof readme === 'string' &&
<Markdown content={readme} />
}
</Article>
</Box>
);

About.propTypes = {
links: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
}),
),
type AboutLink = {
name: string,
url: string
};

export default About;
export default function About(props: {
links: AboutLink[],
}) {
return (
<Box align="center">
<Article align="center" className="panel" pad="large">
<Section align="center" justify="center">
<Heading>
Scalable React Boilerplate
</Heading>
<Divider />
</Section>
<Section align="center" justify="center">
<Paragraph>
This project was created to give the Udacity Alumni development team an
incredibly optimized and easy to use React starter project. Included
below is the documentation for the project.
</Paragraph>
<Heading tag="h4" align="center">
Since making this boilerplate, it has been used in dozens of projects.
</Heading>
<Box align="center" pad="medium">
<List>
{props.links && props.links.map(link =>
<ListItem key={link.url}>
<Anchor href={link.url}>
{link.name}
</Anchor>
</ListItem>,
)}
</List>
</Box>
</Section>
{typeof readme === 'string' &&
<Markdown content={readme} />
}
</Article>
</Box>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ exports[`<About /> should render with default props 1`] = `
tag="h1">
Scalable React Boilerplate
</Heading>
<undefined />
<Divider />
</Section>
<Section
align="center"
Expand Down Expand Up @@ -65,6 +65,7 @@ exports[`<About /> should render with default props 1`] = `
separator="bottom">
<Anchor
href="https://github.com/udacityalumni/alumni-client"
method="push"
tag="a">
Udacity Alumni Web App
</Anchor>
Expand All @@ -82,6 +83,7 @@ exports[`<About /> should render with default props 1`] = `
separator="bottom">
<Anchor
href="https://github.com/RyanCCollins/react-weekly"
method="push"
tag="a">
React Weekly
</Anchor>
Expand Down
10 changes: 5 additions & 5 deletions app/src/components/AppFooter/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import cssModules from 'react-css-modules';
import Footer from 'grommet-udacity/components/Footer';
import Box from 'grommet-udacity/components/Box';
import Heading from 'grommet-udacity/components/Heading';
import SocialShare from 'grommet-udacity/components/SocialShare';
import Anchor from 'grommet-udacity/components/Anchor';
import Footer from 'grommet/components/Footer';
import Box from 'grommet/components/Box';
import Heading from 'grommet/components/Heading';
import SocialShare from 'grommet/components/SocialShare';
import Anchor from 'grommet/components/Anchor';
import styles from './index.module.scss';

const AppFooter = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
exports[`<AppFooter /> should render with default props 1`] = `
<Footer
align="center"
colorIndex="light-2"
direction="row"
pad="large"
Expand Down Expand Up @@ -35,6 +36,7 @@ exports[`<AppFooter /> should render with default props 1`] = `
<br />
<Anchor
href="https://github.com/RyanCCollins/ryancollinsio"
method="push"
tag="a">
source code.
</Anchor>
Expand Down
Loading