Post List

2016년 10월 25일 화요일

react-router-tutorial #11 production-ish server

이번 예제를 위하여 11-productionish-server 디렉토리로 이동하고 npm install 을 실행 해 놓는다.

production 모드는 배포를 뜻하는 것이고, development 모드는 개발 을 뜻한다.
Node.js 프레임워크의 Express 의경우 production 모드일때는 파일 캐싱, 에러 메시지 감추기 등 배포의 적합한 환경을 설정을 한다.

development 모드일 경우는 파일 캐싱 방지, 디버그를 위한 상세한 에러 메시지 보이기 등의 개발에 필요한 환경을 설정을 해 준다.




1. 현재 디렉토리를 확인하자.

[binrang@binrang 11-productionish-server]$ ls -al
합계 52
drwxrwxr-x.   4 binrang binrang  4096 10월 25 14:26 .
drwxrwxr-x.  17 binrang binrang  4096 10월 25 14:26 ..
-rw-rw-r--.   1 binrang binrang  4295 10월 21 14:22 README.md
-rw-rw-r--.   1 binrang binrang    28 10월 21 14:22 index.css
-rw-rw-r--.   1 binrang binrang   195 10월 21 14:22 index.html
-rw-rw-r--.   1 binrang binrang   662 10월 21 14:22 index.js
drwxrwxr-x.   2 binrang binrang    94 10월 21 14:22 modules
drwxrwxr-x. 322 binrang binrang 12288 10월 25 14:26 node_modules
-rw-rw-r--.   1 binrang binrang   586 10월 21 14:22 package.json
-rw-rw-r--.   1 binrang binrang   253 10월 21 14:22 webpack.config.js
[binrang@binrang 11-productionish-server]$ 

2. 아래 모듈을 실행하자.

npm install express if-env compression --save

[binrang@binrang 11-productionish-server]$ npm install express if-env compression --save
tutorial@1.0.0 /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
├── compression@1.6.2 
├── express@4.14.0 
└─┬ if-env@1.0.0 
......
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.14: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN tutorial@1.0.0 No repository field.
[binrang@binrang 11-productionish-server]$

3. package.json 을 수정한다. script 부분을 찾아 보면 아래와 같이 되어 있다.

[binrang@binrang 11-productionish-server]$ pwd
/home/binrang/react/react-router-tutorial/lessons/11-productionish-server
[binrang@binrang 11-productionish-server]$ vi package.json 
{
  "name": "tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --inline --content-base . --history-api-fallback"
  },
  "author": "",
......

script 부분을 아래와 같이 수정한다.

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

start 를 할 때 이제 3개로 구분해서 실행이 가능하게 되었다.

4. 루트 디렉토리의 webpack.config.js 파일을 수정한다.

[binrang@binrang 11-productionish-server]$ pwd
/home/binrang/react/react-router-tutorial/lessons/11-productionish-server
[binrang@binrang 11-productionish-server]$ vi webpack.config.js 
module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
    ]
  }
}

이 부분 중에 output 부분을 수정한다.

  output: {
    path: 'public',
    filename: 'bundle.js',
    publicPath: '/'
  },

5 npm start 를 하여 웹 화면을 체크 해보자. npm start를 하면 NODE_ENV 환경변수가 production으로 세팅되는 것을 확인할 수 잇다.

[binrang@binrang 11-productionish-server]$ npm start
> tutorial@1.0.0 start /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> if-env NODE_ENV=production && npm run start:prod || npm run start:dev
> tutorial@1.0.0 start:dev /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> webpack-dev-server --inline --content-base . --history-api-fallback
 http://localhost:8080/
......
  [300] ./modules/Repo.js 547 bytes {0} [built]
  [301] ./modules/Home.js 452 bytes {0} [built]
webpack: bundle is now VALID.

홈 화면이 정상적으로 나타난다.

6. npm run start:prod 로 실행을 해 보자.

[binrang@binrang 11-productionish-server]$ npm run start:prod
> tutorial@1.0.0 start:prod /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> webpack && node server.js
Hash: 4b8063173d277f8be11f
Version: webpack 1.13.2
Time: 1810ms
    Asset    Size  Chunks             Chunk Names
bundle.js  866 kB       0  [emitted]  main
    + 228 hidden modules
module.js:471
    throw err;
......
npm ERR! Please include the following file with any support request:
npm ERR!     /home/binrang/react/react-router-tutorial/lessons/11-productionish-server/npm-debug.log
[binrang@binrang 11-productionish-server]$ 

하지만, 에러만 뜬다. server.js 가 없다고 뜨는 에러다..  일단 여기까지 하고 다음 명령어로 넘어가자.

7. npm run start:dev 를 실행 해 보자.

[binrang@binrang 11-productionish-server]$ npm run start:dev
> tutorial@1.0.0 start:dev /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> webpack-dev-server --inline --content-base . --history-api-fallback
 http://localhost:8080/
webpack result is served from /
......
  [300] ./modules/Repo.js 547 bytes {0} [built]
  [301] ./modules/Home.js 452 bytes {0} [built]
webpack: bundle is now VALID.

