1 |
|
2 |
|
3 |
|
4 | 'use strict';
|
5 |
|
6 | const child_process = require('child_process');
|
7 | const path = require('path');
|
8 |
|
9 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
10 |
|
11 | function _interopNamespace(e) {
|
12 | if (e && e.__esModule) return e;
|
13 | var n = Object.create(null);
|
14 | if (e) {
|
15 | Object.keys(e).forEach(function (k) {
|
16 | if (k !== 'default') {
|
17 | var d = Object.getOwnPropertyDescriptor(e, k);
|
18 | Object.defineProperty(n, k, d.get ? d : {
|
19 | enumerable: true,
|
20 | get: function () {
|
21 | return e[k];
|
22 | }
|
23 | });
|
24 | }
|
25 | });
|
26 | }
|
27 | n['default'] = e;
|
28 | return Object.freeze(n);
|
29 | }
|
30 |
|
31 | const path__default = _interopDefaultLegacy(path);
|
32 |
|
33 | function initServerProcessWorkerProxy(sendToMain) {
|
34 | const workerPath = require.resolve(path__default['default'].join(__dirname, 'server-worker-thread.js'));
|
35 | const filteredExecArgs = process.execArgv.filter((v) => !/^--(debug|inspect)/.test(v));
|
36 | const forkOpts = {
|
37 | execArgv: filteredExecArgs,
|
38 | env: process.env,
|
39 | cwd: process.cwd(),
|
40 | stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
|
41 | };
|
42 |
|
43 |
|
44 | let serverProcess = child_process.fork(workerPath, [], forkOpts);
|
45 | const receiveFromMain = (msg) => {
|
46 |
|
47 | if (serverProcess) {
|
48 | serverProcess.send(msg);
|
49 | }
|
50 | else if (msg.closeServer) {
|
51 | sendToMain({ serverClosed: true });
|
52 | }
|
53 | };
|
54 |
|
55 | serverProcess.on('message', (msg) => {
|
56 | if (msg.serverClosed && serverProcess) {
|
57 | serverProcess.kill('SIGINT');
|
58 | serverProcess = null;
|
59 | }
|
60 | sendToMain(msg);
|
61 | });
|
62 | serverProcess.stdout.on('data', (data) => {
|
63 |
|
64 | console.log(`dev server: ${data}`);
|
65 | });
|
66 | serverProcess.stderr.on('data', (data) => {
|
67 |
|
68 | sendToMain({ error: { message: 'stderr: ' + data } });
|
69 | });
|
70 | return receiveFromMain;
|
71 | }
|
72 |
|
73 | function start(stencilDevServerConfig, logger, watcher) {
|
74 | return new Promise(async (resolve, reject) => {
|
75 | try {
|
76 | const devServerConfig = {
|
77 | devServerDir: __dirname,
|
78 | ...stencilDevServerConfig,
|
79 | };
|
80 | if (!path__default['default'].isAbsolute(devServerConfig.root)) {
|
81 | devServerConfig.root = path__default['default'].join(process.cwd(), devServerConfig.root);
|
82 | }
|
83 | let initServerProcess;
|
84 | if (stencilDevServerConfig.worker === true || stencilDevServerConfig.worker === undefined) {
|
85 |
|
86 | initServerProcess = initServerProcessWorkerProxy;
|
87 | }
|
88 | else {
|
89 |
|
90 | const devServerProcess = await Promise.resolve().then(function () { return _interopNamespace(require('./server-process.js')); });
|
91 | initServerProcess = devServerProcess.initServerProcess;
|
92 | }
|
93 | startServer(devServerConfig, logger, watcher, initServerProcess, resolve, reject);
|
94 | }
|
95 | catch (e) {
|
96 | reject(e);
|
97 | }
|
98 | });
|
99 | }
|
100 | function startServer(devServerConfig, logger, watcher, initServerProcess, resolve, reject) {
|
101 | var _a;
|
102 | const timespan = logger.createTimeSpan(`starting dev server`, true);
|
103 | const startupTimeout = logger.getLevel() !== 'debug' || devServerConfig.startupTimeout !== 0
|
104 | ? setTimeout(() => {
|
105 | reject(`dev server startup timeout`);
|
106 | }, (_a = devServerConfig.startupTimeout) !== null && _a !== void 0 ? _a : 15000)
|
107 | : null;
|
108 | let isActivelyBuilding = false;
|
109 | let lastBuildResults = null;
|
110 | let devServer = null;
|
111 | let removeWatcher = null;
|
112 | let closeResolve = null;
|
113 | let hasStarted = false;
|
114 | let browserUrl = '';
|
115 | let sendToWorker = null;
|
116 | const closePromise = new Promise((resolve) => (closeResolve = resolve));
|
117 | const close = async () => {
|
118 | clearTimeout(startupTimeout);
|
119 | isActivelyBuilding = false;
|
120 | if (removeWatcher) {
|
121 | removeWatcher();
|
122 | }
|
123 | if (devServer) {
|
124 | devServer = null;
|
125 | }
|
126 | if (sendToWorker) {
|
127 | sendToWorker({
|
128 | closeServer: true,
|
129 | });
|
130 | sendToWorker = null;
|
131 | }
|
132 | return closePromise;
|
133 | };
|
134 | const emit = async (eventName, data) => {
|
135 | if (sendToWorker) {
|
136 | if (eventName === 'buildFinish') {
|
137 | isActivelyBuilding = false;
|
138 | lastBuildResults = { ...data };
|
139 | sendToWorker({ buildResults: { ...lastBuildResults }, isActivelyBuilding });
|
140 | }
|
141 | else if (eventName === 'buildLog') {
|
142 | sendToWorker({
|
143 | buildLog: { ...data },
|
144 | });
|
145 | }
|
146 | else if (eventName === 'buildStart') {
|
147 | isActivelyBuilding = true;
|
148 | }
|
149 | }
|
150 | };
|
151 | const serverStarted = (msg) => {
|
152 | hasStarted = true;
|
153 | clearTimeout(startupTimeout);
|
154 | devServerConfig = msg.serverStarted;
|
155 | devServer = {
|
156 | address: devServerConfig.address,
|
157 | basePath: devServerConfig.basePath,
|
158 | browserUrl: devServerConfig.browserUrl,
|
159 | protocol: devServerConfig.protocol,
|
160 | port: devServerConfig.port,
|
161 | root: devServerConfig.root,
|
162 | emit,
|
163 | close,
|
164 | };
|
165 | browserUrl = devServerConfig.browserUrl;
|
166 | timespan.finish(`dev server started: ${browserUrl}`);
|
167 | resolve(devServer);
|
168 | };
|
169 | const requestLog = (msg) => {
|
170 | if (devServerConfig.logRequests) {
|
171 | if (msg.requestLog.status >= 500) {
|
172 | logger.info(logger.red(`${msg.requestLog.method} ${msg.requestLog.url} (${msg.requestLog.status})`));
|
173 | }
|
174 | else if (msg.requestLog.status >= 400) {
|
175 | logger.info(logger.dim(logger.red(`${msg.requestLog.method} ${msg.requestLog.url} (${msg.requestLog.status})`)));
|
176 | }
|
177 | else if (msg.requestLog.status >= 300) {
|
178 | logger.info(logger.dim(logger.magenta(`${msg.requestLog.method} ${msg.requestLog.url} (${msg.requestLog.status})`)));
|
179 | }
|
180 | else {
|
181 | logger.info(logger.dim(`${logger.cyan(msg.requestLog.method)} ${msg.requestLog.url}`));
|
182 | }
|
183 | }
|
184 | };
|
185 | const serverError = async (msg) => {
|
186 | if (hasStarted) {
|
187 | logger.error(msg.error.message + ' ' + msg.error.stack);
|
188 | }
|
189 | else {
|
190 | await close();
|
191 | reject(msg.error.message);
|
192 | }
|
193 | };
|
194 | const requestBuildResults = () => {
|
195 |
|
196 | if (sendToWorker) {
|
197 | if (lastBuildResults != null) {
|
198 |
|
199 | const msg = {
|
200 | buildResults: { ...lastBuildResults },
|
201 | isActivelyBuilding: isActivelyBuilding,
|
202 | };
|
203 |
|
204 | delete msg.buildResults.hmr;
|
205 | sendToWorker(msg);
|
206 | }
|
207 | else {
|
208 | sendToWorker({
|
209 | isActivelyBuilding: true,
|
210 | });
|
211 | }
|
212 | }
|
213 | };
|
214 | const compilerRequest = async (compilerRequestPath) => {
|
215 | if (watcher && watcher.request && sendToWorker) {
|
216 | const compilerRequestResults = await watcher.request({ path: compilerRequestPath });
|
217 | sendToWorker({ compilerRequestResults });
|
218 | }
|
219 | };
|
220 | const receiveFromWorker = (msg) => {
|
221 | try {
|
222 | if (msg.serverStarted) {
|
223 | serverStarted(msg);
|
224 | }
|
225 | else if (msg.serverClosed) {
|
226 | logger.debug(`dev server closed: ${browserUrl}`);
|
227 | closeResolve();
|
228 | }
|
229 | else if (msg.requestBuildResults) {
|
230 | requestBuildResults();
|
231 | }
|
232 | else if (msg.compilerRequestPath) {
|
233 | compilerRequest(msg.compilerRequestPath);
|
234 | }
|
235 | else if (msg.requestLog) {
|
236 | requestLog(msg);
|
237 | }
|
238 | else if (msg.error) {
|
239 | serverError(msg);
|
240 | }
|
241 | else {
|
242 | logger.debug(`server msg not handled: ${JSON.stringify(msg)}`);
|
243 | }
|
244 | }
|
245 | catch (e) {
|
246 | logger.error('receiveFromWorker: ' + e);
|
247 | }
|
248 | };
|
249 | try {
|
250 | if (watcher) {
|
251 | removeWatcher = watcher.on(emit);
|
252 | }
|
253 | sendToWorker = initServerProcess(receiveFromWorker);
|
254 | sendToWorker({
|
255 | startServer: devServerConfig,
|
256 | });
|
257 | }
|
258 | catch (e) {
|
259 | close();
|
260 | reject(e);
|
261 | }
|
262 | }
|
263 |
|
264 | exports.start = start;
|