Code Monkey home page Code Monkey logo

rrssr-v4's People

Contributors

tylermcginnis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rrssr-v4's Issues

publish ssr app

Hi, can I ask you how to publish these ssr app to a host?
I am new to react and I want to setup a personnel blog using react and webpack and ssr feature.
I created complete structure of blog and service api but I don't know how to publish node base app in a host. :(

can you help me please :D ?

start

Hello, could you please explain how did you manage to use this command
"start": "webpack -w & nodemon server.js".
When I run it on windows webpack builds and starts watching files, and second command just don't start.
Thank you.

How to replace my EJS views with SSR of react components

Problem statement -
I have express ejs view for Server side rendering. I want to replace it React Server side view
e.g.

const view = 'testview';
res.render(view, { param1, param2, param3 });

I am trying to use this for replacing my EJS views with SS with something...
app.get('/view/:viewid', viewRender(param1, param2, param3)) ;

Somehow I am able to render, The button is render with property. But not very sure if the implementation is correct of need improvements. I will request to review and provide feedback
The steps are -

Step 1 - First create a dynamic View route /view/:viewId in routes.js
`
import Home from './Home'
import Grid from './Grid'
import DyanamicView from './DynamicView'
import TestPage from './TestPage.jsx'

import { fetchPopularRepos } from './api'

const routes = [
{
path: '/',
exact: true,
component: Home,
},
{
path: '/popular/:id',
component: Grid,
fetchInitialData: (path = '') => fetchPopularRepos(path.split('/').pop())
},
{
path: '/test',
exact: true,
component: TestPage
},
{
path: '/view/:viewId',
exact: true,
component: DyanamicView
}
]

export default routes
`

Step 2-
Create React component DyanamicView.jsx - This component take the viewId from route param, maps it to React Component and render it. Something similar to Express view engines

`
import React, { Component } from 'react'
import TestPage from './TestPage.jsx'

class DynamicView extends Component {
constructor(props) {
super(props)
let viewData;
if (isBrowser) {
viewData = window.INITIAL_DATA
delete window.INITIAL_DATA
} else {
viewData = this.props.staticContext.viewData
}
this.state = {
viewData,
Component: null,
error: {}
}
}

componentDidMount() {
    const viewName = this.props.match.params.viewId;
    console.log("Rendering dynamic 1 " + viewName)
    if (viewName === 'TestPage') {
        this.setState({ Component: TestPage })
    }
}

render() {
    const { Component } = this.state
    if (Component) {
        console.log("Rendering dynamic 2 " + Component)
        return (
            <div>
                <Component {...this.props} {...this.state.viewData} />
            </div>
        )
    }
    return null
}

}
export default DynamicView

Step 3 : Create the dymamic view - It is simple TestView with matirial-ui
`
import React from 'react';
import AppBar from 'material-ui/AppBar';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import RaisedButton from 'material-ui/RaisedButton';
import PropTypes from 'prop-types';