웹 화면을 확인해보자.
별 이상 없이 뜬다.

8. 6번에서 에러 난 부분을 해결해 보자. 루트 밑에 server.js 파일을 생성하고 express 관련 하여 코드를 추가 해보자.

[binrang@binrang 11-productionish-server]$ pwd
/home/binrang/react/react-router-tutorial/lessons/11-productionish-server
[binrang@binrang 11-productionish-server]$ vi server.js 
var express = require('express')
var path = require('path')
var app = express()
// serve our static stuff like index.css
app.use(express.static(__dirname))
// send all requests to index.html so browserHistory in React Router works
app.get('*', function (req, res) {
  res.sendFile(path.join(__dirname, 'index.html'))
})
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
  console.log('Production Express server running at localhost:' + PORT)
})

이제 production 모드로 실행 해 보자.

[binrang@binrang 11-productionish-server]$ NODE_ENV=production npm start
> tutorial@1.0.0 start /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> if-env NODE_ENV=production && npm run start:prod || npm run start:dev
> tutorial@1.0.0 start:prod /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> webpack && node server.js
Hash: 4b8063173d277f8be11f
Version: webpack 1.13.2
Time: 1801ms
    Asset    Size  Chunks             Chunk Names
bundle.js  866 kB       0  [emitted]  main
    + 228 hidden modules
Production Express server running at localhost:8080

NODE_ENV=production npm start
# 윈도우즈 사용자인 경우는
# SET "NODE_ENV=production" && npm start

이제 웹 화면을 보자.

빈 화면을 만났다..이런..
URL란에 http://localhost:8080/package.json 을 입력해 보자.
package.json 내용이 뜬다.
9. index.html 과 index.css 파일을 public 디렉토리로 이동 시킨다.

[binrang@binrang 11-productionish-server]$ mv index.html index.css public/
[binrang@binrang 11-productionish-server]$ 

10. server.js 파일을 수정한다.

[binrang@binrang 11-productionish-server]$ vi server.js 
var express = require('express')
var path = require('path')
var app = express()
// serve our static stuff like index.css
// path.join 을 추가한다.
//app.use(express.static(__dirname))
app.use(express.static(path.join(__dirname, 'public')))
// send all requests to index.html so browserHistory in React Router works
app.get('*', function (req, res) {
  // 중간 부분에  'public' 을 추가한다.
  //res.sendFile(path.join(__dirname, 'index.html'))
  res.sendFile(path.join(__dirname, 'public', 'index.html'))
})
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
  console.log('Production Express server running at localhost:' + PORT)
})

11. package.json 파일에 start:dev 부분을 변경한다.

"start:dev": "webpack-dev-server --inline --content-base . --history-api-fallback",
==>
"start:dev": "webpack-dev-server --inline --content-base public --history-api-fallback",

12. webpack.config.js 파일을 수정한다.

[binrang@binrang 11-productionish-server]$ vi webpack.config.js 
// make sure to import this
var webpack = require('webpack')
module.exports = {
  entry: './index.js',
  output: {
    path: 'public',
    filename: 'bundle.js',
    publicPath: '/'
  },
  // add this handful of plugins that optimize the build
  // when we're in production
  plugins: process.env.NODE_ENV === 'production' ? [
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin()
  ] : [],
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' }
    ]
  }
}

[binrang@binrang 11-productionish-server]$ vi server.js 
var express = require('express')
var path = require('path')
// express 의 compression 을 추가한다.
var compression = require('compression')
var app = express()
// 첫번째 부분에 사용한다.
app.use(compression())
// serve our static stuff like index.css
// path.join 을 추가한다.
//app.use(express.static(__dirname))
app.use(express.static(path.join(__dirname, 'public')))
// send all requests to index.html so browserHistory in React Router works
app.get('*', function (req, res) {
  // 중간 부분에  'public' 을 추가한다.
  //res.sendFile(path.join(__dirname, 'index.html'))
  res.sendFile(path.join(__dirname, 'public', 'index.html'))
})
var PORT = process.env.PORT || 8080
app.listen(PORT, function() {
  console.log('Production Express server running at localhost:' + PORT)
})

13. 이제 production 모드로 실행을 해보자.

[binrang@binrang 11-productionish-server]$ NODE_ENV=production npm start
> tutorial@1.0.0 start /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> if-env NODE_ENV=production && npm run start:prod || npm run start:dev
> tutorial@1.0.0 start:prod /home/binrang/react/react-router-tutorial/lessons/11-productionish-server
> webpack && node server.js
......
Dropping side-effect-free statement [./~/react/lib/ReactEventListener.js:72,0]
Dropping unused function handleTopLevelWithPath [./~/react/lib/ReactEventListener.js:98,0]
Dropping unused variable DOCUMENT_FRAGMENT_NODE_TYPE [./~/react/lib/ReactEventListener.js:26,0]
Production Express server running at localhost:8080

웹 화면을 확인해 보자.
package.json 화면은 blank 로 나온다.

이 홈 화면도 제대로 나온다.

에혀.. 이번은 많이 힘드네..ㅎㅎ

참조 URL : 11-productionish-server