Post List

2016년 10월 26일 수요일

react-router-tutorial #13 server rendering

13-server-rendering 디렉토리로 이동 한 후 npm install 을 실행하자.

1. 루트 디렉토리에 webpack.server.config.js 파일을 신규로 만들고 아래 코드를 입력한다.

[binrang@binrang 13-server-rendering]$ pwd
/home/binrang/react/react-router-tutorial/lessons/13-server-rendering
[binrang@binrang 13-server-rendering]$ vi webpack.server.config.js
var fs = require('fs')
var path = require('path')
module.exports = {
  entry: path.resolve(__dirname, 'server.js'),
  output: {
    filename: 'server.bundle.js'
  },
  target: 'node',
  // keep node_module paths out of the bundle
  externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
    'react-dom/server', 'react/addons',
  ]).reduce(function (ext, mod) {
    ext[mod] = 'commonjs ' + mod
    return ext
  }, {}),
  node: {
    __filename: true,
    __dirname: true
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
    ]
  }
}



2. package.json에 대하여 아래와 같이 수정한다.

  "scripts": {
    "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
    "start:dev": "webpack-dev-server --inline --content-base public/ --history-api-fallback",
    "start:prod": "webpack && node server.js"
  },
==>
"scripts": {
  "start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
  "start:dev": "webpack-dev-server --inline --content-base public/ --history-api-fallback",
  "start:prod": "npm run build && node server.bundle.js",
  "build:client": "webpack",
  "build:server": "webpack --config webpack.server.config.js",
  "build": "npm run build:client && npm run build:server"
},

3. modules/routes.js 파일을 생성하고 아래와 같이 코드를 입력한다.

[binrang@binrang modules]$ pwd
/home/binrang/react/react-router-tutorial/lessons/13-server-rendering/modules
[binrang@binrang modules]$ vi routes.js 
import React from 'react'
import { Route, IndexRoute } from 'react-router'
import App from './App'
import About from './About'
import Repos from './Repos'
import Repo from './Repo'
import Home from './Home'
module.exports = (
  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="/repos" component={Repos}>
      <Route path="/repos/:userName/:repoName" component={Repo}/>
    </Route>
    <Route path="/about" component={About}/>
  </Route>
)

4. index.js 파일을 아래와 같이 수정한다.

[binrang@binrang 13-server-rendering]$ pwd
/home/binrang/react/react-router-tutorial/lessons/13-server-rendering
[binrang@binrang 13-server-rendering]$ vi index.js
import React from 'react'
import { render } from 'react-dom'
import { Router, browserHistory } from 'react-router'
// import routes and pass them into <Router/>
import routes from './modules/routes'
render((
  <Router routes={routes} history={browserHistory}/>,
  document.getElementById('app')
)

5. server.js 파일을 아래와 같이 수정한다.

[binrang@binrang 13-server-rendering]$ pwd
/home/binrang/react/react-router-tutorial/lessons/13-server-rendering
[binrang@binrang 13-server-rendering]$ vi server.js 
import express from 'express'
import path from 'path'
import compression from 'compression'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { match, RouterContext } from 'react-router'
import routes from './modules/routes'
var app = express()
app.use(compression())
// serve our static stuff like index.css
app.use(express.static(path.join(__dirname, 'public'), {index: false}))
// send all requests to index.html so browserHistory works
app.get('*', (req, res) => {
  match({ routes, location: req.url }, (err, redirect, props) => {
    if (err) {
      res.status(500).send(err.message)
    } else if (redirect) {
      res.redirect(redirect.pathname + redirect.search)
    } else if (props) {
      // hey we made it!
      const appHtml = renderToString(<RouterContext {...props}/>)
      res.send(renderPage(appHtml))
    } else {
      res.status(404).send('Not Found')
    }
  })
})
function renderPage(appHtml) {
  return `
    <!doctype html public="storage">
    <html>
    <meta charset=utf-8/>
    <title>My First React Router App</title>
    <link rel=stylesheet href=/index.css>
    <div id=app>${appHtml}</div>
    <script src="/bundle.js"></script>
   `
}
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
  console.log('Production Express server running at localhost:' + PORT)
})


6. npm start 와 NODE_ENV=production npm start 모드로 각각 실행하여 웹 화면을 비교해보자.

걍 똑같다... 이제까지 했던 것은 서버 쪽에 라우팅을 바꾸어본것인데...이렇게 운영도 가능하다.


똑 같다.. Routing을 다르게 했을 뿐인데...
엉뚱한 URL을 넣으면 server.js에 코딩한 Not Found가 뜬다.



참조 URL : 13-server-rendering