Express 4は、Express 3からの破壊的変更です。つまり、依存関係にExpressのバージョンを更新すると、既存のExpress 3アプリは動作しません。
この記事では、以下について説明します。
Express 4にはいくつかの重要な変更点があります。
参照
Express 4はConnectに依存しなくなり、express.static
関数以外、すべての組み込みミドルウェアをコアから削除しました。つまり、Expressは独立したルーティングおよびミドルウェアのWebフレームワークになり、Expressのバージョン管理とリリースはミドルウェアのアップデートの影響を受けなくなりました。
組み込みミドルウェアがないため、アプリの実行に必要なすべてのミドルウェアを明示的に追加する必要があります。以下の手順に従ってください。
npm install --save <module-name>
require('module-name')
app.use( ... )
次の表に、Express 3ミドルウェアとそのExpress 4での対応物を示します。
Express 3 | Express 4 |
---|---|
express.bodyParser |
body-parser + multer |
express.compress |
compression |
express.cookieSession |
cookie-session |
express.cookieParser |
cookie-parser |
express.logger |
morgan |
express.session |
express-session |
express.favicon |
serve-favicon |
express.responseTime |
response-time |
express.errorHandler |
errorhandler |
express.methodOverride |
method-override |
express.timeout |
connect-timeout |
express.vhost |
vhost |
express.csrf |
csurf |
express.directory |
serve-index |
express.static |
serve-static |
Express 4ミドルウェアの完全なリストはこちらです。
ほとんどの場合、古いバージョン3のミドルウェアをExpress 4の対応物に置き換えるだけで済みます。詳細は、GitHubのモジュールドキュメントを参照してください。
app.use
はパラメータを受け入れますバージョン4では、変数パラメータを使用してミドルウェア関数がロードされるパスを定義し、ルートハンドラーからパラメータの値を読み取ることができます。例:
app.use('/book/:id', (req, res, next) => {
console.log('ID:', req.params.id)
next()
})
アプリは現在、ルーティングミドルウェアを暗黙的にロードするため、router
ミドルウェアに関してミドルウェアのロード順序を気にする必要がなくなりました。
ルートを定義する方法は変更されていませんが、ルーティングシステムには、ルートの整理に役立つ2つの新機能があります。
app.route()
。express.Router
。app.route()
メソッド新しいapp.route()
メソッドを使用すると、ルートパスに対してチェーン可能なルートハンドラーを作成できます。パスは1か所で指定されるため、モジュール化されたルートの作成、冗長性とタイプミスを減らすのに役立ちます。ルートの詳細については、Router()
ドキュメントを参照してください。
app.route()
関数を使用して定義された、チェーンされたルートハンドラーの例を次に示します。
app.route('/book')
.get((req, res) => {
res.send('Get a random book')
})
.post((req, res) => {
res.send('Add a book')
})
.put((req, res) => {
res.send('Update the book')
})
express.Router
クラスルートの整理に役立つもう1つの機能は、新しいクラスexpress.Router
です。これを使用して、モジュール化可能なマウント可能なルートハンドラーを作成できます。Router
インスタンスは完全なミドルウェアとルーティングシステムであるため、「ミニアプリ」と呼ばれることがよくあります。
次の例では、モジュールとしてルーターを作成し、ミドルウェアをロードし、いくつかのルートを定義し、メインアプリのパスにマウントします。
たとえば、アプリディレクトリにbirds.js
という名前のルーターファイルを作成し、次の内容を記述します。
var express = require('express')
var router = express.Router()
// middleware specific to this router
router.use((req, res, next) => {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
res.send('About birds')
})
module.exports = router
次に、アプリでルーターモジュールをロードします。
var birds = require('./birds')
// ...
app.use('/birds', birds)
これで、アプリは/birds
と/birds/about
パスへのリクエストを処理できるようになり、ルートに固有のtimeLog
ミドルウェアを呼び出します。
次の表に、Express 4におけるその他の小さな変更点(ただし重要な変更点)を示します。
オブジェクト | 説明 |
---|---|
Node.js | Express 4はNode.js 0.10.x以降を必要とし、Node.js 0.8.xのサポートを終了しました。 |
|
直接操作する必要がある場合(socket.io/SPDY/HTTPS)を除き、 |
|
|
|
Express 4では、 |
|
|
|
相対URLは解決されなくなりました。 |
|
配列でしたが、オブジェクトになりました。 |
|
関数でしたが、オブジェクトになりました。 |
|
|
|
|
|
削除されました。 |
|
削除されました。 |
|
機能は、基本的なCookie値の設定に限定されています。追加機能には |
Express 3アプリケーションをExpress 4に移行する例を次に示します。対象となるファイルはapp.js
とpackage.json
です。
app.js
次のapp.js
ファイルを持つExpress v.3アプリケーションを検討してください。
var express = require('express')
var routes = require('./routes')
var user = require('./routes/user')
var http = require('http')
var path = require('path')
var app = express()
// all environments
app.set('port', process.env.PORT || 3000)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(express.favicon())
app.use(express.logger('dev'))
app.use(express.methodOverride())
app.use(express.session({ secret: 'your secret here' }))
app.use(express.bodyParser())
app.use(app.router)
app.use(express.static(path.join(__dirname, 'public')))
// development only
if (app.get('env') === 'development') {
app.use(express.errorHandler())
}
app.get('/', routes.index)
app.get('/users', user.list)
http.createServer(app).listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
package.json
それに対応するバージョン3のpackage.json
ファイルは、次のようになります。
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.12.0",
"pug": "*"
}
}
移行プロセスを開始するには、Express 4アプリに必要なミドルウェアをインストールし、次のコマンドを使用してExpressとPugをそれぞれの最新バージョンに更新します。
$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
app.js
に以下の変更を加えます。
組み込みのExpressミドルウェア関数express.favicon
、express.logger
、express.methodOverride
、express.session
、express.bodyParser
、express.errorHandler
は、express
オブジェクトでは使用できなくなりました。代替物を手動でインストールし、アプリにロードする必要があります。
app.router
関数をロードする必要はありません。有効なExpress 4アプリオブジェクトではないため、app.use(app.router);
コードを削除します。
ミドルウェア関数を正しい順序でロードしてください。アプリルートのロード後にerrorHandler
をロードします。
package.json
上記のnpm
コマンドを実行すると、package.json
が次のように更新されます。
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "^1.5.2",
"errorhandler": "^1.1.1",
"express": "^4.8.0",
"express-session": "^1.7.2",
"pug": "^2.0.0",
"method-override": "^2.1.2",
"morgan": "^1.2.2",
"multer": "^0.1.3",
"serve-favicon": "^2.0.1"
}
}
app.js
次に、無効なコードを削除し、必要なミドルウェアをロードし、必要に応じてその他の変更を加えます。app.js
ファイルは次のようになります。
var http = require('http')
var express = require('express')
var routes = require('./routes')
var user = require('./routes/user')
var path = require('path')
var favicon = require('serve-favicon')
var logger = require('morgan')
var methodOverride = require('method-override')
var session = require('express-session')
var bodyParser = require('body-parser')
var multer = require('multer')
var errorHandler = require('errorhandler')
var app = express()
// all environments
app.set('port', process.env.PORT || 3000)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
app.use(logger('dev'))
app.use(methodOverride())
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'uwotm8'
}))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(multer())
app.use(express.static(path.join(__dirname, 'public')))
app.get('/', routes.index)
app.get('/users', user.list)
// error handling middleware should be loaded after the loading the routes
if (app.get('env') === 'development') {
app.use(errorHandler())
}
var server = http.createServer(app)
server.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
http
モジュール(socket.io/SPDY/HTTPS)を直接操作する必要がない限り、ロードする必要はなく、アプリは次のように簡単に起動できます。
app.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
移行プロセスが完了し、アプリはExpress 4アプリになりました。確認するには、次のコマンドを使用してアプリを起動します。
$ node .
https://127.0.0.1:3000にアクセスし、Express 4によってレンダリングされたホームページが表示されることを確認します。
Expressアプリを生成するコマンドラインツールは依然としてexpress
ですが、新しいバージョンにアップグレードするには、Express 3アプリジェネレーターをアンインストールしてから、新しいexpress-generator
をインストールする必要があります。
システムにExpress 3アプリジェネレーターが既にインストールされている場合は、アンインストールする必要があります。
$ npm uninstall -g express
ファイルとディレクトリの権限の構成方法によっては、このコマンドをsudo
で実行する必要がある場合があります。
新しいジェネレーターをインストールします。
$ npm install -g express-generator
ファイルとディレクトリの権限の構成方法によっては、このコマンドをsudo
で実行する必要がある場合があります。
これで、システム上のexpress
コマンドがExpress 4ジェネレーターに更新されました。
コマンドオプションと使い方はほぼ同じですが、次の例外があります。
--sessions
オプションを削除しました。--jshtml
オプションを削除しました。--hogan
オプションを追加しました。次のコマンドを実行して、Express 4アプリを作成します。
$ express app4
app4/app.js
ファイルの内容を見ると、アプリに必要なすべてのミドルウェア関数(express.static
を除く)が独立したモジュールとしてロードされており、router
ミドルウェアはアプリで明示的にロードされなくなっていることがわかります。
また、古いジェネレーターによって生成されたスタンドアロンアプリとは異なり、app.js
ファイルがNode.jsモジュールになっていることもわかります。
依存関係をインストールした後、次のコマンドを使用してアプリを起動します。
$ npm start
package.json
ファイルのnpm startスクリプトを見ると、アプリを起動する実際のコマンドはnode ./bin/www
であり、Express 3ではnode app.js
だったことがわかります。
Express 4ジェネレーターによって生成されたapp.js
ファイルはNode.jsモジュールになったため、(コードを変更しない限り)アプリとして独立して起動できなくなりました。モジュールはNode.jsファイルにロードする必要があり、Node.jsファイルから起動する必要があります。この場合、Node.jsファイルは./bin/www
です。
Expressアプリの作成やアプリの起動にbin
ディレクトリや拡張子なしのwww
ファイルは必須ではありません。ジェネレーターによる単なる提案なので、必要に応じて自由に修正してください。
www
ディレクトリを削除し、「Express 3の方法」を維持するには、app.js
ファイルの末尾にあるmodule.exports = app;
という行を削除し、次のコードを貼り付けます。
app.set('port', process.env.PORT || 3000)
var server = app.listen(app.get('port'), () => {
debug('Express server listening on port ' + server.address().port)
})
次のコードを使用して、app.js
ファイルの先頭でdebug
モジュールをロードしてください。
var debug = require('debug')('app4')
次に、package.json
ファイルの"start": "node ./bin/www"
を"start": "node app.js"
に変更します。
これで、./bin/www
の機能をapp.js
に戻しました。この変更はお勧めしませんが、この演習は、./bin/www
ファイルの動作と、app.js
ファイルが単独で起動しなくなった理由を理解するのに役立ちます。