From 674595893ba17e8fdbbc4c0334b772bff22ad9bd Mon Sep 17 00:00:00 2001 From: Joel Chen Date: Sat, 15 Oct 2016 22:10:25 -0700 Subject: [PATCH] update with fixes from generator and enable isormophic images (#32) --- .gitignore | 2 +- .isomorphic-loader-config.lock | 1 - client/app.jsx | 14 ++-- client/components/above-the-fold.jsx | 95 +++++++++++++++++---- client/components/home.jsx | 31 +++++-- client/images/718smiley.png | Bin 0 -> 13112 bytes client/images/electrode.svg | 121 +++++++++++++++++++++++++++ client/images/peace-smiley.png | Bin 0 -> 20882 bytes client/reducers/count-reducer.js | 8 -- client/reducers/data-reducer.js | 8 -- client/reducers/index.js | 10 --- client/reducers/index.jsx | 5 ++ client/routes.jsx | 16 ++-- config/default.json | 1 + package.json | 3 +- server/index.js | 28 ++++++- server/plugins/webapp/index.js | 2 +- server/views/index-view.jsx | 30 +++++-- 18 files changed, 293 insertions(+), 82 deletions(-) delete mode 100644 .isomorphic-loader-config.lock create mode 100644 client/images/718smiley.png create mode 100644 client/images/electrode.svg create mode 100644 client/images/peace-smiley.png delete mode 100644 client/reducers/count-reducer.js delete mode 100644 client/reducers/data-reducer.js delete mode 100644 client/reducers/index.js create mode 100644 client/reducers/index.jsx diff --git a/.gitignore b/.gitignore index ad8ad8cf1..6ecd206e7 100644 --- a/.gitignore +++ b/.gitignore @@ -154,4 +154,4 @@ Procfile config/assets.json npm-shrinkwrap.json -.isomorphic-loader-config.json +.isomorphic-loader-config.* diff --git a/.isomorphic-loader-config.lock b/.isomorphic-loader-config.lock deleted file mode 100644 index 19104f172..000000000 --- a/.isomorphic-loader-config.lock +++ /dev/null @@ -1 +0,0 @@ -lock \ No newline at end of file diff --git a/client/app.jsx b/client/app.jsx index 540e26c12..ab3896879 100644 --- a/client/app.jsx +++ b/client/app.jsx @@ -1,29 +1,25 @@ import React from "react"; +import {render} from "react-dom"; import { routes } from "./routes"; import { Router, browserHistory } from "react-router"; import { createStore, compose } from "redux"; -import { Resolver } from "react-resolver"; import { Provider } from "react-redux"; import "styles/base.css"; -import rootReducer from "./reducers/index"; +import rootReducer from "./reducers"; import DevTools from "../client/devtools"; -const initialState = window.__PRELOADED_STATE__; - -// const rootReducer = (s, a) => s; // eslint-disable-line no-unused-vars - const enhancer = compose( // Add middlewares you want to use in development: // applyMiddleware(d1, d2, d3), DevTools.instrument() ); -const store = createStore(rootReducer, initialState, enhancer); window.webappStart = () => { - Resolver.render( - () => + const initialState = window.__PRELOADED_STATE__; + const store = createStore(rootReducer, initialState, enhancer); + render(
{routes} diff --git a/client/components/above-the-fold.jsx b/client/components/above-the-fold.jsx index b8ea9ebbc..9d7bd4a6c 100644 --- a/client/components/above-the-fold.jsx +++ b/client/components/above-the-fold.jsx @@ -1,28 +1,91 @@ -import React from "react"; +import React, {PropTypes} from "react"; import {AboveTheFoldOnlyServerRender} from "above-the-fold-only-server-render"; +import {connect} from "react-redux"; +import smileyPng from "../images/718smiley.png"; +import peaceSmileyPng from "../images/peace-smiley.png"; + +/* eslint-disable max-len */ export class AboveFold extends React.Component { render() { return (
-

Above-the-fold-only-server-render: Increase Your Performance

- -
-

This will skip server rendering if the 'AboveTheFoldOnlyServerRender' - lines are present, or uncommented out.

-

This will be rendered on the server and visible - if the 'AboveTheFoldOnlyServerRender' lines are commented out.

-

Try manually toggling this component to see it in action

-

- Read more about this module and see our live demo - -

-
+
+

Above-the-fold-only-server-render: Increase Your Performance. Note: This demo uses CSS3.

+

This page demonstrates the AboveTheFoldOnlyServerRender component.

+

+ + Read more about this module and see our live demo + +

+
+
+

This content block is here to fill up the browser view port as Above The Fold content and it always will be + rendered on server side.

+

To verify, use your browser's view source to see the original HTML of this page and see this being part of + the SSR content

+

You should see this fill up your browser screen to push content below the browser view port, which are + wrapped in the AboveTheFoldOnlyServerRender component.

+ +

Scroll down to see the content below

+
+ {this.props.skip ? ( +
In the page source you should NOT see any more HTML after this except a few empty divs +
) + : + (
In the page source you should SEE the HTML for the wrapped component after this.
) + } + +
+

This content block is wrapped inside the AboveTheFoldOnlyServerRender component, with the + skip prop set to {`${this.props.skip}`}.

+ {this.props.skip ? +

It will not be rendered on the server side, but you should see it in the browser.

+

To verify, check the page source to see this not being part of the SSR content.

+ : +

It is also rendered on the server side since skip is {`${this.props.skip}`}

+

To verify, check the page source to see this being part of the SSR content.

+ } + +
-

This is below the 'Above the fold closing tag'

); } } + +AboveFold.propTypes = { + skip: PropTypes.bool +}; + +export default connect((state) => { + return {skip: state.skip}; +})(AboveFold); diff --git a/client/components/home.jsx b/client/components/home.jsx index 5a16b06a1..2941ec170 100644 --- a/client/components/home.jsx +++ b/client/components/home.jsx @@ -1,10 +1,11 @@ -import React, { PropTypes } from "react"; -import { connect } from "react-redux"; +import React, {PropTypes} from "react"; +import {connect} from "react-redux"; +import electrodeLogo from "../images/electrode.svg"; class HomeWrapper extends React.Component { render() { return ( - + ); } } @@ -13,17 +14,33 @@ HomeWrapper.propTypes = { data: PropTypes.string }; +/* eslint-disable max-len */ + export class Home extends React.Component { render() { return (
-

Hello Electrode

+
+ Electrode Logo + +

Demonstration Components

  • CSRF protection using electrode-csrf-jwt
  • - - Above the Fold Render - increase your App's performance by using a skip prop + + Above the Fold Render with skip=true - increase your App's performance by using a skip prop + +
  • +
  • + + Above the Fold Render with skip=false - increase your App's performance by using a skip prop
  • SSR Caching Simple Type Example
  • @@ -40,7 +57,7 @@ Home.propTypes = { }; const mapStateToProps = (state) => ({ - data: state.data + data: state && state.data }); export default connect( diff --git a/client/images/718smiley.png b/client/images/718smiley.png new file mode 100644 index 0000000000000000000000000000000000000000..c057e107dee9e141d9ba51e0a393335db1db8708 GIT binary patch literal 13112 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 literal 0 HcmV?d00001 diff --git a/client/images/electrode.svg b/client/images/electrode.svg new file mode 100644 index 000000000..050719671 --- /dev/null +++ b/client/images/electrode.svg @@ -0,0 +1,121 @@ + + + + +Created by potrace 1.13, written by Peter Selinger 2001-2015 + + + + + + + + + + + + + + + + diff --git a/client/images/peace-smiley.png b/client/images/peace-smiley.png new file mode 100644 index 0000000000000000000000000000000000000000..ce465a382e92900d4e339c597f7dc1e8cd10ee3a GIT binary patch literal 20882 zcmb?jQ*$L;v^=q`iEZ0XCYac^ot)VA#I|kQwrx8TJGtL|xc}hRs@1FZ+kV>BtGjDQ zD9A}5z~aCH000CjNin7WX5N1t2Mzik0#;vE|3fgKh?EL6H1y`a{N8^@7zasBAOL_k z^uG;~OpAyM01yGB#DrDcv#z?`(oBY3IKFc#aCzisEY00G8v7dPxS`32lY~Kz4In1J z=`>Tm##3xf@~ci8ZKPT-{-VO>`6F{nfyZMaJFc5POx?^}9WC9JR6KkX+PysblYxo6 zzWh_zl((OKyzWtbT9LZtRu!F!#@cvjjrh4n?3(*-x`y!2J^g=#Y0n$`@u}~}{LdQO z;(dHYU$wSzliQ2XLOJ=TD&n`^x!hB?!qYYr38jh^~;zc}7seBA|OiM?a z(J{+meQ4seco!Wgg+lQ6VUJ?LKz12S+(G zJ*|364Nn-enyEQ2*W9WRiJU(~cyGsh5fBaj-+wJG{AH75F0abZ1ghH)-pZV-&@%z4~&W>t(n%|T7+NT1kr<65JkmHdPnr!wkPPxx-R9DD9e4nLC z+gV$`k4~%Xs22G(vQq{4SxGPhOU{VH*1rM+$dIbFx2vbu?`a$rQl8h9n40?5oT zP7pBTWOKfOJ}PtiZ{uSxf<524en#fnIgK~zBUOZ5`}erL-|J4km_i-pUtK>RAy1_} zkK8vSjcYlixOmA}ZaR+_s-@SiO8&@1FvL{LF)M{@mIl0k?7*TZO7IM#f&>XV?}+E` zYQ9_bB*kWhUu29=cp1JvjoTx-ASxIUG)o_kjr*miCV4J&%Mykz0$p8Yl_c){ejt;4T&^6c?+|*Jwp=0 z93z>;R6^B6#-wSCvxEc*j2J`lH=rf`n6bO+^?kmf^_uy(6jZED(l5tbZ+uQkPEZv!@-LNaU8^JcH7xg_rOW=YrGj^eT6B0 zWp#^zU}qc`a$C7o!xn!*j(m@!Avs7!NW%aDQBoE81cjdDu^^9+^_YQy3+T~(DCA(m zvxHM>SDc!KCmv9CR6P)_n&rmLou=z$b$HUqLK_=zccFDMbMzC{GqX7T(|xoFZ#C3#&_jcoIX#1DTs_7aX$Q{!x?JehEu+ZFNxv zUlWC=9sn3o+3~QDX!6xvr4{&h;w(>?WhMzFf((84ZeE9C5*nEYN}F{}C(kYuOVN63 zHG?2OweccwvhC74Q*=B&8ro6_tOfy+|0AHDy889g|00TG!Sy~&Pub0~+?o^Yt@is- zWdjJ}VCvkOh%k;yMjk(G(pV?8A;S?2E+s@n2ZM?;L>3-gS3KrShVz_?bp3t^@?3%_ z_x(N^g`}5gn|5`Hlwb(~+UJl__QiFW zqURlKzM=hk3NC}A_q846>=bnG{%l7jio_5_3i{Awod|azw2r6(QAUA?B+i6{1cq42 zwt=PoHnzQ45coRgvdh5dd0STQd98Mau5HvGV_cWil_nf=U8ZqkGR z_|wF}_vKCKe31uP+o#jA(ykVL{FvR$cj{%e9p8ju*0ynY{y=qTUr9L_2nfr_iL@e} zwfOcnxqm#myb!co)qP#LHD$Z@$b4EJUJ056sh)i#LaA^g5nqRLw6>q7lY=38e-JLN z$ZM(nA-2VYk;ED>+!tDl!-T;l6HX|E)u`VbvyDfNsI}W=2eq?R4RH2U6 z|EON)_1jwE+}*&1?k9reKI2bR>%tr7r~?JkO_1d!gG8fTnnDI)vzJ3KmRl2jUoCV3 z;wzF$TDIL6k6+%)YhJwXw^y!w*c_n(+uP)E42&q4ATXFch!n?OTzc-oY)f-~uHLbq zuH67rQ_1t&hpW0-yB?Wh!aV-J(NVSO*Ii1RvhFXoIue7A`G#?s9 ad%JH}Y+A{S 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 D!%};# literal 0 HcmV?d00001 diff --git a/client/reducers/count-reducer.js b/client/reducers/count-reducer.js deleted file mode 100644 index 95f9e4554..000000000 --- a/client/reducers/count-reducer.js +++ /dev/null @@ -1,8 +0,0 @@ -const countReducer = (state = 0, action) => { - switch (action.type) { - default: - return state; - } -}; - -export default countReducer; diff --git a/client/reducers/data-reducer.js b/client/reducers/data-reducer.js deleted file mode 100644 index 3e413f2b1..000000000 --- a/client/reducers/data-reducer.js +++ /dev/null @@ -1,8 +0,0 @@ -const dataReducer = (state = {}, action) => { - switch (action.type) { - default: - return state; - } -}; - -export default dataReducer; diff --git a/client/reducers/index.js b/client/reducers/index.js deleted file mode 100644 index 1d176845b..000000000 --- a/client/reducers/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from "redux"; -import dataReducer from "./data-reducer"; -import countReducer from "./count-reducer"; - -const rootReducer = combineReducers({ - data: dataReducer, - count: countReducer -}); - -export default rootReducer; diff --git a/client/reducers/index.jsx b/client/reducers/index.jsx new file mode 100644 index 000000000..dd31e88f2 --- /dev/null +++ b/client/reducers/index.jsx @@ -0,0 +1,5 @@ +const rootReducer = (state) => { + return state || {}; +}; + +export default rootReducer; diff --git a/client/routes.jsx b/client/routes.jsx index 140b09e31..c124de8ed 100644 --- a/client/routes.jsx +++ b/client/routes.jsx @@ -1,17 +1,17 @@ import React from "react"; -import { Route, IndexRoute} from "react-router"; +import {Route, IndexRoute} from "react-router"; import Home from "./components/home"; import SSRCachingTemplateType from "./components/ssr-caching-template-type"; import SSRCachingSimpleType from "./components/ssr-caching-simple-type"; -import { CSRF } from "./components/csrf"; -import { AboveFold } from "./components/above-the-fold"; +import {CSRF} from "./components/csrf"; +import AboveFold from "./components/above-the-fold"; export const routes = ( - - - - - + + + + + ); diff --git a/config/default.json b/config/default.json index 3aa2f4845..5c9bf7e95 100644 --- a/config/default.json +++ b/config/default.json @@ -10,6 +10,7 @@ "webapp": { "module": "./server/plugins/webapp", "options": { + "pageTitle": "Electrode Boilerplate Universal React App", "paths": { "/{args*}": { "content": { diff --git a/package.json b/package.json index 81e7b4987..a58420b26 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,10 @@ "dependencies": { "above-the-fold-only-server-render": "^1.0.2", "bluebird": "^3.4.6", + "electrode-archetype-react-app": "^1.0.0", "electrode-csrf-jwt": "^1.0.0", "electrode-react-ssr-caching": "^0.1.3", "electrode-redux-router-engine": "^1.0.0", - "electrode-router-resolver-engine": "^1.0.0", "electrode-server": "^1.0.0", "electrode-static-paths": "^1.0.0", "lodash": "^4.10.1" @@ -37,7 +37,6 @@ "redux-devtools": "^3.3.1", "redux-devtools-dock-monitor": "^1.1.1", "redux-devtools-log-monitor": "^1.0.11", - "electrode-archetype-react-app": "^1.0.0", "electrode-archetype-react-app-dev": "^1.0.0", "gulp": "^3.9.1" } diff --git a/server/index.js b/server/index.js index 87bc03d87..e4bc6846f 100644 --- a/server/index.js +++ b/server/index.js @@ -8,12 +8,18 @@ process.on("SIGINT", () => { const config = require("electrode-confippet").config; const staticPathsDecor = require("electrode-static-paths"); +const supports = require("electrode-archetype-react-app/supports"); require.extensions[".css"] = () => { return; }; -require("babel-register")({ +/** + * Use babel register to transpile any JSX code on the fly to run + * in server mode, and also transpile react code to apply process.env.NODE_ENV + * removal to improve performance in production mode. + */ +supports.babelRegister({ ignore: /node_modules\/(?!react\/)/ }); @@ -33,4 +39,22 @@ const cacheConfig = { SSRCaching.enableCaching(); SSRCaching.setCachingConfig(cacheConfig); -require("electrode-server")(config, [staticPathsDecor()]); +/** + * css-modules-require-hook: handle css-modules on node.js server. + * similar to Babel's babel/register it compiles CSS modules in runtime. + * + * generateScopedName - Short alias for the postcss-modules-scope plugin's option. + * Helps you to specify the custom way to build generic names for the class selectors. + * You may also use a string pattern similar to the webpack's css-loader. + * + * https://github.com/css-modules/css-modules-require-hook#generatescopedname-function + * https://github.com/webpack/css-loader#local-scope + * https://github.com/css-modules/postcss-modules-scope + */ +supports.cssModuleHook({ + generateScopedName: "[name]__[local]___[hash:base64:5]" +}); + +supports.isomorphicExtendRequire().then(() => { + require("electrode-server")(config, [staticPathsDecor()]); // eslint-disable-line +}); diff --git a/server/plugins/webapp/index.js b/server/plugins/webapp/index.js index c18776b8c..18283b832 100644 --- a/server/plugins/webapp/index.js +++ b/server/plugins/webapp/index.js @@ -152,7 +152,7 @@ const registerRoutes = (server, options, next) => { return content; }; - const pluginOptions = _.defaultsDeep({}, pluginOptionsDefaults, options); + const pluginOptions = _.defaultsDeep({}, options, pluginOptionsDefaults); return Promise.try(() => loadAssetsFromStats(pluginOptions.stats)) .then((assets) => { diff --git a/server/views/index-view.jsx b/server/views/index-view.jsx index 2bff87f1d..bb8ff0862 100644 --- a/server/views/index-view.jsx +++ b/server/views/index-view.jsx @@ -1,11 +1,10 @@ import ReduxRouterEngine from 'electrode-redux-router-engine'; import React from 'react'; -import ReactDOM from 'react-dom/server'; import { routes } from "../../client/routes"; const Promise = require("bluebird"); import { createStore } from "redux"; -let rootReducer = (s, a) => s; +import rootReducer from "../../client/reducers"; function storeInitializer(req) { let initialState; @@ -21,12 +20,15 @@ function storeInitializer(req) { initialState = { count: 100 }; + } else if (req.path === "/above-the-fold") { + initialState = { + skip: req.query.skip === "true" + } } else { - let initialState = {}; + initialState = {}; } - const store = createStore(rootReducer, initialState); - return store; + return createStore(rootReducer, initialState); } function createReduxStore(req, match) { @@ -39,11 +41,21 @@ function createReduxStore(req, match) { }); } -module.exports = (req) => { +// +// This function is exported as the content for the webapp plugin. +// +// See config/default.json under plugins.webapp on specifying the content. +// +// When the Web server hits the routes handler installed by the webapp plugin, it +// will call this function to retrieve the content for SSR if it's enabled. +// +// - if (!req.server.app.routesEngine) { - req.server.app.routesEngine = new ReduxRouterEngine({ routes, createReduxStore }); +module.exports = (req) => { + const app = req.server && req.server.app || req.app; + if (!app.routesEngine) { + app.routesEngine = new ReduxRouterEngine({routes, createReduxStore}); } - return req.server.app.routesEngine.render(req); + return app.routesEngine.render(req); };