- Created at 2018/09/22 03:45
引き続きgenを実際に読む。
server.ts
serverの主な役割はこうだ
- File System Watchの立ち上げ(ファイルの変更監視)
- WebSocket Serverの立ち上げ
- HTTPサーバーの立ち上げ
- HTTPサーバーが返すresponseの作成
const start = async (dirname: string, opts: Options) => {
// 利用可能なポートを探す
const socketPort: number = await portfinder.getPortPromise()
// 定義だけ
let socket: WebSocket
// 初回に表示するページの取得
let gPages = await getPages(dirname, opts)
// ファイルの変更監視
const watcher: chokidar.FSWatcher = chokidar.watch(dirname, {
depth: 1,
ignoreInitial: true,
ignored: '!*.(jsx|md|json)',
})
// WebSocketサーバーの立ち上げ
const socketServer = new WebSocket.Server({ port: socketPort })
// 接続時にsocket渡す
socketServer.on('connection', (res: WebSocket) => {
// 最後に接続したものだけ更新の対象とする
socket = res
})
// 更新時に得られたsocketに対してpayloadを投げる
const update = async () => {
if (!socket) {
return
}
gPages = await getPages(dirname, opts)
socket.send(JSON.stringify({ reload: true }))
}
// 省略
}
export { start as server }
続きは、HTTPサーバー部分
const start = async (dirname: string, opts: Options) => {
// 中略
const app = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => {
if (!req.url) {
return
}
const { pathname } = url.parse(req.url)
if (!pathname) {
return
}
// URIとディレクトリ名を結合することで、ファイル名を生成する
const filepath = path.join(dirname, pathname)
// ローカルディレクトリに存在しているかどうか確認
if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) {
fs.createReadStream(filepath).pipe(res)
return
}
// `/`終わりの場合はindexでに変換する
const name = pathname === '/' ? 'index' : pathname.replace(/^\//, '').replace(/\/$/, '')
const page = gPages.find((localPage: any) => localPage.name === name)
if (!page) {
res.write('page not found: ' + pathname)
res.end()
return
}
// レンダリングするページをレスポンスに含める
res.write(page.html)
// hot reloadをかける用のscriptを最後尾に追加する
res.write(makeScript(socketPort))
res.end()
})
try {
const server = await app.listen(socketPort + 2)
return server
} catch (err) {
console.log(err)
throw err
}
}