Nuxt.js(2.14.3)+express4へのバージョンアップでハマったところ


背景

Subroqというサービスを開発しており、その管理画面開発に、Nuxt.js(2.14.3)とexpress4を利用しています。

最初にNuxt.jsの2.0.0で開発したのですが、そこから2.14.3へのバージョンアップで色々ハマったので、それについて記載いたします。

ハマったポイント

yarn upgradeしたら動かなくなった

何も考えず、yarn upgradeしてみたら、動かなくなりました。
※普通やらない方がいいです。

色々試行錯誤したのですが、結局解決できなかったため、npx create-nuxt-app console-subroqで雛形をつく直しました。

npx create-nuxt-appは、言語やフレームワークを選択していって、雛形を作ってくれるコマンドなのですが、その選択支の中に、server side frameworkがないことに気づきました。

昔のバージョンには、存在したのですが、なくなっておりどうすればいいのか路頭に迷いました。
代わりに、Deployment targetという項目が増えてました。

そして、作成された雛形にserverディレクトリが存在せず、困りました。

express-templateの利用

ググったところ、express-templateというものが、あるみたいなので、そのリポジトリを確認してみました。

templateディレクトリ内にサンプルがあるので、cloneして起動して、動くことを確認しました。

ただ、Nuxt2.0.0のserver/index.jsとかなり変わっており、困惑しました。

例えば、以下が2.0.0の時のserver/index.jsです。

・・・
async function start () {
  // Init Nuxt.js
  const nuxt = new Nuxt(config)

  const { host, port } = nuxt.options.server

  await nuxt.ready()
  // Build only in dev mode
  if (config.dev) {
    const builder = new Builder(nuxt)
    await builder.build()
  }

  app.get('/api/users', users)
  app.get('/api/test', test)
  app.listen(port, host)
}

start()

そして、次が、express-templateのindex.jsです。

・・・
// Require API routes
const users = require('./routes/users')
const test = require('./routes/test')

// Import API Routes
app.use(users)
app.use(test)

// Export express app
module.exports = app

// Start standalone server if directly running
if (require.main === module) {
  const port = process.env.PORT || 3001
  app.listen(port, () => {
    console.log(`API server listening on port ${port}`)
  })
}

そもそも、Nuxtモジュールをrequireしていないので、後続の処理がかなり変わってます。

バージョン2.13.0でnuxt.config.jstargetという設定が追加されました。
たぶんこの設定をserverにすることで、このへんの記述をうまくやってくれるため、不要になったのではないかと推測しております。

configuration-target

また、module.exports = appが追加されています。

これもハマったポイントなのですが、module.exportsしないと、ServerMiddleware should expose a handleというエラーがでます。

2.12.0あたりで追加されたぽいです。

既存のアプリケーションのコードを上記に合わせ書き換えました。

vue部分のソースコードは、waringがでた部分が少しだけありましたが、ほとんどそのまま移行し、問題なく動くようになりました。

AmazonLinux2上で起動がうまくいかない

AmazonLinux2上で、yarn devで動かしてみたのですが、以下エラーが発生し、うまく動きませんでした。

なぜか、Address localhost:3000 is already in use.のwaringが発生します。

起動前に、lsof -i:3000で確認しても、何も起動していません。

起動時に3000番port使われているので、別のportを使うメッセージが表示されます。

起動後に、lsofで確認したところ、なぜかプロセスが2つありました。

lsof -i:3000

COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    23234 ec2-user   21u  IPv6 201625      0t0  TCP *:hbci (LISTEN)
lsof -i:36455

COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    23234 ec2-user   22u  IPv4 201629      0t0  TCP localhost:36455 (LISTEN)

開発環境のmacでは、発生していなかったため、かなり悩みました。

結果的に、express-templateと同じようにlisten処理の部分を書き換えました。

app.listen(port)

・・・
if (require.main === module) {
  const port = process.env.PORT || 3001
  app.listen(port, () => {
    console.log(`API server listening on port ${port}`)
  })
}

require.main === moduleとはどういう意味か調べてみたところ、
node index.jsで起動された場合に、require.main === moduletrueになるらしいです。

nuxtコマンドで起動した場合にどうなるか確認したところ、ここの処理は、falseで通りませんでした。

ということは、app.listenが必要じゃない?ということなんですかね。

Nuxt.jsのソースコードを見てみましたが、確かにserverlistenしている記述があるので、内部でlistenしていて、必要ないのかもしれないです。

この認識であっているか怪しいですが。

productionリリース

nuxt buildnuxt startを行い、無事動かすことができました。

deamon化には、foreverを使っており、こんな感じでコマンドを設定しています。

  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "forever start -c 'nuxt start' ./",
    "generate": "nuxt generate"
  },

最後に

Nuxt.jsは、バージョンアップが頻繁に行われており、設定とか使い方が、今後も変わる可能性があるので、注意してみていこうかなと思いました。

Subroqは、企業のフリーランスエンジニアの採用や活用を支援するサービスを提供しております。また、フリーランスエンジニア向けの記事も書いておりますので、興味ある方は是非、ご一読いただければと思います。