Skip to content
This repository was archived by the owner on May 21, 2020. It is now read-only.

Commit 8f258f0

Browse files
committed
refactor(Html): stateless Html component
1 parent 050cf66 commit 8f258f0

File tree

2 files changed

+98
-105
lines changed

2 files changed

+98
-105
lines changed

src/server/components/Html.jsx

Lines changed: 92 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,97 @@
11

22
import { appName, inlineName, isDev, outputPath, statsName, vendorName } from '../../../webpack/env'
3-
import React, { PropTypes as PT, PureComponent } from 'react'
3+
import { renderToStaticMarkup as renderStatic } from 'react-dom/server'
4+
import React, { PropTypes as PT } from 'react'
45
import fs from 'fs'
5-
import { renderToStaticMarkup } from 'react-dom/server'
6-
7-
class Html extends PureComponent {
8-
9-
static getDoctype() {
10-
return '<!doctype html>'
11-
}
12-
13-
static getScript(name) {
14-
if (isDev) return `/${name}.js`
15-
16-
const file = fs.readFileSync(`${outputPath}/${statsName}.json`)
17-
const stats = JSON.parse(file)
18-
19-
return name === 'app' && !isDev
20-
? `/${stats.assetsByChunkName[name][0]}`
21-
: `/${stats.assetsByChunkName[name]}`
22-
}
23-
24-
static getWebpackJsonpInlineScript() {
25-
if (isDev) return false
26-
return fs.readFileSync(`${outputPath}/${inlineName}.js`)
27-
}
28-
29-
static renderToStaticMarkup(props) {
30-
return Html.getDoctype() + renderToStaticMarkup(<Html {...props}/>)
31-
}
32-
33-
render() {
34-
const { app, content, initalState, inline, vendor } = this.props
35-
36-
return (
37-
<html
38-
className='no-js'
39-
lang='en_US'
40-
>
41-
<head>
42-
<meta charSet='utf-8'/>
43-
<meta content='IE=edge,chrome=1' httpEquiv='X-UA-Compatible'/>
44-
45-
<title>Universal React Webpack Boilerplate</title>
46-
47-
<meta content='' name='description'/>
48-
<meta content='' name='keywords'/>
49-
50-
{/* Spiders must use meta description */}
51-
<meta content='noodp, noydir' name='robots'/>
52-
53-
{/* No Google Translate toolbar */}
54-
<meta content='notranslate' name='google'/>
55-
56-
{/* Viewport and mobile */}
57-
<meta content='width = device-width,
58-
initial-scale = 1,
59-
user-scalable = no,
60-
maximum-scale = 1,
61-
minimum-scale = 1'
62-
name='viewport'
63-
/>
64-
<meta content='true' name='HandheldFriendly'/>
65-
<meta content='320' name='MobileOptimized'/>
66-
67-
<link href='/apple-icon-57x57.png' rel='apple-touch-icon' sizes='57x57'/>
68-
<link href='/apple-icon-60x60.png' rel='apple-touch-icon' sizes='60x60'/>
69-
<link href='/apple-icon-72x72.png' rel='apple-touch-icon' sizes='72x72'/>
70-
<link href='/apple-icon-76x76.png' rel='apple-touch-icon' sizes='76x76'/>
71-
<link href='/apple-icon-114x114.png' rel='apple-touch-icon' sizes='114x114'/>
72-
<link href='/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/>
73-
<link href='/apple-icon-144x144.png' rel='apple-touch-icon' sizes='144x144'/>
74-
<link href='/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/>
75-
<link href='/apple-icon-180x180.png' rel='apple-touch-icon' sizes='180x180'/>
76-
<link href='/android-icon-192x192.png' rel='icon' sizes='192x192' type='image/png'/>
77-
<link href='/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/>
78-
<link href='/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/>
79-
<link href='/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/>
80-
81-
<meta content='#ffffff' name='msapplication-TileColor'/>
82-
<meta content='/ms-icon-144x144.png' name='msapplication-TileImage'/>
83-
<meta content='#ffffff' name='theme-color'/>
84-
85-
{!isDev && <link href='/style.css' rel='stylesheet'/>}
86-
</head>
87-
<body>
88-
<div id='app'>
89-
<div dangerouslySetInnerHTML={{ __html: content }}/>
90-
</div>
91-
92-
<script dangerouslySetInnerHTML={{ __html: `window.__INITAL_STATE__ = ${JSON.stringify(initalState)}` }}/>
93-
{inline && <script dangerouslySetInnerHTML={{ __html: inline }}/>}
94-
<script src={vendor}/>
95-
<script src={app}/>
96-
</body>
97-
</html>
98-
)
99-
}
6+
7+
export const getScript = (name) => {
8+
if (isDev) return `/${name}.js`
9+
10+
const file = fs.readFileSync(`${outputPath}/${statsName}.json`)
11+
const stats = JSON.parse(file)
12+
13+
return name === 'app' && !isDev
14+
? `/${stats.assetsByChunkName[name][0]}`
15+
: `/${stats.assetsByChunkName[name]}`
10016
}
10117

18+
export const getWebpackJsonpInlineScript = () => {
19+
if (isDev) return false
20+
return fs.readFileSync(`${outputPath}/${inlineName}.js`)
21+
}
22+
23+
export const renderToStaticMarkup = (props) => `<!doctype html>${renderStatic(<Html {...props}/>)}`
24+
25+
const Html = ({
26+
app,
27+
content,
28+
initalState,
29+
inline,
30+
vendor,
31+
}) => (
32+
<html
33+
className='no-js'
34+
lang='en_US'
35+
>
36+
<head>
37+
<meta charSet='utf-8'/>
38+
<meta content='IE=edge,chrome=1' httpEquiv='X-UA-Compatible'/>
39+
40+
<title>Universal React Webpack Boilerplate</title>
41+
42+
<meta content='' name='description'/>
43+
<meta content='' name='keywords'/>
44+
45+
{/* Spiders must use meta description */}
46+
<meta content='noodp, noydir' name='robots'/>
47+
48+
{/* No Google Translate toolbar */}
49+
<meta content='notranslate' name='google'/>
50+
51+
{/* Viewport and mobile */}
52+
<meta content='width = device-width,
53+
initial-scale = 1,
54+
user-scalable = no,
55+
maximum-scale = 1,
56+
minimum-scale = 1'
57+
name='viewport'
58+
/>
59+
<meta content='true' name='HandheldFriendly'/>
60+
<meta content='320' name='MobileOptimized'/>
61+
62+
<link href='/apple-icon-57x57.png' rel='apple-touch-icon' sizes='57x57'/>
63+
<link href='/apple-icon-60x60.png' rel='apple-touch-icon' sizes='60x60'/>
64+
<link href='/apple-icon-72x72.png' rel='apple-touch-icon' sizes='72x72'/>
65+
<link href='/apple-icon-76x76.png' rel='apple-touch-icon' sizes='76x76'/>
66+
<link href='/apple-icon-114x114.png' rel='apple-touch-icon' sizes='114x114'/>
67+
<link href='/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/>
68+
<link href='/apple-icon-144x144.png' rel='apple-touch-icon' sizes='144x144'/>
69+
<link href='/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/>
70+
<link href='/apple-icon-180x180.png' rel='apple-touch-icon' sizes='180x180'/>
71+
<link href='/android-icon-192x192.png' rel='icon' sizes='192x192' type='image/png'/>
72+
<link href='/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/>
73+
<link href='/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/>
74+
<link href='/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/>
75+
76+
<meta content='#ffffff' name='msapplication-TileColor'/>
77+
<meta content='/ms-icon-144x144.png' name='msapplication-TileImage'/>
78+
<meta content='#ffffff' name='theme-color'/>
79+
80+
{!isDev && <link href='/style.css' rel='stylesheet'/>}
81+
</head>
82+
<body>
83+
<div id='app'>
84+
<div dangerouslySetInnerHTML={{ __html: content }}/>
85+
</div>
86+
87+
<script dangerouslySetInnerHTML={{ __html: `window.__INITAL_STATE__ = ${JSON.stringify(initalState)}` }}/>
88+
{inline && <script dangerouslySetInnerHTML={{ __html: inline }}/>}
89+
<script src={vendor}/>
90+
<script src={app}/>
91+
</body>
92+
</html>
93+
)
94+
10295
Html.propTypes = {
10396
app: PT.string.isRequired,
10497
content: PT.string.isRequired,
@@ -108,9 +101,9 @@ Html.propTypes = {
108101
}
109102

110103
Html.defaultProps = {
111-
app: Html.getScript(appName),
112-
vendor: Html.getScript(vendorName),
113-
inline: Html.getWebpackJsonpInlineScript(),
104+
app: getScript(appName),
105+
vendor: getScript(vendorName),
106+
inline: getWebpackJsonpInlineScript(),
114107
}
115108

116109
export default Html

src/server/middlewares/viewMiddleware.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
// View Middleware
44
//
55

6-
import { RouterContext, match } from 'react-router'
7-
import Html from '../components/Html.jsx'
86
import { Provider } from 'react-redux'
9-
import React from 'react'
10-
import configureStore from 'configureStore'
11-
import reducers from '../../shared/modules'
7+
import { renderToStaticMarkup } from '../components/Html.jsx'
128
import { renderToString } from 'react-dom/server'
139
import { route as routes } from '../../Application'
10+
import { RouterContext, match } from 'react-router'
11+
import configureStore from 'configureStore'
12+
import React from 'react'
13+
import reducers from '../../shared/modules'
1414

1515
export default (app) => {
1616
// match everything else
@@ -41,6 +41,6 @@ export default (app) => {
4141
)
4242
const content = renderToString(provider)
4343

44-
return Html.renderToStaticMarkup({ content, initalState })
44+
return renderToStaticMarkup({ content, initalState })
4545
}
4646
}

0 commit comments

Comments
 (0)