diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..06721631 --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@babel/env", "@babel/react"], + "plugins": ["@babel/plugin-proposal-object-rest-spread"] +} diff --git a/.eslintignore b/.eslintignore index 0dab9088..c7174499 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,5 @@ node_modules/ exports/ index.js test/ +server/render/handlePageRender.js +server/render/handleShowRender.js diff --git a/package.json b/package.json index 0d128d72..8aaf2b29 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,12 @@ "scripts": { "test": "mocha --recursive", "test-all": "mocha --recursive", - "start": "node index.js", - "start-dev": "nodemon index.js", "lint": "eslint .", "fix": "eslint . --fix", "precommit": "eslint .", - "babel": "babel", - "build-dev": "webpack --config webpack.dev.js", - "build": "webpack --config webpack.prod.js" + "build": "babel server/render/src -d server/render", + "build:watch": "babel server/render/src -w -d server/render" + }, "repository": { "type": "git", @@ -34,7 +32,6 @@ "axios": "^0.16.1", "bcrypt": "^1.0.3", "body-parser": "^1.17.1", - "babel-polyfill": "^6.26.0", "config": "^1.26.1", "connect-multiparty": "^2.0.0", "cookie-session": "^2.0.0-beta.3", @@ -61,20 +58,16 @@ "sequelize": "^4.1.0", "sequelize-cli": "^3.0.0-3", "universal-analytics": "^0.4.13", - "webpack-node-externals": "^1.6.0", - "whatwg-fetch": "^2.0.3", "winston": "^2.3.1", "winston-slack-webhook": "billbitt/winston-slack-webhook", "spee.ch-components": "git://github.com/billbitt/spee.ch-components.git" }, "devDependencies": { - "babel-core": "^6.26.0", - "babel-loader": "^7.1.2", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", - "babel-preset-stage-2": "^6.24.1", - "babel-register": "^6.26.0", + "@babel/cli": "^7.0.0-beta.37", + "@babel/core": "^7.0.0-beta.37", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.42", + "@babel/preset-env": "^7.0.0-beta.37", + "@babel/preset-react": "^7.0.0-beta.37", "chai": "^4.1.2", "chai-http": "^3.0.0", "css-loader": "^0.28.9", @@ -90,8 +83,6 @@ "mocha": "^4.0.1", "nodemon": "^1.15.1", "redux-devtools": "^3.4.1", - "regenerator-transform": "^0.12.3", - "webpack": "^3.10.0", - "webpack-merge": "^4.1.2" + "regenerator-transform": "^0.12.3" } } diff --git a/server/helpers/multipartMiddleware.js b/server/helpers/multipartMiddleware.js index c483754b..e85fc5c6 100644 --- a/server/helpers/multipartMiddleware.js +++ b/server/helpers/multipartMiddleware.js @@ -1,5 +1,5 @@ const multipart = require('connect-multiparty'); -const { publishing: { uploadDirectory } } = require('siteConfig.js'); +const { publishing: { uploadDirectory } } = require('../../config/siteConfig.js'); const multipartMiddleware = multipart({uploadDir: uploadDirectory}); module.exports = multipartMiddleware; diff --git a/server/models/index.js b/server/models/index.js index 6c5a084d..cda6419f 100644 --- a/server/models/index.js +++ b/server/models/index.js @@ -8,7 +8,7 @@ const User = require('./user.js'); const Sequelize = require('sequelize'); const logger = require('winston'); -const {database, username, password} = require('mysqlConfig.js'); +const {database, username, password} = require('../../config/mysqlConfig.js'); // set sequelize options const sequelize = new Sequelize(database, username, password, { diff --git a/server/render/handlePageRender.js b/server/render/handlePageRender.js new file mode 100644 index 00000000..eb792e72 --- /dev/null +++ b/server/render/handlePageRender.js @@ -0,0 +1,59 @@ +"use strict"; + +var _react = _interopRequireDefault(require("react")); + +var _server = require("react-dom/server"); + +var _redux = require("redux"); + +var _reactRedux = require("react-redux"); + +var _reactRouterDom = require("react-router-dom"); + +var _spee = require("spee.ch-components"); + +var _renderFullPage = _interopRequireDefault(require("../../helpers/renderFullPage.js")); + +var _reactHelmet = _interopRequireDefault(require("react-helmet")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* + ^ note: to do this right, maybe + these should be passed in from the implementation (www.spee.ch) itself, + so that there are no conflicts between the SSR here and + the bundle sent to the server? + there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does? +*/ +var siteConfig = require('../../../config/siteConfig.js'); + +module.exports = function (req, res) { + var context = {}; // customize the reducer by passing in intial state configs + + var MyReducers = (0, _spee.Reducers)(siteConfig); + var MyApp = (0, _spee.App)(siteConfig); + var MyGAListener = (0, _spee.GAListener)(siteConfig); // create a new Redux store instance + + var store = (0, _redux.createStore)(MyReducers); // render component to a string + + var html = (0, _server.renderToString)(_react.default.createElement(_reactRedux.Provider, { + store: store + }, _react.default.createElement(_reactRouterDom.StaticRouter, { + location: req.url, + context: context + }, _react.default.createElement(MyGAListener, null, _react.default.createElement(MyApp, null))))); // get head tags from helmet + + var helmet = _reactHelmet.default.renderStatic(); // check for a redirect + + + if (context.url) { + // Somewhere a `<Redirect>` was rendered + return res.redirect(301, context.url); + } else {} // we're good, send the response + // get the initial state from our Redux store + + + var preloadedState = store.getState(); // send the rendered page back to the client + + res.send((0, _renderFullPage.default)(helmet, html, preloadedState)); +}; \ No newline at end of file diff --git a/server/render/handleShowRender.js b/server/render/handleShowRender.js new file mode 100644 index 00000000..a109c9d2 --- /dev/null +++ b/server/render/handleShowRender.js @@ -0,0 +1,92 @@ +"use strict"; + +var _react = _interopRequireDefault(require("react")); + +var _server = require("react-dom/server"); + +var _redux = require("redux"); + +var _reactRedux = require("react-redux"); + +var _reactRouterDom = require("react-router-dom"); + +var _renderFullPage = _interopRequireDefault(require("../../helpers/renderFullPage")); + +var _reduxSaga = _interopRequireDefault(require("redux-saga")); + +var _effects = require("redux-saga/effects"); + +var _spee = require("spee.ch-components"); + +var _reactHelmet = _interopRequireDefault(require("react-helmet")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* + ^ note: to do this right, maybe + these should be passed in from the implementation (www.spee.ch) itself, + so that there are no conflicts between the SSR here and + the bundle sent to the server? + there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does? +*/ +var siteConfig = require('../../../config/siteConfig.js'); + +var returnSagaWithParams = function returnSagaWithParams(saga, params) { + return ( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee() { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return (0, _effects.call)(saga, params); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee, this); + }) + ); +}; + +module.exports = function (req, res) { + var context = {}; // configure the reducers by passing initial state configs + + var MyReducers = (0, _spee.Reducers)(siteConfig); + var MyApp = (0, _spee.App)(siteConfig); + var MyGAListener = (0, _spee.GAListener)(siteConfig); // create and apply middleware + + var sagaMiddleware = (0, _reduxSaga.default)(); + var middleware = (0, _redux.applyMiddleware)(sagaMiddleware); // create a new Redux store instance + + var store = (0, _redux.createStore)(MyReducers, middleware); // create saga + + var action = _spee.Actions.onHandleShowPageUri(req.params); + + var saga = returnSagaWithParams(_spee.Sagas.handleShowPageUri, action); // run the saga middleware + + sagaMiddleware.run(saga).done.then(function () { + // render component to a string + var html = (0, _server.renderToString)(_react.default.createElement(_reactRedux.Provider, { + store: store + }, _react.default.createElement(_reactRouterDom.StaticRouter, { + location: req.url, + context: context + }, _react.default.createElement(MyGAListener, null, _react.default.createElement(MyApp, null))))); // get head tags from helmet + + var helmet = _reactHelmet.default.renderStatic(); // check for a redirect + + + if (context.url) { + return res.redirect(301, context.url); + } // get the initial state from our Redux store + + + var preloadedState = store.getState(); // send the rendered page back to the client + + res.send((0, _renderFullPage.default)(helmet, html, preloadedState)); + }); +}; \ No newline at end of file diff --git a/server/helpers/handlePageRender.jsx b/server/render/src/handlePageRender.jsx similarity index 93% rename from server/helpers/handlePageRender.jsx rename to server/render/src/handlePageRender.jsx index 3c35edba..39594cf3 100644 --- a/server/helpers/handlePageRender.jsx +++ b/server/render/src/handlePageRender.jsx @@ -11,10 +11,10 @@ import { Reducers, GAListener, App } from 'spee.ch-components'; the bundle sent to the server? there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does? */ -import renderFullPage from './renderFullPage.js'; +import renderFullPage from '../../helpers/renderFullPage.js'; import Helmet from 'react-helmet'; -const siteConfig = require('../../config/siteConfig.js'); +const siteConfig = require('../../../config/siteConfig.js'); module.exports = (req, res) => { let context = {}; diff --git a/server/helpers/handleShowRender.jsx b/server/render/src/handleShowRender.jsx similarity index 95% rename from server/helpers/handleShowRender.jsx rename to server/render/src/handleShowRender.jsx index 7cd4efc6..4999a171 100644 --- a/server/helpers/handleShowRender.jsx +++ b/server/render/src/handleShowRender.jsx @@ -3,7 +3,7 @@ import { renderToString } from 'react-dom/server'; import { createStore, applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; import { StaticRouter } from 'react-router-dom'; -import renderFullPage from './renderFullPage'; +import renderFullPage from '../../helpers/renderFullPage'; import createSagaMiddleware from 'redux-saga'; import { call } from 'redux-saga/effects'; import { Reducers, GAListener, App, Sagas, Actions } from 'spee.ch-components'; @@ -16,7 +16,7 @@ import { Reducers, GAListener, App, Sagas, Actions } from 'spee.ch-components'; */ import Helmet from 'react-helmet'; -const siteConfig = require('../../config/siteConfig.js'); +const siteConfig = require('../../../config/siteConfig.js'); const returnSagaWithParams = (saga, params) => { return function * () { diff --git a/server/routes/assets/serveAssetByClaim.js b/server/routes/assets/serveAssetByClaim.js index e0f57792..74e28170 100644 --- a/server/routes/assets/serveAssetByClaim.js +++ b/server/routes/assets/serveAssetByClaim.js @@ -1,7 +1,7 @@ const { sendGAServeEvent } = require('../../helpers/googleAnalytics'); const { determineResponseType, logRequestData, getClaimIdAndServeAsset } = require('../../helpers/serveHelpers.js'); const lbryUri = require('../../helpers/lbryUri.js'); -const handleShowRender = require('../../helpers/handleShowRender.jsx'); +const handleShowRender = require('../../render/handleShowRender.js'); const SERVE = 'SERVE'; /* diff --git a/server/routes/assets/serveAssetByIdentifierAndClaim.js b/server/routes/assets/serveAssetByIdentifierAndClaim.js index e9f42f17..207d5fb7 100644 --- a/server/routes/assets/serveAssetByIdentifierAndClaim.js +++ b/server/routes/assets/serveAssetByIdentifierAndClaim.js @@ -6,7 +6,7 @@ const { getClaimIdAndServeAsset, } = require('../../helpers/serveHelpers.js'); const lbryUri = require('../../helpers/lbryUri.js'); -const handleShowRender = require('../../helpers/handleShowRender.jsx'); +const handleShowRender = require('../../render/handleShowRender.js'); const SERVE = 'SERVE'; diff --git a/server/routes/auth/index.js b/server/routes/auth/index.js index 2dfd2c48..a0a4e64b 100644 --- a/server/routes/auth/index.js +++ b/server/routes/auth/index.js @@ -1,4 +1,4 @@ -const speechPassport = require('../speechPassport'); +const speechPassport = require('../../speechPassport'); const handleSignupRequest = require('./signup'); const handleLoginRequest = require('./login'); const handleLogoutRequest = require('./logout'); diff --git a/server/routes/auth/login.js b/server/routes/auth/login.js index fcc4782d..63f13814 100644 --- a/server/routes/auth/login.js +++ b/server/routes/auth/login.js @@ -1,4 +1,4 @@ -const speechPassport = require('speechPassport'); +const speechPassport = require('../../speechPassport'); const login = (req, res, next) => { speechPassport.authenticate('local-login', (err, user, info) => { diff --git a/server/routes/fallback/sendReactApp.js b/server/routes/fallback/sendReactApp.js index 794ab587..4a269454 100644 --- a/server/routes/fallback/sendReactApp.js +++ b/server/routes/fallback/sendReactApp.js @@ -1,4 +1,4 @@ -const handlePageRender = require('../../helpers/handlePageRender.jsx'); +const handlePageRender = require('../../render/handlePageRender.js'); const sendReactApp = (req, res) => { handlePageRender(req, res); diff --git a/server/routes/pages/sendReactApp.js b/server/routes/pages/sendReactApp.js index 794ab587..4a269454 100644 --- a/server/routes/pages/sendReactApp.js +++ b/server/routes/pages/sendReactApp.js @@ -1,4 +1,4 @@ -const handlePageRender = require('../../helpers/handlePageRender.jsx'); +const handlePageRender = require('../../render/handlePageRender.js'); const sendReactApp = (req, res) => { handlePageRender(req, res);