This repository has been archived by the owner on Apr 8, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathserver.js
145 lines (124 loc) · 4.03 KB
/
server.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const http = require('http');
const https = require('https');
const chalk = require('chalk');
const clip = require('clipboardy');
const getPort = require('get-port');
const killable = require('killable');
const Koa = require('koa');
const koaWebpack = require('koa-webpack');
const serveStatic = require('@shellscape/koa-static/legacy');
const urljoin = require('url-join');
const weblog = require('webpack-log');
const WebpackServeError = require('./WebpackServeError');
module.exports = (options) => {
const app = new Koa();
const { bus } = options;
const log = weblog({ name: 'serve', id: 'webpack-serve' });
let http2;
let server;
let koaMiddleware;
const middleware = {
webpack: () => {
middleware.webpack.called = true;
// track the promise state in the event that someone calls server.close()
// quickly, before this promise resolves.
try {
koaMiddleware = koaWebpack({
// be explicit about what we want to pass, rather than passing the entire
// options object
compiler: options.compiler,
dev: options.dev,
hot: options.hot,
});
app.use(koaMiddleware);
middleware.webpack.state = Promise.resolve();
} catch (e) {
/* istanbul ignore next*/
middleware.webpack.state = Promise.reject(e);
/* istanbul ignore next*/
throw new WebpackServeError(
`An error was thrown while initializing koa-webpack\n ${e.toString()}`
);
}
},
content: (staticOptions) => {
middleware.content.called = true;
for (const dir of options.content) {
app.use(serveStatic(dir, staticOptions || {}));
}
},
};
if (options.http2) {
// the check for if we can do this is in options.js
http2 = require('http2'); // eslint-disable-line
}
if (options.https) {
if (http2) {
server = http2.createSecureServer(options.https, app.callback());
} else {
server = https.createServer(options.https, app.callback());
}
} else {
server = (http2 || http).createServer(app.callback());
}
killable(server);
server.on('error', (err) => log.error(err));
return {
server,
close(callback) {
server.kill(() => {
if (middleware.webpack.called) {
middleware.webpack.state.then(() => koaMiddleware.close(callback));
}
});
},
start() {
server.once('listening', () => {
const uri = `${options.protocol}://${options.host}:${options.port}`;
log.info(chalk`Project is running at {blue ${uri}}`);
if (options.clipboard && !options.open) {
/* istanbul ignore next*/
try {
clip.writeSync(uri);
log.info(chalk.grey('Server URI copied to clipboard'));
} catch (error) {
log.warn(
chalk.grey(
'Failed to copy server URI to clipboard. ' +
"Use logLevel: 'debug' for more information."
)
);
log.debug(error);
}
}
bus.emit('listening', server);
if (options.open) {
const open = require('opn'); // eslint-disable-line global-require
open(urljoin(uri, options.open.path || ''), options.open.app || {});
}
});
return Promise.all([
getPort({ port: options.port, host: options.host }),
getPort({ port: options.hot.port || 8081, host: options.host }),
]).then(([port, hotPort]) => {
/* eslint-disable no-param-reassign */
options.port = port;
if (options.hot) {
options.hot.port = hotPort;
}
if (typeof options.add === 'function') {
options.add(app, middleware, options);
}
if (!middleware.content.called) {
middleware.content();
}
// allow consumers to specifically order middleware
if (!middleware.webpack.called) {
middleware.webpack();
}
server.listen(options.port, options.host);
return server;
});
},
};
};