Skip to content

Commit

Permalink
V0.1.7 (#16)
Browse files Browse the repository at this point in the history
* Switch to Fractal pattern with CSS modules based on [redux-starter-kit](https://github.com/davezuko/react-redux-starter-kit)
* `redux-firebasev3` updated to v0.1.6
* coverage being sent to Codecov
* Outputted `README.md` matches new application format
* Deploy section of outputted `README.md` matches choice
* Tests updated to match new format
  • Loading branch information
prescottprue authored Sep 26, 2016
1 parent 77c1b15 commit 34d38bf
Show file tree
Hide file tree
Showing 346 changed files with 9,820 additions and 5,163 deletions.
2 changes: 1 addition & 1 deletion .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exclude_paths:
- "README.md"
- "config.json"
- "package.json"
- "generators/**/templates"
- "generators/**/templates/**"

engines:
duplication:
Expand Down
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ branches:
only:
- master

script: npm run test && npm run test:cov
script:
- npm run test


addons:
code_climate:
Expand All @@ -16,3 +18,4 @@ addons:
after_success:
- npm install -g codeclimate-test-reporter
- codeclimate-test-reporter < coverage/*/lcov.info
- npm run codecov
75 changes: 47 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ npm install -g generator-react-firebase
## Project

### Development
Run `npm start` to start live reloading development server
Run `npm run dev` to start live reloading development server

### Production

Expand Down Expand Up @@ -81,7 +81,6 @@ To deploy:
* `HEROKU_KEY` - Your Heroku API key
* `HEROKU_APP` - Your Heroku App name


## Sub generators

Sub generators are included to help speed up the application building process. You can run a sub-generator by calling `yo react-firebase:<name of sub-generator> <param1>`.
Expand All @@ -108,16 +107,12 @@ A component is best for things that will be reused in multiple places. Our examp

```javascript
import React, { Component, PropTypes } from 'react'
import './Car.scss'
import classes from './Car.scss'

export default class Car extends Component {
constructor (props) {
super(props)
}

render () {
return (
<div className="Car">
<div className={classes['container']}>

</div>
)
Expand Down Expand Up @@ -147,41 +142,63 @@ Creates a folder within `/containers` that matches the name provided. Below is t
/app/containers/Cars.js:
```javascript
import React, { Component, PropTypes } from 'react'
import { firebase, helpers } from 'redux-react-firebase'

import './Cars.scss'

const { isLoaded, isEmpty, dataToJS, pathToJS } = helpers

import './Login.scss'
import { connect } from 'react-redux'
import { firebase, helpers } from 'redux-firebasev3'
const { isLoaded, isEmpty, dataToJS } = helpers

// Props decorators
@firebase([
'cars'
// Syncs todos root
'/todos'
])
@connect(
({firebase}) => ({
authError: pathToJS(firebase, 'authError'),
profile: pathToJS(firebase, 'profile')
// Place list of todos into this.props.todos
todos: dataToJS(firebase, '/todos'),
})
)
export default class Cars extends Component {
constructor (props) {
super(props)
}

class Todos extends Component {
static propTypes = {

todos: PropTypes.object,
firebase: PropTypes.object
}

render () {
return (
<div className="Cars">
render() {
const { firebase, todos } = this.props;

// Add a new todo to firebase
const handleAdd = () => {
const {newTodo} = this.refs
firebase.push('/todos', { text:newTodo.value, done:false })
newTodo.value = ''
}

// Build Todos list if todos exist and are loaded
const todosList = !isLoaded(todos)
? 'Loading'
: isEmpty(todos)
? 'Todo list is empty'
: Object.keys(todos).map(
(key, id) => (
<TodoItem key={key} id={id} todo={todos[key]}/>
)
)

return (
<div>
<h1>Todos</h1>
<ul>
{todosList}
</ul>
<input type="text" ref="newTodo" />
<button onClick={handleAdd}>
Add
</button>
</div>
)
}
}
export default Todos
```

## Examples
Expand All @@ -196,8 +213,10 @@ In order to enable server-side rendering with React, you must host a NodeJS serv


## In the future
* Container Generator - Prompt for props/state vars (which Firebase location to bind to props)
* Non-decorators implementation for props binding (pure redux and firebase implementations)
* Option to use simple file structure instead of fractal pattern
* Smart Container Generator - Prompt for props/state vars (which Firebase location to bind to props)
* Store previous answers and use them as defaults
* Open to ideas

## License
Expand Down
10 changes: 8 additions & 2 deletions examples/react-firebase-redux/.babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// NOTE: These options are overriden by the babel-loader configuration
// for webpack, which can be found in ~/build/webpack.config.
//
// Why? The react-transform-hmr plugin depends on HMR (and throws if
// module.hot is disabled), so keeping it and related plugins contained
// within webpack helps prevent unexpected errors.
{
"presets": ["es2015", "stage-0", "react"],
"plugins": ["lodash", "transform-decorators-legacy"]
"presets": ["es2015", "react", "stage-0"],
"plugins": ["lodash", "transform-decorators-legacy", "transform-runtime"]
}
2 changes: 2 additions & 0 deletions examples/react-firebase-redux/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ npm-debug.log
stats.json
.DS_Store
**/.DS_Store
build
coverage
182 changes: 162 additions & 20 deletions examples/react-firebase-redux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,180 @@
[![License][license-image]][license-url]
[![Code Style][code-style-image]][code-style-url]


## Table of Contents
1. [Features](#features)
1. [Requirements](#requirements)
1. [Getting Started](#getting-started)
1. [Application Structure](#application-structure)
1. [Development](#development)
1. [Developer Tools](#developer-tools)
1. [Routing](#routing)
1. [Testing](#testing)
1. [Deployment](#deployment)
1. [Build System](#build-system)
1. [Configuration](#configuration)
1. [Globals](#globals)
1. [Styles](#styles)
1. [Server](#server)
1. [Production Optimization](#production-optimization)

## Requirements
* node `^4.5.0`
* npm `^3.0.0`

## Getting Started

1. Install dependencies: `npm install`

2. Start Development server: `npm start`

If everything works, you should see the following:

<img src="http://i.imgur.com/zR7VRG6.png?2" />

While developing, you will probably rely mostly on `npm start`; however, there are additional scripts at your disposal:

|`npm run <script>`|Description|
|------------------|-----------|
|`start`|Serves your app at `localhost:3000`. HMR will be enabled in development.|
|`compile`|Compiles the application to disk (`~/dist` by default).|
|`dev`|Same as `npm start`, but enables nodemon for the server as well.|
|`test`|Runs unit tests with Karma and generates a coverage report.|
|`test:dev`|Runs Karma and watches for changes to re-run tests; does not generate coverage reports.|
|`build`|Runs linter, tests, and then, on success, compiles your application to disk.|
|`build:dev`|Same as `build` but overrides `NODE_ENV` to "development".|
|`build:prod`|Same as `build` but overrides `NODE_ENV` to "production".|
|`lint`|Lint all `.js` files.|
|`lint:fix`|Lint and fix all `.js` files. [Read more on this](http://eslint.org/docs/user-guide/command-line-interface.html#fix).|

## Application Structure

The application structure presented in this boilerplate is **fractal**, where functionality is grouped primarily by feature rather than file type. Please note, however, that this structure is only meant to serve as a guide, it is by no means prescriptive. That said, it aims to represent generally accepted guidelines and patterns for building scalable applications. If you wish to read more about this pattern, please check out this [awesome writeup](https://github.com/davezuko/react-redux-starter-kit/wiki/Fractal-Project-Structure) by [Justin Greenberg](https://github.com/justingreenberg).

```
.
├── bin # Build/Start scripts
├── blueprints # Blueprint files for redux-cli
├── build # All build-related configuration
│ └── webpack # Environment-specific configuration files for webpack
├── config # Project configuration settings
├── server # Express application that provides webpack middleware
│ └── main.js # Server application entry point
├── src # Application source code
│ ├── index.html # Main HTML page container for app
│ ├── main.js # Application bootstrap and rendering
│ ├── components # Global Reusable Presentational Components
│ ├── containers # Global Reusable Container Components
│ ├── layouts # Components that dictate major page structure
│ ├── redux # "Ducks" location...
│ │ └── modules # reducer, action, creators not part of a route
│ ├── routes # Main route definitions and async split points
│ │ ├── index.js # Bootstrap main application routes with store
│ │ └── Home # Fractal route
│ │ ├── index.js # Route definitions and async split points
│ │ ├── assets # Assets required to render components
│ │ ├── components # Presentational React Components
│ │ ├── container # Connect components to actions and store
│ │ ├── modules # Collections of reducers/constants/actions
│ │ └── routes ** # Fractal sub-routes (** optional)
│ ├── static # Static assets (not imported anywhere in source code)
│ ├── store # Redux-specific pieces
│ │ ├── createStore.js # Create and instrument redux store
│ │ └── reducers.js # Reducer registry and injection
│ └── styles # Application-wide styles (generally settings)
└── tests # Unit tests
```

## Development

#### Developer Tools

**We recommend using the [Redux DevTools Chrome Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd).**
Using the chrome extension allows your monitors to run on a separate thread and affords better performance and functionality. It comes with several of the most popular monitors, is easy to configure, filters actions, and doesn’t require installing any packages.

However, adding the DevTools components to your project is simple. First, grab the packages from npm:

```bash
npm i --save-dev redux-devtools redux-devtools-log-monitor redux-devtools-dock-monitor
```

Then follow the [manual integration walkthrough](https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md).

### Routing
We use `react-router` [route definitions](https://github.com/reactjs/react-router/blob/master/docs/API.md#plainroute) (`<route>/index.js`) to define units of logic within our application. See the [application structure](#application-structure) section for more information.

## Testing
To add a unit test, simply create a `.spec.js` file anywhere in `~/tests`. Karma will pick up on these files automatically, and Mocha and Chai will be available within your test without the need to import them. Coverage reports will be compiled to `~/coverage` by default. If you wish to change what reporters are used and where reports are compiled, you can do so by modifying `coverage_reporters` in `~/config/index.js`.

## Deployment
Out of the box, this starter kit is deployable by serving the `~/dist` folder generated by `npm run deploy` (make sure to specify your target `NODE_ENV` as well). This project does not concern itself with the details of server-side rendering or API structure, since that demands an opinionated structure that makes it difficult to extend the starter kit. However, if you do need help with more advanced deployment strategies, here are a few tips:

### Static Deployments
If you are serving the application via a web server such as nginx, make sure to direct incoming routes to the root `~/dist/index.html` file and let react-router take care of the rest. If you are unsure of how to do this, you might find [this documentation](https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#configuring-your-server) helpful. The Express server that comes with the starter kit is able to be extended to serve as an API or whatever else you need, but that's entirely up to you.

## Build System

### Configuration

Default project configuration can be found in `~/config/index.js`. Here you'll be able to redefine your `src` and `dist` directories, adjust compilation settings, tweak your vendor dependencies, and more. For the most part, you should be able to make changes in here **without ever having to touch the actual webpack build configuration**.

If you need environment-specific overrides (useful for dynamically setting API endpoints, for example), you can edit `~/config/environments.js` and define overrides on a per-NODE_ENV basis. There are examples for both `development` and `production`, so use those as guidelines. Here are some common configuration options:

|Key|Description|
|---|-----------|
|`dir_src`|application source code base path|
|`dir_dist`|path to build compiled application to|
|`server_host`|hostname for the Express server|
|`server_port`|port for the Express server|
|`compiler_devtool`|what type of source-maps to generate (set to `false`/`null` to disable)|
|`compiler_vendor`|packages to separate into to the vendor bundle|

Webpack is configured to make use of [resolve.root](http://webpack.github.io/docs/configuration.html#resolve-root), which lets you import local packages as if you were traversing from the root of your `~/src` directory. Here's an example:

```js
// current file: ~/src/views/some/nested/View.js
// What used to be this:
import SomeComponent from '../../../components/SomeComponent'

// Can now be this:
import SomeComponent from 'components/SomeComponent' // Hooray!
```

### Globals

These are global variables available to you anywhere in your source code. If you wish to modify them, they can be found as the `globals` key in `~/config/index.js`. When adding new globals, make sure you also add them to `~/.eslintrc`.

|Variable|Description|
|---|---|
|`process.env.NODE_ENV`|the active `NODE_ENV` when the build started|
|`__DEV__`|True when `process.env.NODE_ENV` is `development`|
|`__PROD__`|True when `process.env.NODE_ENV` is `production`|
|`__TEST__`|True when `process.env.NODE_ENV` is `test`|

### Styles

Both `.scss` and `.css` file extensions are supported out of the box. After being imported, styles will be processed with [PostCSS](https://github.com/postcss/postcss) for minification and autoprefixing, and will be extracted to a `.css` file during production builds.

### Server

This starter kit comes packaged with an Express server. It's important to note that the sole purpose of this server is to provide `webpack-dev-middleware` and `webpack-hot-middleware` for hot module replacement. Using a custom Express app in place of [webpack-dev-server](https://github.com/webpack/webpack-dev-server) makes it easier to extend the starter kit to include functionality such as API's, universal rendering, and more -- all without bloating the base boilerplate.

### Production Optimization

Babel is configured to use [babel-plugin-transform-runtime](https://www.npmjs.com/package/babel-plugin-transform-runtime) so transforms aren't inlined. In production, webpack will extract styles to a `.css` file, minify your JavaScript, and perform additional optimizations such as module deduplication.

## Learning Resources

* [Starting out with react-redux-starter-kit](https://suspicious.website/2016/04/29/starting-out-with-react-redux-starter-kit/) is an introduction to the components used in this starter kit with a small example in the end.


### Production

Build code before deployment by running `npm run build`. There are multiple options below for types of deployment, if you are unsure, checkout the Firebase section.

### Deployment

#### Firebase

1. Login to [Firebase](firebase.google.com) (or Signup if you don't have an account) and create a new project
2. Install cli: `npm i -g firebase-tools`
3. Login: `firebase login`
Expand All @@ -33,27 +193,9 @@ Build code before deployment by running `npm run build`. There are multiple opti
6. Confirm Firebase config by running locally: `firebase serve`
7. Deploy to firebase: `firebase deploy`

#### AWS S3

Selecting AWS S3 from the deploy options when running the generator adds deploy configs in `.travis.yml`.

1. Get your AWS Key and Secret from the AWS Console Credentials page
2. Set the following environment vars within the Travis-CI repo settings page:
* AWS_KEY - Your AWS key
* AWS_SECRET - Your AWS secret
* BUCKET - Your S3 Bucket

#### Heroku

Selecting [Heroku](http://heroku.com) from the deploy options when running the generator adds a `Procfile` as well as deploy configs in `.travis.yml` for out of the box deployment.

To deploy to [Heroku](http://heroku.com) through [Travis-CI](http://travis-ci.org):
1. Enable Repo on Travis-CI Account
2. Get API Key from Heroku Dashboard
3. Create a new App (this name will be used in travis env var)
4. Set the following environment vars within the Travis-CI repo settings page:
* HEROKU_KEY - Your Heroku API key
* APP - Your Heroku App name


[npm-image]: https://img.shields.io/npm/v/react-firebase-redux.svg?style=flat-square
Expand Down
Loading

0 comments on commit 34d38bf

Please sign in to comment.