├── .env
├── .eslintrc
├── .gitignore
├── README.md
├── package.json
├── public
├── favicon.ico
└── robots.txt
├── src
├── application
│ └── Main.js
├── client.js
├── index.js
├── server.js
└── static.js
└── yarn.lock
/.env:
--------------------------------------------------------------------------------
1 | HOST=127.0.0.1
2 | PORT=80
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "react-app"
3 | , "rules": {
4 | "no-undef": 1
5 | , "eqeqeq": 0
6 | , "no-mixed-operators": 0
7 | , "no-extend-native": 0
8 |
9 | , "react/no-direct-mutation-state": 0
10 |
11 | , "no-useless-concat": 0
12 | }
13 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | static
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Razzle Material-UI Styled Example
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
⭐ Star and get notified about new releases via email.
19 |
20 |
21 | ## Features
22 | -
23 | - **S**erver **S**ide **R**endering
24 | - **H**ot **M**odule **R**eplacement for both client and server side
[React](https://facebook.github.io/react/) components
25 | - Up to date JavaScript ([**E**CMA](https://en.wikipedia.org/wiki/Ecma_International)**S**cript 6 (2015)) support
26 | - Single route static site generation
27 | -
server with gzip [compression](https://github.com/expressjs/compression)
28 | - HTML and inline CSS and JS minification with [HTMLMinifier](https://github.com/kangax/html-minifier)
29 | -
[Styled Components](https://www.styled-components.com/)
30 | -
[Material-UI](http://www.material-ui.com/#/)
31 |
32 | ## Getting Started
33 | - Initial steps
34 | - Install
and
.
35 | - [Download](https://github.com/kireerik/razzle-material-ui-styled-example/archive/master.zip) or [clone](github-windows://openRepo/https://github.com/kireerik/razzle-material-ui-styled-example) this repository.
36 | - Open a command prompt in the project folder.
37 |
38 | > Install dependencies:
39 | > ```shell
40 | > yarn install
41 | > ```
42 |
43 | Start the server:
44 | > ```shell
45 | > yarn start
46 | > ```
47 | > This command initiates a build process and starts the server in production mode.
48 |
49 | Visit http://localhost/ to access the web application.
50 |
51 | ### Development
52 | Start the server in development mode:
53 | ```shell
54 | yarn dev
55 | ```
56 |
57 | ### Single route static site generation
58 | Generate a static site:
59 | ```shell
60 | yarn static
61 | ```
62 | Open the `index.html` within the `static` folder to access the web application. The folder name can be modified with the `RAZZLE_STATIC_PATH` environment variable.
63 |
64 | ## Idea behind the example
65 | This project is based on the [basic razzle example](https://github.com/jaredpalmer/razzle/tree/master/examples/basic). This repository also satisfies the following 2 entry points requred by Razzle:
66 | - `src/index.js` for the server
67 | - `src/client.js` for the browser
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "start": "razzle build && cross-env NODE_ENV=production node build/server.js"
4 | , "dev": "razzle start"
5 |
6 | , "static": "cross-env RAZZLE_STATIC=true razzle build && cross-env NODE_ENV=production node build/server.js"
7 | }
8 | , "dependencies": {
9 | "express": "4.x"
10 | , "compression": "1.x"
11 | , "html-minifier": "3.x"
12 |
13 | , "react": "16.x"
14 | , "react-dom": "16.x"
15 | , "styled-components": "3.x"
16 |
17 | , "material-ui": "0.x"
18 | }
19 | , "devDependencies": {
20 | "cross-env": "5.x"
21 | , "razzle": "2.x"
22 | }
23 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kireerik/razzle-material-ui-styled-example/d5ea65bab29106de9d6a6be6d9ff7016f7d9445e/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 |
3 | #Sitemap:
--------------------------------------------------------------------------------
/src/application/Main.js:
--------------------------------------------------------------------------------
1 | // In this file, we create a React component which contains components provided by Material-UI.
2 | import React, {Component} from 'react'
3 | import styled, {injectGlobal} from 'styled-components'
4 |
5 | import {MuiThemeProvider, getMuiTheme} from 'material-ui/styles'
6 | import {deepOrange500} from 'material-ui/styles/colors'
7 |
8 | import {RaisedButton, Dialog, FlatButton} from 'material-ui'
9 |
10 | injectGlobal`
11 | h1, h2 {
12 | font-family: 'Roboto', sans-serif;
13 | }
14 | `
15 |
16 | const Div = styled.div`
17 | text-align: center;
18 | padding-top: 200px;
19 | `
20 |
21 | export default class Main extends Component {
22 | constructor(properties) {
23 | super(properties)
24 |
25 | this.muiTheme = getMuiTheme({
26 | palette: {
27 | accent1Color: deepOrange500
28 | }
29 | , userAgent: properties.userAgent
30 | })
31 |
32 | this.state = {
33 | open: false
34 | }
35 | }
36 |
37 | handleRequestClose = () => this.setState({
38 | open: false
39 | })
40 |
41 | handleClick = () => this.setState({
42 | open: true
43 | })
44 |
45 | render = () =>
46 |
47 |
48 |
Material-UI
49 | example project
50 |
51 |
52 |
54 | } onRequestClose={this.handleRequestClose}>1-2-3-4-5
55 |
56 |
57 | }
--------------------------------------------------------------------------------
/src/client.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {hydrate} from 'react-dom'
3 |
4 | import Application from './application/Main'
5 |
6 | hydrate(, document.getElementById('root'))
7 |
8 | if (module.hot)
9 | module.hot.accept()
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import server from './server'
3 |
4 | import generateStaticSite from './static'
5 |
6 | if (module.hot) {
7 | module.hot.accept('./server')
8 | console.info('Server-side HMR Enabled.\n')
9 | }
10 |
11 | const mainServer = express()
12 | .use((request, response) => server.handle(request, response))
13 |
14 | , serverInstance = mainServer
15 | .listen(process.env.PORT, error => {
16 | if (error) {
17 | console.error(error)
18 |
19 | return
20 | }
21 |
22 | console.log('Server started at ' + process.env.HOST + ':' + process.env.PORT + '.\n')
23 |
24 | if (process.env.RAZZLE_STATIC)
25 | generateStaticSite(serverInstance)
26 | })
27 |
28 | export default mainServer
--------------------------------------------------------------------------------
/src/server.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import compression from 'compression'
3 | import {minify} from 'html-minifier'
4 |
5 | import React from 'react'
6 | import {renderToString} from 'react-dom/server'
7 | import {ServerStyleSheet} from 'styled-components'
8 |
9 | import Application from './application/Main'
10 |
11 | const assets = require(process.env.RAZZLE_ASSETS_MANIFEST)
12 |
13 | // Workaround for Razzle's assets route issue in terms of static site genearation
14 | var clientCss = assets.client.css
15 | , clientJs = assets.client.js
16 |
17 | if (process.env.NODE_ENV == 'production') {
18 | if (clientCss)
19 | clientCss = clientCss.replace('/', '')
20 |
21 | clientJs = clientJs.replace('/', '')
22 | }
23 |
24 | export default express()
25 | .disable('x-powered-by')
26 | .use(compression())
27 | .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
28 | .get('/*', (request, response) => {
29 | const sheet = new ServerStyleSheet()
30 | , html = renderToString(sheet.collectStyles())
31 | , css = sheet.getStyleTags()
32 |
33 | response.send(minify(
34 | `
35 |
36 |
37 | Material-UI Example
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | ` + (clientCss ?
48 | '' : ''
49 | ) + css + `
50 |
51 |
52 |
53 |
54 | ` + html + `
55 |
56 | `
57 | , {
58 | collapseWhitespace: true
59 | , removeComments: true
60 | , minifyCSS: true
61 | , minifyJS: true
62 | }))
63 | })
--------------------------------------------------------------------------------
/src/static.js:
--------------------------------------------------------------------------------
1 | import http from 'http'
2 | import fs from 'fs-extra'
3 |
4 | const staticDirectory = process.env.RAZZLE_STATIC_PATH || 'static'
5 |
6 | export default server => {
7 | fs.emptyDirSync(staticDirectory)
8 |
9 | fs.copy(process.env.RAZZLE_PUBLIC_DIR, staticDirectory)
10 |
11 | http.get({url: 'http://' + process.env.HOST + ':' + process.env.PORT
12 | , headers: {'User-Agent': 'all'}
13 | }, response =>
14 | response.on('data', html =>
15 | fs.writeFile(staticDirectory + '/' + 'index.html', html, error => {
16 | if (error)
17 | console.error(error)
18 |
19 | server.close()
20 |
21 | console.log('Static site generated.\n')
22 | })
23 | )
24 | )
25 | }
--------------------------------------------------------------------------------