ff-stream-web

git clone git://archive.git.mtrnord.blog/MTRNord/ff-stream-web.git
Log | Files | Refs | README | LICENSE

commit 7388190d8100c79d4c33f05149156db3ddcae2d7
parent d1b98c9b2e8816dbed6b5bd652bdcbec7deeeb9c
Author: Konstantin Tarkus <hello@tarkus.me>
Date:   Thu, 24 Sep 2015 04:56:32 +0300

Update npm modules; remove lodash; create Html (shell) component

Diffstat:
MREADME.md | 60++++++++++++++++++++++++++++--------------------------------
Mpackage.json | 12++++++------
Asrc/components/Html/Html.js | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/components/Html/package.json | 6++++++
Asrc/config.js | 5+++++
Msrc/server.js | 13++++---------
Dsrc/templates/index.html | 28----------------------------
Mtools/config.js | 2+-
Mtools/copy.js | 9---------
9 files changed, 105 insertions(+), 85 deletions(-)

diff --git a/README.md b/README.md @@ -17,15 +17,15 @@ Join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom ### Documentation - * **General** - - [React Style Guide](./docs/react-style-guide.md) - - [How to configure text editors and IDEs](./docs/how-to-configure-text-editors.md) - * **Questions** - - [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3) - - [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22) - * **Recipes** - - [How to Implement Routing and Navigation](./docs/recipes/how-to-implement-routing.md) - - [How to Integrate Disqus](./docs/recipes/how-to-integrate-disqus.md) + * **General** + - [React Style Guide](./docs/react-style-guide.md) + - [How to configure text editors and IDEs](./docs/how-to-configure-text-editors.md) + * **Questions** + - [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3) + - [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22) + * **Recipes** + - [How to Implement Routing and Navigation](./docs/recipes/how-to-implement-routing.md) + - [How to Integrate Disqus](./docs/recipes/how-to-integrate-disqus.md) ### Directory Layout @@ -35,8 +35,8 @@ Join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom ├── /docs/ # Documentation files for the project ├── /node_modules/ # 3rd-party libraries and utilities ├── /src/ # The source code of the application -│ ├── /api/ # REST API / Relay endpoints │ ├── /actions/ # Action creators that allow to trigger a dispatch to stores +│ ├── /api/ # REST API / Relay endpoints │ ├── /components/ # React components │ ├── /constants/ # Constants (action types etc.) │ ├── /content/ # Static content (plain HTML or Markdown, Jade, you name it) @@ -44,9 +44,10 @@ Join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom │ ├── /decorators/ # Higher-order React components │ ├── /public/ # Static files which are copied into the /build/public folder │ ├── /stores/ # Stores contain the application state and logic -│ ├── /templates/ # HTML templates for server-side rendering, emails etc. │ ├── /utils/ # Utility classes and functions │ ├── /app.js # Client-side startup script +│ ├── /config.js # Global application settings +│ ├── /routes.js # Universal (isomorphic) application routes │ └── /server.js # Server-side startup script ├── /tools/ # Build automation scripts and utilities │ ├── /lib/ # Library for utility snippets @@ -64,8 +65,7 @@ Join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom ### Getting Started -Just [clone](github-windows://openRepo/https://github.com/kriasoft/react-starter-kit) or -[fork](https://github.com/kriasoft/react-starter-kit/fork) the repo and start hacking: +Just clone the repo and start hacking: ```shell $ git clone -o react-starter-kit -b master --single-branch \ @@ -127,33 +127,29 @@ Test any javascript module by creating a `__tests__/` directory where the file is. Name the test by appending `-test.js` to the js file. [Jest](https://facebook.github.io/jest/) will do the rest. -### Customizations - - * [Azure deployment](https://github.com/kriasoft/react-starter-kit/pull/106) - ### Related Projects - * [React Static Boilerplate](https://github.com/koistya/react-static-boilerplate) — Generates a static website from React components - * [Babel Starter Kit](https://github.com/kriasoft/babel-starter-kit) — A boilerplate for authoring JavaScript/React.js libraries - * [React Decorators](https://github.com/kriasoft/react-decorators) — A collection of higher-order React components + * [React Static Boilerplate](https://github.com/koistya/react-static-boilerplate) — Generates a static website from React components + * [Babel Starter Kit](https://github.com/kriasoft/babel-starter-kit) — A boilerplate for authoring JavaScript/React.js libraries + * [React Decorators](https://github.com/kriasoft/react-decorators) — A collection of higher-order React components ### Learn More - * [Getting Started with React.js](http://facebook.github.io/react/) - * [React.js Wiki on GitHub](https://github.com/facebook/react/wiki) - * [React.js Questions on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) - * [React.js Discussion Board](https://discuss.reactjs.org/) - * [Flux Architecture for Building User Interfaces](http://facebook.github.io/flux/) - * [Jest - Painless Unit Testing](http://facebook.github.io/jest/) - * [Flow - A static type checker for JavaScript](http://flowtype.org/) - * [The Future of React](https://github.com/reactjs/react-future) - * [Learn ES6](https://babeljs.io/docs/learn-es6/), [ES6 Features](https://github.com/lukehoban/es6features#readme) + * [Getting Started with React.js](http://facebook.github.io/react/) + * [Getting Started with GraphQL and Relay](https://quip.com/oLxzA1gTsJsE) + * [React.js Questions on StackOverflow](http://stackoverflow.com/questions/tagged/reactjs) + * [React.js Discussion Board](https://discuss.reactjs.org/) + * [Flux Architecture for Building User Interfaces](http://facebook.github.io/flux/) + * [Jest - Painless Unit Testing](http://facebook.github.io/jest/) + * [Flow - A static type checker for JavaScript](http://flowtype.org/) + * [The Future of React](https://github.com/reactjs/react-future) + * [Learn ES6](https://babeljs.io/docs/learn-es6/), [ES6 Features](https://github.com/lukehoban/es6features#readme) ### Support - * [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) on Gitter - * [Live help sessions](http://start.thinkful.com/react/?utm_source=github&utm_medium=badge&utm_campaign=react-starter-kit) on Thinkful - * [@koistya](https://www.codementor.io/koistya) on Codementor + * [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) on Gitter — Feedback, feature requests, Q&A + * [@koistya](https://www.codementor.io/koistya) on Codementor — Mentorship, code reviews + * support@kriasoft.com — Customization requests, help with GraphQL/Relay back-ends etc. ### License diff --git a/package.json b/package.json @@ -14,9 +14,8 @@ "fbjs": "0.2.1", "flux": "2.1.1", "front-matter": "1.0.0", - "history": "1.9.1", + "history": "1.10.1", "jade": "1.11.0", - "lodash": "3.10.1", "normalize.css": "3.0.3", "react": "0.14.0-rc1", "react-dom": "0.14.0-rc1", @@ -28,11 +27,11 @@ "autoprefixer": "^6.0.3", "babel-eslint": "^4.1.3", "babel-loader": "^5.3.2", - "browser-sync": "^2.9.3", - "css-loader": "^0.18.0", + "browser-sync": "^2.9.6", + "css-loader": "^0.19.0", "csscomb": "^3.1.8", "del": "^2.0.2", - "eslint": "^1.5.0", + "eslint": "^1.5.1", "eslint-config-airbnb": "0.0.8", "eslint-loader": "^1.0.0", "eslint-plugin-react": "^3.4.2", @@ -41,9 +40,10 @@ "glob": "^5.0.14", "jest-cli": "^0.5.7", "jscs": "^2.1.1", + "lodash.merge": "^3.3.2", "mkdirp": "^0.5.1", "ncp": "^2.0.0", - "postcss": "^5.0.5", + "postcss": "^5.0.6", "postcss-cssnext": "^2.1.0", "postcss-import": "^7.0.0", "postcss-loader": "^0.6.0", diff --git a/src/components/Html/Html.js b/src/components/Html/Html.js @@ -0,0 +1,55 @@ +/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */ + +import React, { Component, PropTypes } from 'react'; +import { googleAnalyticsId } from '../../config'; + +class Html extends Component { + + static propTypes = { + title: PropTypes.string, + description: PropTypes.string, + css: PropTypes.string, + body: PropTypes.string.isRequired, + }; + + static defaultProps = { + title: '', + description: '', + }; + + goolgeAnalytics() { + // TODO: Change UA-XXXXX-X to be your site's ID. + return ({__html: + `(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=` + + `function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;` + + `e=o.createElement(i);r=o.getElementsByTagName(i)[0];` + + `e.src='https://www.google-analytics.com/analytics.js';` + + `r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));` + + `ga('create','${googleAnalyticsId}','auto');ga('send','pageview');`, + }); + } + + render() { + return ( + <html className="no-js" lang=""> + <head> + <meta charSet="utf-8" /> + <meta httpEquiv="X-UA-Compatible" content="IE=edge" /> + <title>{this.props.title}</title> + <meta name="description" content={this.props.description} /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="apple-touch-icon" href="apple-touch-icon.png" /> + <style id="css" dangerouslySetInnerHTML={{__html: this.props.css}} /> + </head> + <body> + <div id="app" dangerouslySetInnerHTML={{__html: this.props.body}} /> + <script src="/app.js"></script> + <script dangerouslySetInnerHTML={this.goolgeAnalytics()} /> + </body> + </html> + ); + } + +} + +export default Html; diff --git a/src/components/Html/package.json b/src/components/Html/package.json @@ -0,0 +1,6 @@ +{ + "name": "Html", + "version": "0.0.0", + "private": true, + "main": "./Html.js" +} diff --git a/src/config.js b/src/config.js @@ -0,0 +1,5 @@ +/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */ + +export default { + googleAnalyticsId: 'UA-XXXXX-X', +}; diff --git a/src/server.js b/src/server.js @@ -1,12 +1,12 @@ /*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */ import 'babel/polyfill'; -import _ from 'lodash'; -import fs from 'fs'; import path from 'path'; import express from 'express'; +import React from 'react'; import ReactDOM from 'react-dom/server'; import Router from './routes'; +import Html from './components/Html'; const server = global.server = express(); @@ -21,11 +21,6 @@ server.use('/api/content', require('./api/content')); // // Register server-side rendering middleware // ----------------------------------------------------------------------------- - -// The top-level React component + HTML template for it -const templateFile = path.join(__dirname, 'templates/index.html'); -const template = _.template(fs.readFileSync(templateFile, 'utf8')); - server.get('*', async (req, res, next) => { try { let statusCode = 200; @@ -43,8 +38,8 @@ server.get('*', async (req, res, next) => { data.css = css.join(''); }); - const html = template(data); - res.status(statusCode).send(html); + const html = ReactDOM.renderToStaticMarkup(<Html {...data} />); + res.status(statusCode).send('<!doctype html>\n' + html); } catch (err) { next(err); } diff --git a/src/templates/index.html b/src/templates/index.html @@ -1,28 +0,0 @@ -<!doctype html> -<html class="no-js" lang=""> - <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <title><%- title %></title> - <meta name="description" content="<%- description %>"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="apple-touch-icon" href="apple-touch-icon.png"> - <style id="css"><%= css %></style> - </head> - <body> - <!--[if lt IE 8]> - <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> - <![endif]--> - <div id="app"><%= body %></div> - <script src="/app.js"></script> - <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. --> - <script> - (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= - function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; - e=o.createElement(i);r=o.getElementsByTagName(i)[0]; - e.src='//www.google-analytics.com/analytics.js'; - r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); - ga('create','UA-XXXXX-X', 'auto');ga('send','pageview'); - </script> - </body> -</html> diff --git a/tools/config.js b/tools/config.js @@ -9,7 +9,7 @@ import path from 'path'; import webpack, { DefinePlugin, BannerPlugin } from 'webpack'; -import merge from 'lodash/object/merge'; +import merge from 'lodash.merge'; const DEBUG = !process.argv.includes('release'); const VERBOSE = process.argv.includes('verbose'); diff --git a/tools/copy.js b/tools/copy.js @@ -19,18 +19,9 @@ import watch from './lib/watch'; export default async () => { console.log('copy'); await Promise.all([ - - // Static files copy('src/public', 'build/public'), - - // Files with content (e.g. *.md files) copy('src/content', 'build/content'), - - // Website and email templates - copy('src/templates', 'build/templates'), - copy('package.json', 'build/package.json'), - ]); replace({