2018-09-10

超今さらExpress触ってみた - その1 Expressって生々しすぎない? -

Express - Node.js web application framework

背景

  • これまでサーバサイド Node.js は callback 地獄に耐えられなさそうで避けてきてて、サーバサイドは基本 Rails 、インフラはフルマネージドに持っていくようにしてる
  • Webサーバと Rails と PHP はまぁそれなりに使える、JavaScript そのものを書くのは別にそんな困らないけど、Node.js 独自の事情はよく知らない
  • Google BigQuery の導入に向けて Google Cloud の Storage と Functions を使っていく作戦
    • Cloud Functions は調べ始めた段階で Node.js 6 のみ対応1
    • HTTP-triggered Function は Express の req, res オブジェクトが渡ってくる

ということで Node.js 6 ベースで Express.js を書くというのが当面の目標で、最終的には Functions で動くようにしつつテストコードも書きたい、というところを目指していく。

以下は Express のドキュメントはほとんど読んでなくてあり合わせの知識で作業をしてたので変なことしてたら教えてほしいです。(こういうの書いててリアクションあったことほぼないんだけど)

まず普通に動かす

これはまぁ簡単。特に書くこともないけど、Node.js 6 前提なので、npm ではなく yarn で入れてみた。くらいかな。npm 5 が bundle されるのは Node.js 8 から、らしいので。

The npm Blog — npm@5 is now `npm@latest`

びっくりしたのはサーバの起動メッセージも何も出ないんですね…。

routingはアプリの中の事情であって環境の事情とは分けたい

サーバのセットアップとアプリの設定は分けたかったので、server.js と app.js に分けてみる。

app.js

const express = require('express')

const app = express()

app.get('/', (req, res) => {
  res.send('Hello Express')
})

module.exports = app

server.js

const app = require('./app')

app.listen(3000, () => {
  console.log('Starting server localhost:3000 ...')
})

これを

node server.js

で起動する。

なにもかもねぇのでmiddlewareを足す、が、

少なくとも Rails の development 環境にはあった

  1. request ごとのログ2が自動的に出力される
  2. 変更に追随してコードを自動的にリロード

機能がない。これは割と致命的に不便。

ということで以下を追加。

ここで困った。と言うのも上で server.js と app.js を分けていたんだけど、middleware の記述はどっちかというとアプリそのものというよりは環境に近いので server.js に分けたい。ところが

const morgan = require('morgan')
const app    = require('./app')

app.use(morgan('combined'))

app.listen(3000, () => {
..

とは書けない。

どうも、

routing の後に middleware を追加しようとするのはダメっぽい。

はーなるほど。まぁ分からなくもないんだけど、そういうの、記述順に依存せずに動くような、Sinatra で言う configure block みたいなやつを用意してほしいなぁと思う。`Unopiniated` に反するのかもしれないけど。

ということで express の初期化を server.js 側でやって、routing を行う app.js に投げる形にした。

server.js

const express = require('express')
const morgan  = require('morgan')

let app = express()
app.use(morgan('combined'))

app = require('./app')(app)

app.listen(3000, () => {
  console.log('Starting server localhost:3000 ...')
})

app.js

module.exports = (app) => {
  app.get('/', (req, res) => {
    res.send('Hello Express')
  })

  return app
}

これを

nodemon server.js

で立ち上げると reload できるし、普通にログを吐く!

ちなみにNodemonについて

以下の記事を参考にした。

StrongLoop - Comparison: Tools to Automate Restarting Node.js Server After Code Changes

ちょっと古いけど、たぶんそう困らないんじゃないかな。

つづき

超今さらExpress触ってみた - その2 Routerと実際のRequest Handlerを分けたい - - あーありがち(2018-09-11)

  1. 2018-07-24 段階で Node.js 8 と Python 3.7 が beta サポートされた 

  2. logger で手動で吐くやつじゃなくて 

About

例によって個人のなんちゃらです