react-isomorphic-boilerplate
Advanced tools
Comparing version 0.1.3 to 0.2.0
{ | ||
"name": "react-isomorphic-boilerplate", | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"main": "src/server/index.js", | ||
"license": "MIT", | ||
"scripts": { | ||
"start": "DEBUG=*,-nodemon*,-express*,-send nodemon --inspect dist/server.js", | ||
"clean": "find dist -type f -not -name 'server.js' -delete", | ||
"start": "DEBUG=*,-nodemon*,-express*,-send nodemon --inspect dist/server/index.js", | ||
"clean": "rm -rf dist/assets/*.js", | ||
"build:client:dev": "npm run clean && webpack --env=dev --progress --profile --colors", | ||
@@ -29,3 +29,2 @@ "build:server:dev": "webpack --env=dev --config=webpack.server.js --progress --profile --colors", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babel-preset-react": "^6.24.1", | ||
@@ -32,0 +31,0 @@ "babel-preset-stage-2": "^6.24.1", |
@@ -45,7 +45,5 @@ # react-isomorphic-boilerplate | ||
[extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) would extract them (font, image) into `/dist` with hash key and handle url transform. (so you don't have to worry about cache issue) | ||
On the other hand, node server **only** serves static files in `/dist/assets` which means **/src/assets/ files not imported to your code base are not accessible from your web server.** | ||
[file-loader](https://github.com/webpack-contrib/file-loader) will exports them to static folder with hash key and handle url transform. (so you don't have to worry about cache issue) | ||
On the other hand, node server **only** serves static files in `/dist` which means **/src/assets/ files not imported to your code base are not accessible from your web server.** | ||
### Style | ||
@@ -56,2 +54,4 @@ - [reset.css](https://www.npmjs.com/package/reset-css) resets default style and is imported in [global.scss](https://github.com/ddhp/react-isomorphic-boilerplate/blob/master/src/client/global.scss). | ||
[extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) would extract style sheet from built code into target dist folder. | ||
### SEO | ||
@@ -80,3 +80,13 @@ - Define `loadData` method in your route to prefetch data needed for SEO. ([example](https://github.com/ddhp/react-isomorphic-boilerplate/blob/master/src/routes/main.js)) | ||
### TODO | ||
- i18n, possibly don't need any library to do this, we only need some handy helpers for those topics: | ||
- number: ? | ||
- date: by [momentjs](https://momentjs.com/) | ||
- money: ? | ||
basically we can approach by define our multi-lingual words in yaml(s) and get them by key and locale. | ||
- deprecate sass and use [styled-components](https://github.com/styled-components/styled-components) instead. | ||
- MODEL to handle api request and parse response. | ||
## LICENSE | ||
MIT |
@@ -8,3 +8,3 @@ import Express from 'express'; | ||
//Serve static files | ||
app.use('/assets', Express.static('dist')); | ||
app.use('/assets', Express.static('dist/assets')); | ||
@@ -11,0 +11,0 @@ apiMiddleware(app); |
@@ -1,45 +0,35 @@ | ||
import React from 'react'; | ||
import { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import assetsJSON from '../../webpack-assets.json'; | ||
import favicon from '../assets/images/favicon.ico'; | ||
import touchicon from '../assets/images/icon.png'; | ||
const assetsJSON = require('../../webpack-assets.json'); | ||
function renderFullPage(content, reduxState, head) { | ||
return ` | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> | ||
${head.title.toString()} | ||
${head.meta.toString()} | ||
export default class Layout extends Component { | ||
static propTypes = { | ||
content: PropTypes.object, | ||
reduxState: PropTypes.string, | ||
head: PropTypes.object | ||
} | ||
<link rel="icon" type="image/x-icon" href=${favicon} /> | ||
<link rel="apple-touch-icon" href=${touchicon} /> | ||
render() { | ||
const { content, reduxState, head } = this.props; | ||
return ( | ||
<html> | ||
<head> | ||
<meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" /> | ||
<meta charSet="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" /> | ||
{head.title.toComponent()} | ||
{head.meta.toComponent()} | ||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" /> | ||
<link href=${assetsJSON.main.css} rel="stylesheet" /> | ||
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico" /> | ||
<link rel="apple-touch-icon" href="/assets/images/icon.png" /> | ||
<script type="text/javascript" charSet="utf-8"> | ||
window.__REDUX_STATE__ = ${reduxState} | ||
</script> | ||
</head> | ||
<body> | ||
<div id="app-mount-point">${content}</div> | ||
<!-- entry script generated by webpack --> | ||
<script src=${assetsJSON.main.js} type="text/javascript" charSet="utf-8"></script> | ||
</body> | ||
</html> | ||
`; | ||
} | ||
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" /> | ||
<link href={assetsJSON.main.css} rel="stylesheet" /> | ||
<script type="text/javascript" charSet="utf-8" dangerouslySetInnerHTML={{__html: ` | ||
window.__REDUX_STATE__ = ${reduxState} | ||
`}} /> | ||
</head> | ||
<body> | ||
<div id="app-mount-point"> | ||
{content} | ||
</div> | ||
{/* entry script generated by webpack*/} | ||
<script src={assetsJSON.main.js} type="text/javascript" charSet="utf-8"></script> | ||
</body> | ||
</html> | ||
); | ||
} | ||
} | ||
export default renderFullPage; |
@@ -7,3 +7,3 @@ import React from 'react'; | ||
import { /*get as _get,*/ isFunction as _isFunction } from 'lodash'; | ||
import Layout from './layout'; | ||
import renderFullPage from './layout'; | ||
import configureStore from '../configureStore'; | ||
@@ -55,3 +55,3 @@ import MainRoute, { getRoute } from '../routes/main'; | ||
routerContext = {}, | ||
reduxState = JSON.stringify(store.getState()).replace(/</g, '\\u003c'); | ||
reduxStateString = JSON.stringify(store.getState()).replace(/</g, '\\u003c'); | ||
@@ -66,15 +66,9 @@ const content = ( | ||
ReactServer.renderToString(content); // render to sting to get helmet setting | ||
// render to sting to get helmet setting | ||
const contentString = ReactServer.renderToString(content); | ||
const head = Helmet.renderStatic(); | ||
const htmlString = renderFullPage(contentString, reduxStateString, head); | ||
const htmlString = ReactServer.renderToString( | ||
<Layout | ||
content={content} | ||
reduxState={reduxState} | ||
head={head} | ||
/> | ||
); | ||
res.send(`<!DOCTYPE HTML>${htmlString}`); | ||
res.send(htmlString); | ||
}); | ||
}; |
@@ -17,2 +17,4 @@ const path = require('path'); | ||
module.exports = { | ||
context: path.resolve(__dirname), | ||
entry: { | ||
@@ -22,3 +24,3 @@ main: path.resolve(__dirname, 'src/entries/main') | ||
output: { | ||
path: path.join(__dirname, '/dist'), | ||
path: path.join(__dirname, '/dist/assets'), | ||
publicPath: '/assets/', | ||
@@ -83,9 +85,30 @@ filename: '[chunkhash]-[name].js' | ||
{ | ||
test: /\.(gif|jpg|png|woff|woff2|eot|ttf|svg)$/, | ||
test: /\.(woff|woff2|eot|ttf)$/, | ||
use: [{ | ||
loader: 'url-loader', | ||
options: { | ||
limit: 8192 | ||
outputPath: '../assets/', | ||
limit: 8192 // 8kB | ||
} | ||
}] | ||
}, | ||
{ | ||
test: /\.(gif|jpg|png|svg)$/, | ||
use: [{ | ||
loader: 'url-loader', | ||
options: { | ||
outputPath: '../assets/', | ||
limit: 8192 // 8kB | ||
} | ||
}] | ||
}, | ||
{ | ||
// ico is lower than limit of url-loader, so we explictly use file-loader | ||
test: /.ico$/, | ||
use: [{ | ||
loader: 'file-loader', | ||
options: { | ||
outputPath: '../assets/', | ||
} | ||
}] | ||
} | ||
@@ -92,0 +115,0 @@ ] |
@@ -25,5 +25,5 @@ const webpack = require('webpack'); | ||
output: { | ||
path: path.join(__dirname, '/dist'), | ||
path: path.join(__dirname, '/dist/server'), | ||
publicPath: '/assets/', | ||
filename: '[name].js' | ||
filename: 'index.js' | ||
}, | ||
@@ -30,0 +30,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
466838
48
70
1552
90