ff-stream-web

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

commit 2fe7a9c40bbc22a3d28b83e21cf558b54078de3f
parent a17c01f7200c68970ddf7f2ed5c2dd6d1e1bbb5a
Author: Konstantin Tarkus <hello@tarkus.me>
Date:   Sun,  5 Oct 2014 14:34:00 +0400

Add pre-rendering at compile-time. Issue #4

Diffstat:
Mgulpfile.js | 24++++++++++++++++++++----
Mpackage.json | 5++++-
Msrc/App.js | 6++++--
Msrc/components/Link.jsx | 3+--
Dsrc/pages/HomePage.jsx | 49-------------------------------------------------
Asrc/pages/Index.jsx | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/pages/Privacy.jsx | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/pages/PrivacyPage.jsx | 62--------------------------------------------------------------
Asrc/pages/_template.html | 27+++++++++++++++++++++++++++
Dsrc/pages/index.html | 28----------------------------
10 files changed, 178 insertions(+), 148 deletions(-)

diff --git a/gulpfile.js b/gulpfile.js @@ -87,14 +87,16 @@ gulp.task('images', function () { // HTML pages gulp.task('pages', function () { - src.pages = 'src/pages/**/*.html'; + src.pages = ['src/pages/**/*.jsx', 'src/pages/404.html']; return gulp.src(src.pages) - .pipe($.changed(DEST)) + .pipe($.changed(DEST, {extension: '.html'})) + .pipe($.if('*.jsx', $.render({template: './src/pages/_template.html'}))) + .pipe($.replace('UA-XXXXX-X', GOOGLE_ANALYTICS_ID)) .pipe($.if(RELEASE, $.htmlmin({ removeComments: true, collapseWhitespace: true, minifyJS: true - }))) + }), $.jsbeautifier())) .pipe(gulp.dest(DEST)) .pipe($.size({title: 'pages'})); }); @@ -150,6 +152,8 @@ gulp.task('build', ['clean'], function (cb) { // Launch a lightweight HTTP Server gulp.task('serve', function (cb) { + var url = require('url'); + var fs = require('fs'); watch = true; runSequence('build', function () { @@ -161,7 +165,19 @@ gulp.task('serve', function (cb) { // Note: this uses an unsigned certificate which on first access // will present a certificate warning in the browser. // https: true, - server: DEST + server: { + baseDir: DEST, + // Allow web page requests without .html file extension in URLs + middleware: function (req, res, cb) { + var uri = url.parse(req.url); + if (uri.pathname.length > 1 && + path.extname(uri.pathname) === '' && + fs.existsSync(DEST + uri.pathname + '.html')) { + req.url = uri.pathname + '.html' + (uri.search || ''); + } + cb(); + } + } }); gulp.watch(src.assets, ['assets']); diff --git a/package.json b/package.json @@ -15,7 +15,7 @@ "browser-sync": "^1.5.2", "del": "^0.1.3", "gulp": "^3.8.8", - "gulp-autoprefixer": "1.0.1", + "gulp-autoprefixer": "^1.0.1", "gulp-cache": "^0.2.2", "gulp-changed": "^1.0.0", "gulp-csscomb": "^3.0.2", @@ -23,11 +23,14 @@ "gulp-htmlmin": "^0.2.0", "gulp-if": "^1.2.4", "gulp-imagemin": "^1.0.1", + "gulp-jsbeautifier": "^0.0.3", "gulp-jshint": "^1.8.5", "gulp-less": "^1.3.6", "gulp-load-plugins": "^0.6.0", "gulp-minify-css": "^0.3.10", "gulp-plumber": "^0.6.5", + "gulp-render": "^0.0.2", + "gulp-replace": "^0.4.0", "gulp-size": "^1.1.0", "gulp-uglify": "^1.0.1", "gulp-util": "^3.0.1", diff --git a/src/App.js b/src/App.js @@ -4,17 +4,19 @@ var React = require('react'); var {Router} = require('director'); var AppDispatcher = require('./AppDispatcher'); var ActionTypes = require('./constants/ActionTypes'); +var HomePage = require('./pages/Index.jsx'); // Export React so the dev tools can find it (window !== window.top ? window.top : window).React = React; function render(component) { React.renderComponent(component(), document.body); + document.title = component.defaultProps.title || HomePage.defaultProps.title; } var routes = { - '/': () => render(require('./pages/HomePage.jsx')), - '/privacy': () => render(require('./pages/PrivacyPage.jsx')) + '/': () => render(HomePage), + '/privacy': () => render(require('./pages/Privacy.jsx')) }; var router = new Router(routes).configure({html5history: true}).init(); diff --git a/src/components/Link.jsx b/src/components/Link.jsx @@ -9,8 +9,7 @@ var RouteActions = require('../actions/RouteActions'); var Link = React.createClass({ propTypes: { - to: React.PropTypes.string.isRequired, - children: React.PropTypes.component.isRequired + to: React.PropTypes.string.isRequired }, render() { this.props.href = diff --git a/src/pages/HomePage.jsx b/src/pages/HomePage.jsx @@ -1,49 +0,0 @@ -/** - * @jsx React.DOM - */ - -'use strict'; - -var React = require('react'); -var DefaultLayout = require('../layouts/DefaultLayout.jsx'); - -var HomePage = React.createClass({ - render() { - return ( - <DefaultLayout> - <div className="container"> - <div className="row"> - <div className="col-sm-4"> - <h3>Runtime Components</h3> - <dl> - <dt><a href="https://facebook.github.io/react/">React</a></dt> - <dd>A JavaScript library for building user interfaces, developed by Facebook</dd> - <dt><a href="https://github.com/rackt/react-router">React-Router</a></dt> - <dd>A complete routing library for React</dd> - <dt><a href="http://getbootstrap.com/">Bootstrap</a></dt> - <dd>CSS framework for developing responsive, mobile first interfaces</dd> - </dl> - </div> - <div className="col-sm-4"> - <h3>Development Tools</h3> - <dl> - <dt><a href="http://gulpjs.com">Gulp</a></dt> - <dd>JavaScript streaming build system and task automation</dd> - <dt><a href="http://webpack.github.io/">Webpack</a></dt> - <dd>Compiles front-end source code into modules / bundles</dd> - <dt><a href="http://www.browsersync.io/">BrowserSync</a></dt> - <dd>A lightweight HTTP server for development</dd> - </dl> - </div> - <div className="col-sm-4"> - <h3>Fork me on GitHub</h3> - <p><a href="https://github.com/kriasoft/react-starter-kit">github.com/kriasoft/react-starter-kit</a></p> - </div> - </div> - </div> - </DefaultLayout> - ); - } -}); - -module.exports = HomePage; diff --git a/src/pages/Index.jsx b/src/pages/Index.jsx @@ -0,0 +1,55 @@ +/** + * @jsx React.DOM + */ + +'use strict'; + +var React = require('react'); +var DefaultLayout = require('../layouts/DefaultLayout.jsx'); + +var HomePage = React.createClass({ + getDefaultProps() { + return { + title: 'React.js Starter Kit', + description: 'A skeleton for a web application built with Facebook\'s React.js Library' + }; + }, + render() { + return ( + <DefaultLayout title={this.props.title}> + <div className="container"> + <div className="row"> + <div className="col-sm-4"> + <h3>Runtime Components</h3> + <dl> + <dt><a href="https://facebook.github.io/react/">React</a></dt> + <dd>A JavaScript library for building user interfaces, developed by Facebook</dd> + <dt><a href="https://github.com/rackt/react-router">React-Router</a></dt> + <dd>A complete routing library for React</dd> + <dt><a href="http://getbootstrap.com/">Bootstrap</a></dt> + <dd>CSS framework for developing responsive, mobile first interfaces</dd> + </dl> + </div> + <div className="col-sm-4"> + <h3>Development Tools</h3> + <dl> + <dt><a href="http://gulpjs.com">Gulp</a></dt> + <dd>JavaScript streaming build system and task automation</dd> + <dt><a href="http://webpack.github.io/">Webpack</a></dt> + <dd>Compiles front-end source code into modules / bundles</dd> + <dt><a href="http://www.browsersync.io/">BrowserSync</a></dt> + <dd>A lightweight HTTP server for development</dd> + </dl> + </div> + <div className="col-sm-4"> + <h3>Fork me on GitHub</h3> + <p><a href="https://github.com/kriasoft/react-starter-kit">github.com/kriasoft/react-starter-kit</a></p> + </div> + </div> + </div> + </DefaultLayout> + ); + } +}); + +module.exports = HomePage; diff --git a/src/pages/Privacy.jsx b/src/pages/Privacy.jsx @@ -0,0 +1,67 @@ +/** + * @jsx React.DOM + */ + +'use strict'; + +var React = require('react'); +var DefaultLayout = require('../layouts/DefaultLayout.jsx'); + +var PrivacyPage = React.createClass({ + getDefaultProps() { + return { + title: 'Privacy Policy' + }; + }, + render() { + return ( + <DefaultLayout title={this.props.title}> + <div className="container"> + <h2>{this.props.title}</h2> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean consequat tortor fermentum mi + fermentum dignissim. Nullam vel ipsum ut ligula elementum lobortis. Maecenas aliquam, massa laoreet + lacinia pretium, nisi urna venenatis tortor, nec imperdiet tellus libero efficitur metus. Fusce + semper posuere ligula, et facilisis metus bibendum interdum. Mauris at mauris sit amet sem pharetra + commodo a eu leo. Nam at est non risus cursus maximus. Nam feugiat augue libero, id consectetur + tortor bibendum non. Quisque nec fringilla lorem. Nullam efficitur vulputate mauris, nec maximus leo + dignissim id. + </p> + <p> + In hac habitasse platea dictumst. Duis sagittis dui ac ex suscipit maximus. Morbi pellentesque + venenatis felis sed convallis. Nulla varius, nibh vitae placerat tempus, mauris sem elementum ipsum, + eget sollicitudin nisl est vel purus. Fusce malesuada odio velit, non cursus leo fermentum id. Cras + pharetra sodales fringilla. Etiam quis est a dolor egestas pellentesque. Maecenas non scelerisque + purus, congue cursus arcu. Donec vel dapibus mi. Mauris maximus posuere placerat. Sed et libero eu + nibh tristique mollis a eget lectus. Donec interdum augue sollicitudin vehicula hendrerit. Vivamus + justo orci, molestie ac sollicitudin ac, lobortis at tellus. Etiam rhoncus ullamcorper risus eu + tempor. Sed porttitor, neque ac efficitur gravida, arcu lacus pharetra dui, in consequat elit tellus + auctor nulla. Donec placerat elementum diam, vitae imperdiet lectus luctus at. + </p> + <p> + Nullam eu feugiat mi. Quisque nec tristique nisl, dignissim dictum leo. Nam non quam nisi. Donec + rutrum turpis ac diam blandit, id pulvinar mauris suscipit. Pellentesque tincidunt libero ultricies + risus iaculis, sit amet consequat velit blandit. Fusce quis varius nulla. Nullam nisi nisi, suscipit + ut magna quis, feugiat porta nibh. Sed id enim lectus. Suspendisse elementum justo sapien, sit amet + consequat orci accumsan et. Aliquam ornare ullamcorper sem sed finibus. Nullam ac lacus pulvinar, + egestas felis ut, accumsan est. + </p> + <p> + Pellentesque sagittis vehicula sem quis luctus. Proin sodales magna in lorem hendrerit aliquam. + Integer eu varius orci. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere + cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia + Curae; Ut at mauris nibh. Suspendisse maximus ac eros at vestibulum. + </p> + <p> + Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque egestas tortor et dui + consequat faucibus. Nunc vitae odio ornare, venenatis ligula a, vulputate nisl. Aenean congue varius + ex, sit amet bibendum odio posuere at. Nulla facilisi. In finibus, nulla vitae tincidunt ornare, + sapien nulla fermentum mauris, sed consectetur tortor arcu eget arcu. Vestibulum vel quam enim. + </p> + </div> + </DefaultLayout> + ); + } +}); + +module.exports = PrivacyPage; diff --git a/src/pages/PrivacyPage.jsx b/src/pages/PrivacyPage.jsx @@ -1,62 +0,0 @@ -/** - * @jsx React.DOM - */ - -'use strict'; - -var React = require('react'); -var DefaultLayout = require('../layouts/DefaultLayout.jsx'); - -var PrivacyPage = React.createClass({ - render() { - return ( - <DefaultLayout> - <div className="container"> - <h2>Privacy Policy</h2> - <p> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean consequat tortor fermentum mi - fermentum dignissim. Nullam vel ipsum ut ligula elementum lobortis. Maecenas aliquam, massa laoreet - lacinia pretium, nisi urna venenatis tortor, nec imperdiet tellus libero efficitur metus. Fusce - semper posuere ligula, et facilisis metus bibendum interdum. Mauris at mauris sit amet sem pharetra - commodo a eu leo. Nam at est non risus cursus maximus. Nam feugiat augue libero, id consectetur - tortor bibendum non. Quisque nec fringilla lorem. Nullam efficitur vulputate mauris, nec maximus leo - dignissim id. - </p> - <p> - In hac habitasse platea dictumst. Duis sagittis dui ac ex suscipit maximus. Morbi pellentesque - venenatis felis sed convallis. Nulla varius, nibh vitae placerat tempus, mauris sem elementum ipsum, - eget sollicitudin nisl est vel purus. Fusce malesuada odio velit, non cursus leo fermentum id. Cras - pharetra sodales fringilla. Etiam quis est a dolor egestas pellentesque. Maecenas non scelerisque - purus, congue cursus arcu. Donec vel dapibus mi. Mauris maximus posuere placerat. Sed et libero eu - nibh tristique mollis a eget lectus. Donec interdum augue sollicitudin vehicula hendrerit. Vivamus - justo orci, molestie ac sollicitudin ac, lobortis at tellus. Etiam rhoncus ullamcorper risus eu - tempor. Sed porttitor, neque ac efficitur gravida, arcu lacus pharetra dui, in consequat elit tellus - auctor nulla. Donec placerat elementum diam, vitae imperdiet lectus luctus at. - </p> - <p> - Nullam eu feugiat mi. Quisque nec tristique nisl, dignissim dictum leo. Nam non quam nisi. Donec - rutrum turpis ac diam blandit, id pulvinar mauris suscipit. Pellentesque tincidunt libero ultricies - risus iaculis, sit amet consequat velit blandit. Fusce quis varius nulla. Nullam nisi nisi, suscipit - ut magna quis, feugiat porta nibh. Sed id enim lectus. Suspendisse elementum justo sapien, sit amet - consequat orci accumsan et. Aliquam ornare ullamcorper sem sed finibus. Nullam ac lacus pulvinar, - egestas felis ut, accumsan est. - </p> - <p> - Pellentesque sagittis vehicula sem quis luctus. Proin sodales magna in lorem hendrerit aliquam. - Integer eu varius orci. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere - cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia - Curae; Ut at mauris nibh. Suspendisse maximus ac eros at vestibulum. - </p> - <p> - Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque egestas tortor et dui - consequat faucibus. Nunc vitae odio ornare, venenatis ligula a, vulputate nisl. Aenean congue varius - ex, sit amet bibendum odio posuere at. Nulla facilisi. In finibus, nulla vitae tincidunt ornare, - sapien nulla fermentum mauris, sed consectetur tortor arcu eget arcu. Vestibulum vel quam enim. - </p> - </div> - </DefaultLayout> - ); - } -}); - -module.exports = PrivacyPage; diff --git a/src/pages/_template.html b/src/pages/_template.html @@ -0,0 +1,27 @@ +<!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="stylesheet" href="css/bootstrap.css"> + </head> + <body> + <!--[if lt IE 8]> + <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> + <![endif]--> + <%= body %> + <script src="app.js"></script> + <!-- Google Analytics --> + <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');ga('send','pageview'); + </script> + </body> +</html> diff --git a/src/pages/index.html b/src/pages/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>Facebook React Starter Kit</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <link rel="stylesheet" href="css/bootstrap.css"> - </head> - <body> - <!--[if lt IE 8]> - <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> - <![endif]--> - - <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');ga('send','pageview'); - </script> - </body> -</html>