From 51ace69ccb386a7086cd35baf93ecb7ec26fa636 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Wed, 20 Jul 2016 12:26:15 -0700 Subject: [PATCH] Update web-starter --- .eslintrc | 26 ++++++++++++++++++++ modules/client/.eslintrc | 5 ++++ modules/client/components/Layout.js | 5 ++++ modules/client/components/NumberTextInput.js | 3 ++- modules/client/components/Stats.js | 11 ++++++--- modules/server/AssetsUtils.js | 23 +++++++++++++++++ modules/server/MainController.js | 8 ++++-- modules/server/ServerConfig.js | 6 +++-- modules/server/components/HomePage.js | 16 ++++++++---- modules/server/index.js | 5 ++-- package.json | 24 ++++++++++++++---- webpack.config.js | 24 ++++++++++++------ 12 files changed, 127 insertions(+), 29 deletions(-) create mode 100644 .eslintrc create mode 100644 modules/client/.eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..2e92947 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,26 @@ +{ + "parser": "babel-eslint", + "plugins": [ + "import", + "react" + ], + "env": { + "es6": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:import/errors", + "plugin:react/recommended" + ], + "settings": { + "import/resolver": "webpack" + }, + "rules": { + "array-bracket-spacing": [ 2, "always" ], + "eqeqeq": [ 2, "smart" ], + "prefer-arrow-callback": 2, + "react/no-danger": 0, + "semi": [ 2, "never" ] + } +} diff --git a/modules/client/.eslintrc b/modules/client/.eslintrc new file mode 100644 index 0000000..e5a34ae --- /dev/null +++ b/modules/client/.eslintrc @@ -0,0 +1,5 @@ +{ + "env": { + "browser": true + } +} diff --git a/modules/client/components/Layout.js b/modules/client/components/Layout.js index b8551f9..4a128d1 100644 --- a/modules/client/components/Layout.js +++ b/modules/client/components/Layout.js @@ -4,6 +4,11 @@ import { findDOMNode } from 'react-dom' import Window from './Window' class Layout extends React.Component { + static propTypes = { + location: PropTypes.object, + children: PropTypes.node + } + state = { underlineLeft: 0, underlineWidth: 0, diff --git a/modules/client/components/NumberTextInput.js b/modules/client/components/NumberTextInput.js index bcc9ca3..02fab47 100644 --- a/modules/client/components/NumberTextInput.js +++ b/modules/client/components/NumberTextInput.js @@ -5,7 +5,8 @@ class NumberTextInput extends React.Component { static propTypes = { value: PropTypes.number, parseNumber: PropTypes.func, - formatNumber: PropTypes.func + formatNumber: PropTypes.func, + onChange: PropTypes.func } static defaultProps = { diff --git a/modules/client/components/Stats.js b/modules/client/components/Stats.js index b8ed506..c5f1540 100644 --- a/modules/client/components/Stats.js +++ b/modules/client/components/Stats.js @@ -1,5 +1,4 @@ import React, { PropTypes } from 'react' -import { findDOMNode } from 'react-dom' import formatBytes from 'byte-size' import formatDate from 'date-fns/format' import parseDate from 'date-fns/parse' @@ -21,8 +20,12 @@ const addValues = (a, b) => { } class Stats extends React.Component { + static propTypes = { + stats: PropTypes.object + } + static defaultProps = { - stats: window.NPMCDN_STATS + stats: window.npmcdnStats } state = { @@ -83,13 +86,13 @@ class Stats extends React.Component { }) topContinents.forEach(continent => { - const name = ContinentsIndex[continent] + const continentName = ContinentsIndex[continent] const { countries, requests, bandwidth } = continentData[continent] if (bandwidth !== 0) { regionRows.push( - {ContinentsIndex[continent]} + {continentName} {formatNumber(requests)} ({formatPercent(requests / totalRequests)}%) {formatBytes(bandwidth)} ({formatPercent(bandwidth / totalBandwidth)}%) diff --git a/modules/server/AssetsUtils.js b/modules/server/AssetsUtils.js index f4f7da5..c79ebe2 100644 --- a/modules/server/AssetsUtils.js +++ b/modules/server/AssetsUtils.js @@ -31,6 +31,29 @@ const createBundle = (webpackStats) => { } } +/** + * An express middleware that sets req.manifest from the build manifest + * in the given file. Should be used in production to get consistent hashes. + */ +export const assetsManifest = (webpackManifestFile) => { + let manifest + try { + manifest = JSON.parse(fs.readFileSync(webpackManifestFile, 'utf8')) + } catch (error) { + invariant( + false, + 'assetsManifest middleware cannot read the manifest file "%s"; ' + + 'do `npm run build` before starting the server', + webpackManifestFile + ) + } + + return (req, res, next) => { + req.manifest = manifest + next() + } +} + /** * An express middleware that sets req.bundle from the build * info in the given stats file. Should be used in production. diff --git a/modules/server/MainController.js b/modules/server/MainController.js index c98751b..ae26f13 100644 --- a/modules/server/MainController.js +++ b/modules/server/MainController.js @@ -26,11 +26,15 @@ const fetchStats = (callback) => { } export const sendHomePage = (req, res, next) => { + const chunks = [ 'vendor', 'home' ] const props = { - styles: req.bundle.getStyleAssets([ 'vendor', 'home' ]), - scripts: req.bundle.getScriptAssets([ 'vendor', 'home' ]) + styles: req.bundle.getStyleAssets(chunks), + scripts: req.bundle.getScriptAssets(chunks) } + if (req.manifest) + props.webpackManifest = req.manifest + fetchStats((error, stats) => { if (error) { next(error) diff --git a/modules/server/ServerConfig.js b/modules/server/ServerConfig.js index 0100c75..130f043 100644 --- a/modules/server/ServerConfig.js +++ b/modules/server/ServerConfig.js @@ -2,10 +2,12 @@ import path from 'path' export const id = 1 export const port = parseInt(process.env.PORT, 10) || 5000 -export const timeout = parseInt(process.env.TIMEOUT, 10) || 20000 +export const webpackConfig = require('../../webpack.config') export const statsFile = path.resolve(__dirname, '../../stats.json') export const publicDir = path.resolve(__dirname, '../../public') -export const webpackConfig = require('../../webpack.config') +export const manifestFile = path.resolve(publicDir, '__assets__/chunk-manifest.json') +export const timeout = parseInt(process.env.TIMEOUT, 10) || 20000 +export const maxAge = process.env.MAX_AGE || '365d' export const registryURL = process.env.REGISTRY_URL || 'https://registry.npmjs.org' export const bowerBundle = process.env.BOWER_BUNDLE || '/bower.zip' diff --git a/modules/server/components/HomePage.js b/modules/server/components/HomePage.js index f006c88..264c51f 100644 --- a/modules/server/components/HomePage.js +++ b/modules/server/components/HomePage.js @@ -2,33 +2,39 @@ import React, { PropTypes } from 'react' class HomePage extends React.Component { static propTypes = { + webpackManifest: PropTypes.object, styles: PropTypes.arrayOf(PropTypes.string), scripts: PropTypes.arrayOf(PropTypes.string), stats: PropTypes.object } static defaultProps = { + webpackManifest: {}, styles: [], scripts: [], stats: {} } - render = () => { - const { styles, scripts, stats } = this.props + render() { + const { webpackManifest, styles, scripts, stats } = this.props return ( + npmcdn - {styles.map(style => )} -