Skip to content

Commit

Permalink
Always require multiline trailing commas, add nice webpack colors
Browse files Browse the repository at this point in the history
  • Loading branch information
hedgepigdaniel committed Sep 18, 2017
1 parent ec2d810 commit 90412ab
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 110 deletions.
11 changes: 1 addition & 10 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,7 @@ module.exports = {
peerDependencies: true
}
],
'comma-dangle': [
2,
{
arrays: 'never',
objects: 'never',
imports: 'never',
exports: 'never',
functions: 'never'
}
],
'comma-dangle': [2, 'always-multiline'],
'max-len': [
'error',
{
Expand Down
24 changes: 12 additions & 12 deletions server/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const fpVideos = [
tip: `Redux-First Router does not require you to embed actual links into the page
to get the benefit of a synced address bar. Regular actions if matched
will change the URL. That makes it easy to apply to an existing SPA Redux
lacking in routing/URLs!`
lacking in routing/URLs!`,
},
{
youtubeId: 'zBHB9i8e3Kc',
Expand All @@ -45,7 +45,7 @@ const fpVideos = [
color: 'blue',
tip: `Redux reducers programmatically allow you to produce any state you need.
So logically Route Matching components such as in React Reacter only
allow you to do LESS, but with a MORE complicated API.`
allow you to do LESS, but with a MORE complicated API.`,
},
{
youtubeId: 'mty0RwkPmE8',
Expand All @@ -57,8 +57,8 @@ const fpVideos = [
tip: `In your actions.meta.location key passed to your reducers you have all sorts
of information: the previous route, its type and payload, history, whether
the browser back/next buttons were used and if the action was dispatched on load.
Check the "kind" key.`
}
Check the "kind" key.`,
},
]

const reactReduxVideos = [
Expand All @@ -71,7 +71,7 @@ const reactReduxVideos = [
color: 'red',
tip: `Redux-First Router tries in all cases to mirror the Redux API. There is no need
to pass your thunk :params such as in an express request or the like. Just grab it
from the payload stored in the location state.`
from the payload stored in the location state.`,
},
{
youtubeId: 'zD_judE-bXk',
Expand All @@ -83,7 +83,7 @@ const reactReduxVideos = [
tip: `Redux-First Router requires your payload to be objects, as its keys are directionally extracted
and from your URLs and passed from payloads to URL path segments. Your free
to use whatever payload you like for redux actions not connected to your routes. Not all
actions need to be connected to routes.`
actions need to be connected to routes.`,
},
{
youtubeId: 'uvAXVMwHJXU',
Expand All @@ -94,8 +94,8 @@ const reactReduxVideos = [
color: 'red',
tip: `The <Link /> component embeds paths in hrefs for SEO, but you don't need to use it
to get the benefits of a changing address bar. Actions that match routes will
trigger the corresponding URL even if you dispatch them directly.`
}
trigger the corresponding URL even if you dispatch them directly.`,
},
]

const dbGraphqlVideos = [
Expand All @@ -108,7 +108,7 @@ const dbGraphqlVideos = [
color: 'orange',
tip: `The 'thunk' feature is optional, but very useful. Using our 'thunk' feature allows you
to define it in one place while linking to the route from many places without
worrying about getting the data first. It's also very easy to handle server-side.`
worrying about getting the data first. It's also very easy to handle server-side.`,
},
{
youtubeId: '_5VShOmnfQ0',
Expand All @@ -120,7 +120,7 @@ const dbGraphqlVideos = [
tip: `Structure your reducers so that less actions are used to trigger the same state.
Your actions will become more 'page-like'. As a result your reducers
will need to do more "tear down" work when leaving corresponding pages. It's also
recommended to set action types as the capitalized noun name of the page.`
recommended to set action types as the capitalized noun name of the page.`,
},
{
youtubeId: 'm-hre1tt9C4',
Expand All @@ -131,8 +131,8 @@ const dbGraphqlVideos = [
color: 'orange',
tip: `Using a hash of slugs within one of your reducers is the recommended approach to
maintain a normalized set of entities to get the benefits of SEO. This is as opposed
to using IDs. Refrain from using normalizr or Apollo until your app justifies it.`
}
to using IDs. Refrain from using normalizr or Apollo until your app justifies it.`,
},
]

const allVideos = reactReduxVideos.concat(dbGraphqlVideos, fpVideos)
10 changes: 8 additions & 2 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import webpackHotMiddleware from 'webpack-hot-middleware'
import webpackHotServerMiddleware from 'webpack-hot-server-middleware'
import clientConfig from '../webpack/client.dev'
import serverConfig from '../webpack/server.dev'
import statsOptions from '../webpack/stats.config'
import { findVideos, findVideo } from './api'

const DEV = process.env.NODE_ENV === 'development'
Expand Down Expand Up @@ -50,12 +51,17 @@ if (DEV) {
const multiCompiler = webpack([clientConfig, serverConfig])
const clientCompiler = multiCompiler.compilers[0]

app.use(webpackDevMiddleware(multiCompiler, { publicPath }))
app.use(
webpackDevMiddleware(multiCompiler, {
publicPath,
stats: statsOptions,
})
)
app.use(webpackHotMiddleware(clientCompiler))
app.use(
// keeps serverRender updated with arg: { clientStats, outputPath }
webpackHotServerMiddleware(multiCompiler, {
serverRendererOptions: { outputPath }
serverRendererOptions: { outputPath },
})
)
}
Expand Down
12 changes: 6 additions & 6 deletions src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@ import { NOT_FOUND } from 'redux-first-router'

export const goToPage = (type, category) => ({
type,
payload: category && { category }
payload: category && { category },
})

export const goHome = () => ({
type: 'HOME'
type: 'HOME',
})

export const goToAdmin = () => ({
type: 'ADMIN'
type: 'ADMIN',
})

export const notFound = () => ({
type: NOT_FOUND
type: NOT_FOUND,
})

export const visitCategory = category => ({
type: 'LIST',
payload: { category }
payload: { category },
})

export const visitVideo = slug => ({
type: 'VIDEO',
payload: { slug }
payload: { slug },
})
4 changes: 2 additions & 2 deletions src/components/Switcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import styles from '../css/Switcher'
const UniversalComponent = universal(({ page }) => import(`./${page}`), {
minDelay: 500,
loading: Loading,
error: Err
error: Err,
})

const Switcher = ({ page, direction, isLoading }) =>
Expand All @@ -28,7 +28,7 @@ const Switcher = ({ page, direction, isLoading }) =>
const mapState = ({ page, direction, ...state }) => ({
page,
direction,
isLoading: isLoading(state)
isLoading: isLoading(state),
})

export default connect(mapState)(Switcher)
2 changes: 1 addition & 1 deletion src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default {
alert(alertMessage)
}, 1500)
}
}
},
}

