JavaScriptだけでWebサイト開発

node.js + Express + mongodb系 + React でサービスを作るメモ

create-react-appのアプリをExpress内で配置、配信する

クライアントReactアプリとWebサーバー&APIサーバーを分けるのが面倒で一箇所(プロセス)でホスティングしたいときがあります

create-react-app で作成したプロジェクトをexpressの /_admin 以下で動作(配信)させてみます

Express環境

$ express together
   create : together
   create : together/package.json
   create : together/app.js
   create : together/public
   create : together/routes
   create : together/routes/index.js
   create : together/routes/users.js
   create : together/views
   create : together/views/index.jade
   create : together/views/layout.jade
   create : together/views/error.jade
   create : together/bin
   create : together/bin/www
   create : together/public/javascripts
   create : together/public/images
   create : together/public/stylesheets
   create : together/public/stylesheets/style.css

   install dependencies:
     $ cd together && npm install

   run the app:
     $ DEBUG=together:* npm start

$ cd together/
$ npm install

create-react-appをexpressプロジェクト内で作成

$ cd together
$ create-react-app client
create-react-app client

Creating a new React app in ~/together/client.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...

ディレクトリ構造は

together
├── app.js
├── bin
├── client         <-- ここにcreate-react-app
├── node_modules
├── package-lock.json
├── package.json
├── public
├── routes
└── views

express の app.js

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

// 静的ファイルの配信をURL毎に設定
//----------------------------------------------
app.use('/_admin',express.static(path.join(__dirname, 'client/build')));

// publicのstatic
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

clientのreactアプリを express上の /_admin で動作させたいので

app.use('/_admin',express.static(path.join(__dirname, 'client/build')));

create-react-app の package.json

client/package.json

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "homepage": "/_admin", // <--- ここにBase URLを設定
  "dependencies": {
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-scripts": "1.0.17"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

create-react-appをbuild

$ cd ~/together/client
$ npm run build

express サーバー起動

$ cd ~/together
$ npm start

ブラウザで確認

localhost:3000 expressのデフォルトページ(route / )が表示されます

localhost:3000/users expressのroute /users が表示されます

localhost:3000/_admin create-react-app のおなじみのデフォルトページが表示されます。

以上です

©ichi-bit