rca-precursor
Advanced tools
Comparing version 0.1.25 to 0.1.26
@@ -14,5 +14,5 @@ import { argv } from 'yargs'; | ||
` | ||
Generating output bundle for ${appName} | ||
Generating output bundle for ${appName}! | ||
`); | ||
createOutputBundle(userConfig); |
{ | ||
"name": "rca-precursor", | ||
"version": "0.1.25", | ||
"version": "0.1.26", | ||
"repository": "git@git.realestate.com.au:craig-collie/rca-precursor.git", | ||
@@ -32,10 +32,5 @@ "author": "Craig Collie <craig.collie@rea-group.com>", | ||
"devDependencies": { | ||
"express": "^4.15.3", | ||
"lodash": "^4.17.4", | ||
"react": "^15.6.1", | ||
"react-dom": "^15.6.1", | ||
"react-router": "^4.1.2", | ||
"react-router-dom": "^4.1.2", | ||
"babel-eslint": "^7.2.3", | ||
"babel-loader": "^7.1.1", | ||
"babel-plugin-root-import": "^5.1.0", | ||
"babel-polyfill": "^6.23.0", | ||
@@ -48,13 +43,31 @@ "babel-preset-env": "^1.6.0", | ||
"chai": "^4.1.0", | ||
"chunk-manifest-webpack-plugin": "1.1.0", | ||
"compose-middleware": "^3.0.0", | ||
"concurrently": "^3.5.0", | ||
"css-loader": "^0.28.4", | ||
"css-modules-require-hook": "^4.0.6", | ||
"enzyme": "^2.9.1", | ||
"eslint": "^3.19.0", | ||
"eslint-config-airbnb": "^14.1.0", | ||
"eslint-import-resolver-babel-root-import": "^0.0.2", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-jsx-a11y": "^4.0.0", | ||
"eslint-plugin-react": "^6.10.3", | ||
"express": "^4.15.3", | ||
"extract-text-webpack-plugin": "^3.0.0", | ||
"flow-bin": "^0.52.0", | ||
"fs-extra": "^4.0.0", | ||
"html-webpack-plugin": "^2.29.0", | ||
"jsdom": "9.12.0", | ||
"jsdom-global": "^3.0.2", | ||
"lodash": "^4.17.4", | ||
"mocha": "^3.4.2", | ||
"path": "^0.12.7", | ||
"postcss-cssnext": "^3.0.2", | ||
"postcss-import": "^10.0.0", | ||
"postcss-loader": "^2.0.6", | ||
"react": "^15.6.1", | ||
"react-dom": "^15.6.1", | ||
"react-router": "^4.1.2", | ||
"react-router-dom": "^4.1.2", | ||
"react-test-renderer": "^15.6.1", | ||
@@ -64,6 +77,4 @@ "require-ensure": "^1.0.2", | ||
"sinon": "^3.0.0", | ||
"style-loader": "^0.18.2", | ||
"uglifyjs-webpack-plugin": "^0.4.6", | ||
"webpack-node-externals": "^1.6.0", | ||
"yargs": "^8.0.2", | ||
"style-loader": "^0.18.2", | ||
"webpack": "^3.3.0", | ||
@@ -73,14 +84,5 @@ "webpack-chunk-hash": "^0.4.0", | ||
"webpack-hot-middleware": "^2.18.2", | ||
"postcss-cssnext": "^3.0.2", | ||
"postcss-import": "^10.0.0", | ||
"postcss-loader": "^2.0.6", | ||
"extract-text-webpack-plugin": "^3.0.0", | ||
"fs-extra": "^4.0.0", | ||
"html-webpack-plugin": "^2.29.0", | ||
"chunk-manifest-webpack-plugin": "1.1.0", | ||
"compose-middleware": "^3.0.0", | ||
"css-loader": "^0.28.4", | ||
"css-modules-require-hook": "^4.0.6", | ||
"path": "^0.12.7" | ||
"webpack-node-externals": "^1.6.0", | ||
"yargs": "^8.0.2" | ||
} | ||
} |
184
README.md
@@ -1,2 +0,2 @@ | ||
# Precursor (Precursor) | ||
# RCA-Precursor | ||
@@ -29,3 +29,185 @@ ## Quick start guide | ||
``` | ||
# Configuration | ||
## Required settings | ||
#### appName | ||
The name of your application. | ||
#### entry | ||
Configure your webpack bundles using the `entry` configuration. | ||
```js | ||
{ | ||
entry: { | ||
main: './utils/client.js', | ||
} | ||
} | ||
``` | ||
#### root | ||
Default: `./src/App.js` | ||
The root application component. By default, this component receives `serverProps` which is any resolved route data. | ||
```js | ||
import React from 'react'; | ||
const App = serverProps => ( | ||
<div> | ||
//... | ||
</div> | ||
); | ||
export default App; | ||
``` | ||
#### routes | ||
An collection of routes that both the server and client will both used. Routes follow the standard `react-router` guidelines for defining a route. These rounds should be exported as an array. | ||
```js | ||
export default [ | ||
{ | ||
path: '/', | ||
exact: true, | ||
component: //..., | ||
}, | ||
{ | ||
path: '/pages/:pageId', | ||
component: //..., | ||
}, | ||
{ | ||
path: null, | ||
component: //..., | ||
}, | ||
]; | ||
``` | ||
--- | ||
## Environment flags | ||
#### isDevEnvironment | ||
_Default: _`process.env.NODE_ENV` | ||
Sets a flag against the current `NODE_ENV` allowing for both `express` and `webpack` to run in production mode. | ||
--- | ||
## Bundle output | ||
#### context | ||
_Default_: `<root>/src/` | ||
The contextual path of your application source folder. | ||
#### distOutput | ||
_Default_: `/public` | ||
The output folder that is created and published to when building and deploying your application. | ||
#### jsPath | ||
_Default_: `/js` | ||
The output folder for all bundled javascript. | ||
#### cssPath | ||
_Default_: `/css` | ||
The output folder for all bundled CSS. | ||
#### publicPath | ||
_Default_: `/` | ||
A prefix that is added to all outputted assets, generally used when you need to configure a CDN. | ||
#### indexFile | ||
_Default_: `index.html` | ||
The index filename of your application | ||
--- | ||
## Plugin settings | ||
#### localIdentName | ||
The className output for CSS-Modules | ||
# Routes | ||
## Getting started | ||
Routes are the pages of your application, and usually require a few properties to ensure they work correctly. Each **Route** should contain the `path` property, which defines the `URL` path. For example, consider `http://www.myapp.com/admin`, to ensure your `admin` route is visible when the user visits that `URL`, the following route would need to be created: | ||
```js | ||
{ | ||
path: '/admin', | ||
exact: true, | ||
component: AdminContainer, | ||
}, | ||
``` | ||
In this route definition, the `path` and `exact` properties ensure that when the user visits `http://www.myapp.com/admin` this route is visible, and that the `AdminContainer` component is rendered. | ||
## Creating a route component \(Container\) | ||
Route components, or **Containers** are the components that render routes for your application. **Containers** are the components that connect to your external **API's** and provide data to any components that live inside them. Each **Container** you create comes with some additional static methods and properties that allow you to express how data is **requests** and **cached**. | ||
Consider the below example: | ||
```js | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
// Any service that performs an ajax request | ||
import fetchService from './fetchService'; | ||
class RouteContainer extends Component { | ||
static getInitialProps = () => fetchService() | ||
static cache = true | ||
render() { | ||
const { data } = this.props; | ||
return ( | ||
<div> | ||
// ... | ||
</div> | ||
); | ||
} | ||
} | ||
export default RouteContainer; | ||
``` | ||
This **Container** is a standard, stateful **React Component** with the addition of the `static getInitialProps` method, which requests the `fetchService()`. This **fetchService** is completely made up at this state, and we don't need to know how it connects to an API, rather, we just need to know that it does. | ||
### static getInitialProps\(\) \[Promise<expression>\] | ||
When defining your **Container**, including this static method will ensure that whatever request is required to be called, it is called and the response is returned **BEFORE** the rendering of this route. This means that if your **Route** requires things to be rendered based on some data that comes back from `fetchService()` then all of the rendering will be done first, before it is visually available to your user. | ||
> #### Why is this a good thing? | ||
> | ||
> You don't necessarily need to do this in your application, however if you prefer to present visually complete pages to your user, or have concerns around SEO, it can usually be a good idea request first, and present later. | ||
After making this initial request, the data returned from that initial call will yield `this.props.data` in your **Container**. | ||
### static cache \[boolean\] | ||
Every single time a **Route** is rendered, it will refresh it's data, and call the `static getInitialProps` method. If this is something you want to avoid, in which case stale data isn't a concern to you, then add the `static cache = true` property to your **Container**. | ||
## Technology Stack | ||
@@ -32,0 +214,0 @@ | Tech | Description | |
@@ -12,2 +12,3 @@ import path from 'path'; | ||
publicPath: '/assets/', | ||
indexFile: 'index.html', | ||
staticAssetsPath: '/public/assets', | ||
@@ -14,0 +15,0 @@ localIdentName: '[name]__[local]', |
@@ -1,2 +0,1 @@ | ||
export UniversalRoute from './components/UniversalRoute'; | ||
export RoutePreloader from './components/RoutePreloader'; | ||
export UniversalRouter from './components/UniversalRouter'; |
import { compose } from 'compose-middleware'; | ||
import compiler from './compiler/compiler'; | ||
import token from './token/token'; | ||
import universal from './universal/universal'; | ||
import compiler from './compiler'; | ||
import token from './token'; | ||
import universal from './universal'; | ||
const middleware = [compiler, token, universal]; | ||
// Middleware that doesn't require composition | ||
export applyStaticHandlers from './static/static'; | ||
export errorHandler from './error/error'; | ||
export default (app, config) => compose( | ||
middleware.map(m => m(app, config)), | ||
); |
// @flow | ||
import express from 'express'; | ||
import type { $Request, $Response } from 'express'; | ||
import type { IConfig } from '@/IConfig'; | ||
import type { IApp } from '@/IApp'; | ||
import { getMessage } from './../tools/messaging'; | ||
import composedMiddleware, { applyStaticHandlers, errorHandler } from './middleware'; | ||
import applyStaticHandler from './handlers/staticHandler'; | ||
import errorHandler from './handlers/errorHandler'; | ||
import composedMiddleware from './middleware'; | ||
@@ -11,5 +15,2 @@ import hooks from './../tools/hooks'; | ||
import type { IConfig } from './../flow/IConfig'; | ||
import type { IApp } from './../flow/IApp'; | ||
// Run hooks before | ||
@@ -25,3 +26,3 @@ // starting application | ||
this.config = { ...defaultConfig, ...config }; | ||
this.app = applyStaticHandlers(express(), this.config); | ||
this.app = applyStaticHandler(express(), this.config); | ||
} | ||
@@ -28,0 +29,0 @@ |
@@ -6,6 +6,3 @@ // @flow | ||
const fetchInitialProps = ( | ||
getInitialProps: Function, | ||
routeParams: RouteParams, | ||
): Object => ( | ||
const fetchInitialProps = (getInitialProps: Function, routeParams: RouteParams): Object => ( | ||
hasInitialFetch(getInitialProps) | ||
@@ -12,0 +9,0 @@ ? Promise.resolve(getInitialProps(routeParams)) |
@@ -6,6 +6,3 @@ // @flow | ||
function getParamsFromUrl( | ||
routePath: ?string, | ||
urlPath: string, | ||
): ?UrlParams { | ||
function getParamsFromUrl(routePath: ?string, urlPath: string): ?UrlParams { | ||
if (!routePath) { | ||
@@ -12,0 +9,0 @@ return null; |
@@ -8,1 +8,2 @@ export fetchInitialProps from './fetchInitialProps/fetchInitialProps'; | ||
export getRouteComponent from './getRouteComponent/getRouteComponent'; | ||
export resolveInitialProps from './resolveInitialProps/resolveInitialProps'; |
// @flow | ||
import type { IRoute } from './../../../flow/IRoute'; | ||
export default ( | ||
routes: Array<IRoute>, | ||
url: string, | ||
): IRoute => { | ||
export default (routes: Array<IRoute>, url: string): IRoute => { | ||
let foundRoute = routes.filter(({ path }) => { | ||
@@ -9,0 +6,0 @@ if (!path) { |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
203588
44
222
51
1136
9