const alertMessage =
Expand Down
2 changes: 1 addition & 1 deletion src/reducers/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const components = {
VIDEO: 'Video',
ADMIN: 'Admin',
LOGIN: 'Login',
[NOT_FOUND]: 'NotFound'
[NOT_FOUND]: 'NotFound',
}

// NOTES: this is the primary reducer demonstrating how RFR replaces the need
Expand Down
12 changes: 6 additions & 6 deletions src/routesMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default {
const {
jwToken,
location: { payload: { category } },
videosByCategory
videosByCategory,
} = getState()

if (videosByCategory[category]) return
Expand All @@ -20,7 +20,7 @@ export default {
}

dispatch({ type: 'VIDEOS_FETCHED', payload: { videos, category } })
}
},
},
VIDEO: {
path: '/video/:slug',
Expand All @@ -32,7 +32,7 @@ export default {
// using fetchData(`/api/video/${slug}`) and by dispatching
// the the corresponding action type which I'll leave up to you to find
// in ../reducers/index.js :)
}
},
},
PLAY: {
path: '/video/:slug/play',
Expand All @@ -43,13 +43,13 @@ export default {

dispatch(action)
}
}
},
},
LOGIN: '/login',
ADMIN: {
path: '/admin', // TRY: visit this path or dispatch ADMIN
role: 'admin' // + change jwToken to 'real' in server/index.js
}
role: 'admin', // + change jwToken to 'real' in server/index.js
},
}

// DON'T GO DOWN THERE!
Expand Down
2 changes: 1 addition & 1 deletion src/selectors/isLoading.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default createSelector(
state => state.location.type,
state => state.location.payload,
state => state.videosHash,
state => state.videosByCategory
state => state.videosByCategory,
],
(type, { slug, category }, hash1, hash2) => {
if (type === 'VIDEO') return !hash1[slug]
Expand Down
6 changes: 3 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const fetchData = async (path, jwToken) =>
fetch(`http://localhost:3000${path}`, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${jwToken || ''}`
}
Authorization: `Bearer ${jwToken || ''}`,
},
}).then(data => data.json())

export const isAllowed = (type, state) => {
Expand All @@ -32,7 +32,7 @@ export const isAllowed = (type, state) => {
const fakeUser = { roles: ['admin'] }
const userFromState = ({ jwToken, user }) => jwToken === 'real' && fakeUser
const jwt = {
verify: (jwToken, secret) => jwToken === 'real' && fakeUser
verify: (jwToken, secret) => jwToken === 'real' && fakeUser,
}

// NOTE ON COOKIES:
Expand Down
38 changes: 20 additions & 18 deletions webpack/client.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const webpack = require('webpack')
const WriteFilePlugin = require('write-file-webpack-plugin')
const AutoDllPlugin = require('autodll-webpack-plugin')
const ExtractCssChunks = require('extract-css-chunks-webpack-plugin')
const statsOptions = require('./stats.config')

module.exports = {
name: 'client',
Expand All @@ -14,20 +15,20 @@ module.exports = {
'fetch-everywhere',
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=false&quiet=false&noInfo=false',
'react-hot-loader/patch',
path.resolve(__dirname, '../src/index.js')
path.resolve(__dirname, '../src/index.js'),
],
output: {
filename: '[name].js',
chunkFilename: '[name].js',
path: path.resolve(__dirname, '../buildClient'),
publicPath: '/static/'
publicPath: '/static/',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
use: 'babel-loader',
},
{
test: /\.css$/,
Expand All @@ -36,31 +37,31 @@ module.exports = {
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]'
}
}
})
}
]
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
}),
},
],
},
resolve: {
extensions: ['.js', '.css']
extensions: ['.js', '.css'],
},
plugins: [
new WriteFilePlugin(), // used so you can see what chunks are produced in dev
new ExtractCssChunks(),
new webpack.optimize.CommonsChunkPlugin({
names: ['bootstrap'], // needed to put webpack bootstrap code before chunks
filename: '[name].js',
minChunks: Infinity
minChunks: Infinity,
}),

new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
NODE_ENV: JSON.stringify('development'),
},
}),
new AutoDllPlugin({
context: path.join(__dirname, '..'),
Expand All @@ -77,9 +78,10 @@ module.exports = {
'redux-first-router-link',
'fetch-everywhere',
'babel-polyfill',
'redux-devtools-extension/logOnlyInProduction'
]
}
})
]
'redux-devtools-extension/logOnlyInProduction',
],
},
}),
],
stats: statsOptions,
}
Loading

0 comments on commit 90412ab

Please sign in to comment.