class TestPage extends React.Component {
constructor(props, context) {
super(props, context);
console.log("Rendering TestPage 1 ");
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render() {
console.log("Rendering TestPage 2 " +this.props);
return (




        </div>
    );
}

}

TestPage.childContextTypes = {
muiTheme: PropTypes.object.isRequired,
};
export default TestPage;
`

Step 4- Modify App.js to render dynamic view
`
import express from "express"
import cors from "cors"
import React from "react"
import { renderToString } from "react-dom/server"
import { StaticRouter, matchPath } from "react-router-dom"
import serialize from "serialize-javascript"
import App from '../shared/App'
import routes from '../shared/routes'

const app = express()

app.use(cors())
app.use(express.static("public"))

app.get('/view/:viewid', handleRender) ; //THIS is generic route for all dynamic Views*

//***THIS is request handler -- We need to pass View Params in the hardler curretly hard coded *****//

function handleRender(req,res) {
console.log("Finding match path URL component "+req.url)
const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
console.log("Finding match path URL component ");
var params = {name :'Manoj'}
const context = { params };

const markup = renderToString(
  <StaticRouter location={req.url} context={context}>
    <App />
  </StaticRouter>
)

res.send(`
  <!DOCTYPE html>
  <html>
    <head>
      <title>SSR with RR</title>
      <script src="/bundle.js" defer></script>
      <script>window.__INITIAL_DATA__ = ${serialize(params)}</script>
    </head>

    <body>
      <div id="app">${markup}</div>
    </body>
  </html>
`)

}

app.get("*", (req, res, next) => {
console.log("Finding match path URL component "+req.url)
const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
console.log("Finding match path URL component ")
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve()

promise.then((data) => {
const context = { data }

const markup = renderToString(
  <StaticRouter location={req.url} context={context}>
    <App />
  </StaticRouter>
)

res.send(`
  <!DOCTYPE html>
  <html>
    <head>
      <title>SSR with RR</title>
      <script src="/bundle.js" defer></script>
      <script>window.__INITIAL_DATA__ = ${serialize(data)}</script>
    </head>

    <body>
      <div id="app">${markup}</div>
    </body>
  </html>
`)

}).catch(next)
})

app.listen(3000, () => {
console.log(Server is listening on port: 3000)
})

`

`

running nodemon server.js --> Reference: 'document' is not defined

Hey Tyler. I used your rrssr-v4 template for my own project. I inserted my react application into the App.js that you created. What happened after running webpack -w is I get the error mentioned above (document is not defined) when I run nodemon server.js. I know document is a DOM variable which should not be defined in the server, hence the error.

Below is my error, package.json, and webpack.config.js. From the error, it looks like it has some problem with the webpack style-loader I use. Do you know why?

ReferenceError: document is not defined
    at insertStyleElement (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:93:15)
    at addStyle (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:208:13)
    at modulesToDom (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:81:18)
    at module.exports (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:239:25)
    at eval (webpack:///./src/shared/css/home-style.css?:15:14)

package.json

{

	"scripts": {
		"start": "webpack && nodemon server.js",
		"watch:server": "nodemon server.js",
		"watch:build": "webpack -w",
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"babel": {
		"presets": [
			"@babel/preset-env",
			"@babel/preset-react"
		],
		"plugins": [
			"@babel/plugin-proposal-object-rest-spread",
                        "@babel/plugin-proposal-class-properties"
		]
	},
	"devDependencies": {
		"@babel/core": "^7.3.4",
		"@babel/plugin-proposal-object-rest-spread": "^7.9.0",
                "@babel/plugin-proposal-class-properties": "^7.10.4",
		"@babel/preset-env": "^7.3.4",
		"@babel/preset-react": "^7.0.0",
		"babel-loader": "^8.1.0",
		"concurrently": "^5.3.0",
		"css-loader": "^4.2.1",
		"file-loader": "^6.0.0",
		"nodemon": "^2.0.4",
		"style-loader": "^1.2.1",
		"url-loader": "^4.1.0",
		"webpack": "^4.42.1",
		"webpack-cli": "^3.3.11",
		"webpack-node-externals": "^1.7.2"
	},
	"dependencies": {
		"cors": "^2.8.5",
		"express": "^4.17.1",
		"isomorphic-fetch": "^2.2.1",
		"npm-run-all": "^4.1.5",
		"pure-react-carousel": "^1.27.1",
		"react": "^16.13.1",
		"react-dom": "^16.13.1",
		"react-router-dom": "4.4.0-beta.8",
		"serialize-javascript": "^3.0.0"
	}
}

webpack.config.js

var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');

var browserConfig = {
	entry: './src/browser/index.js',
	output: {
		path: path.resolve(__dirname, 'public'),
		filename: 'bundle.js',
		publicPath: '/',
	},
	module: {
		rules: [
			{ test: /\.(js)$/, use: 'babel-loader' },
			{
				test: /\.css$/,
				use: ['style-loader', 'css-loader'],
			},
			{
				test: /\.(jpg|png|PNG|svg|jpe?g)$/,
				use: [
					{
						loader: 'file-loader',
						options: {
							outputPath: 'img/',
							publicPath: 'img/',
						},
					},
				],
			},
		],
	},
	mode: 'production',
	plugins: [
		new webpack.DefinePlugin({
			__isBrowser__: 'true',
		}),
	],
	performance: {
		maxEntrypointSize: 512000,
		maxAssetSize: 512000,
	},
};

var serverConfig = {
	entry: './src/server/index.js',
	target: 'node',
	externals: [nodeExternals()],
	output: {
		path: __dirname,
		filename: 'server.js',
		publicPath: '/',
	},
	module: {
		rules: [
			{ test: /\.(js)$/, use: 'babel-loader' },
			{
				test: /\.css$/,
				use: ['style-loader', 'css-loader'],
			},
			{
				test: /\.(jpg|png|PNG|svg|jpe?g)$/,
				use: [
					{
						loader: 'file-loader',
						options: {
							outputPath: 'img/',
							publicPath: 'img/',
						},
					},
				],
			},
		],
	},
	mode: 'production',
	plugins: [
		new webpack.DefinePlugin({
			__isBrowser__: 'false',
		}),
	],
	performance: {
		maxEntrypointSize: 512000,
		maxAssetSize: 512000,
	},
};

module.exports = [browserConfig, serverConfig];

Start error

` npm run start

[email protected] start /home/ubuntu/workspace/ssr/rrssr
webpack -w & nodemon server.js

[nodemon] 1.18.6
[nodemon] to restart at any time, enter rs
[nodemon] watching: .
[nodemon] starting node server.js index.js
module.js:471
throw err;
^

Error: Cannot find module '/home/ubuntu/workspace/ssr/rrssr/index.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:504:3
[nodemon] app crashed - waiting for file changes before starting...

Webpack is watching the files…

[nodemon] restarting due to changes...
[nodemon] starting node server.js index.js
[nodemon] restarting due to changes...
[nodemon] starting node server.js index.js
module.js:471
throw err;
^

Error: Cannot find module '/home/ubuntu/workspace/ssr/rrssr/index.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:504:3
[nodemon] app crashed - waiting for file changes before starting...
[BABEL] Note: The code generator has deoptimised the styling of "/home/ubuntu/workspace/ssr/rrssr/node_modules/react-dom/cjs/react-dom.development.js" as it exceeds the max of "500KB".
[nodemon] restarting due to changes...
[nodemon] starting node server.js index.js
Hash: bff9cea1ec1b7c6cae060ba71515fe741766f334
Version: webpack 3.12.0
Child
Hash: bff9cea1ec1b7c6cae06
Time: 16990ms
Asset Size Chunks Chunk Names
bundle.js 1.04 MB 0 [emitted] [big] main
[24] ./src/browser/index.js 546 bytes {0} [built]
[35] ./src/shared/App.js 3.85 kB {0} [built]
[36] ./src/shared/routes.js 726 bytes {0} [built]
[37] ./src/shared/Home.js 390 bytes {0} [built]
[38] ./src/shared/Grid.js 4.67 kB {0} [built]
[39] ./src/shared/api.js 854 bytes {0} [built]
[68] ./src/shared/Navbar.js 1.04 kB {0} [built]
[69] ./src/shared/NoMatch.js 391 bytes {0} [built]
+ 62 hidden modules
Child
Hash: 0ba71515fe741766f334
Time: 2860ms
Asset Size Chunks Chunk Names
server.js 17.9 kB 0 [emitted] main
[2] ./src/shared/routes.js 726 bytes {0} [built]
[3] ./src/server/index.js 2.22 kB {0} [built]
[8] ./src/shared/App.js 3.85 kB {0} [built]
[9] ./src/shared/Home.js 390 bytes {0} [built]
[10] ./src/shared/Grid.js 4.67 kB {0} [built]
[11] ./src/shared/api.js 854 bytes {0} [built]
[13] ./src/shared/Navbar.js 1.04 kB {0} [built]
[14] ./src/shared/NoMatch.js 391 bytes {0} [built]
+ 7 hidden modules
module.js:471
throw err;
^

Error: Cannot find module '/home/ubuntu/workspace/ssr/rrssr/index.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:504:3
[nodemon] app crashed - waiting for file changes before starting...`

What about the production build?

Please upgrade the webpack.config.js for production level and add the script to package.json. It would be more helpful. Also did you consider the code-splitting as well?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.