-
Notifications
You must be signed in to change notification settings - Fork 102
/
index.js
101 lines (82 loc) · 2.43 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
var requireWithGlobal = require('require-with-global')
var debug = require('debug')('bankai.server-render')
var Console = require('console').Console
var through = require('through2')
var assert = require('assert')
var choo = require('./choo')
module.exports = class ServerRender {
constructor (entry) {
assert.strictEqual(typeof entry, 'string', 'bankai/ssr/index.js: entry should be type string')
this.entry = entry
this.error = null
this.console = through()
this.consoleInstance = new Console(this.console)
this.require = requireWithGlobal()
this.reload()
this.DEFAULT_RESPONSE = {
body: '<body></body>',
title: '',
language: 'en-US',
selector: 'body'
}
}
reload () {
this.app = this._requireApp(this.entry)
this.appType = this._getAppType(this.app)
this.routes = this._listRoutes(this.app)
}
render (route, done) {
var self = this
if (this.appType === 'choo') choo.render(this.app, route, send)
else done(null, Object.assign({ route: route }, this.DEFAULT_RESPONSE))
function send (err, res) {
if (err) return done(err)
done(null, Object.assign({ route: route }, self.DEFAULT_RESPONSE, res))
}
}
close () {
this.require.remove()
}
_getAppType (app) {
if (choo.is(app)) return 'choo'
else return 'default'
}
_requireApp (entry) {
try {
return this._freshRequire(entry, { console: this.consoleInstance })
} catch (err) {
var failedRequire = err.message === `Cannot find module '${entry}'`
if (!failedRequire) {
var ssrError = err
ssrError.isSsr = true
this.error = ssrError
}
}
}
// Clear the cache, and require the file again.
_freshRequire (file, vars) {
clearRequireAndChildren(file)
return this.require(file, vars)
}
_listRoutes (app) {
if (this.appType === 'choo') return choo.listRoutes(this.app)
return ['/']
}
}
function clearRequireAndChildren (key) {
if (!require.cache[key]) return
require.cache[key].children
.filter(isNotNativeModulePath)
.filter(isNotInNodeModules)
.forEach(function (child) {
clearRequireAndChildren(child.id)
})
debug('clearing require cache for %s', key)
delete require.cache[key]
function isNotNativeModulePath (module) {
return /\.node$/.test(module.id) === false
}
function isNotInNodeModules (module) {
return /node_modules/.test(module.id) === false
}
}