-
Notifications
You must be signed in to change notification settings - Fork 770
/
app-update.ts
170 lines (147 loc) · 4.84 KB
/
app-update.ts
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import type * as d from '../../declarations';
import {
appError,
clearAppErrorModal,
hmrWindow,
logBuild,
logDiagnostic,
logReload,
logWarn,
emitBuildStatus,
onBuildResults,
} from '../client';
import { OPEN_IN_EDITOR_URL } from '../dev-server-constants';
export const initAppUpdate = (win: d.DevClientWindow, config: d.DevClientConfig) => {
onBuildResults(win, (buildResults) => {
appUpdate(win, config, buildResults);
});
};
const appUpdate = (win: d.DevClientWindow, config: d.DevClientConfig, buildResults: d.CompilerBuildResults) => {
try {
if (buildResults.buildId === win['s-build-id']) {
return;
}
win['s-build-id'] = buildResults.buildId;
// remove any app errors that may already be showing
clearAppErrorModal({ window: win });
if (buildResults.hasError) {
// looks like we've got an error
// let's show the error all pretty like
const editorId = Array.isArray(config.editors) && config.editors.length > 0 ? config.editors[0].id : null;
const errorResults = appError({
window: win,
buildResults: buildResults,
openInEditor: editorId
? (data) => {
const qs: d.OpenInEditorData = {
file: data.file,
line: data.line,
column: data.column,
editor: editorId,
};
const url = `${OPEN_IN_EDITOR_URL}?${Object.keys(qs)
.map((k) => `${k}=${(qs as any)[k]}`)
.join('&')}`;
win.fetch(url);
}
: null,
});
errorResults.diagnostics.forEach(logDiagnostic);
emitBuildStatus(win, errorResults.status);
return;
}
if (win['s-initial-load']) {
// this page is the initial dev server loading page
// and the build has finished without errors
// let's make sure the url is at the root
// and we've unregistered any existing service workers
// then let's refresh the page from the root of the server
appReset(win, config, () => {
logReload(`Initial load`);
win.location.reload();
});
return;
}
if (buildResults.hmr) {
appHmr(win, buildResults.hmr);
}
} catch (e) {
console.error(e);
}
};
const appHmr = (win: Window, hmr: d.HotModuleReplacement) => {
let shouldWindowReload = false;
if (hmr.reloadStrategy === 'pageReload') {
shouldWindowReload = true;
}
if (hmr.indexHtmlUpdated) {
logReload(`Updated index.html`);
shouldWindowReload = true;
}
if (hmr.serviceWorkerUpdated) {
logReload(`Updated Service Worker: sw.js`);
shouldWindowReload = true;
}
if (hmr.scriptsAdded && hmr.scriptsAdded.length > 0) {
logReload(`Added scripts: ${hmr.scriptsAdded.join(', ')}`);
shouldWindowReload = true;
}
if (hmr.scriptsDeleted && hmr.scriptsDeleted.length > 0) {
logReload(`Deleted scripts: ${hmr.scriptsDeleted.join(', ')}`);
shouldWindowReload = true;
}
if (hmr.excludeHmr && hmr.excludeHmr.length > 0) {
logReload(`Excluded From Hmr: ${hmr.excludeHmr.join(', ')}`);
shouldWindowReload = true;
}
if (shouldWindowReload) {
win.location.reload();
return;
}
const results = hmrWindow({ window: win, hmr: hmr });
if (results.updatedComponents.length > 0) {
logBuild(
`Updated component${results.updatedComponents.length > 1 ? 's' : ''}: ${results.updatedComponents.join(', ')}`
);
}
if (results.updatedInlineStyles.length > 0) {
logBuild(`Updated styles: ${results.updatedInlineStyles.join(', ')}`);
}
if (results.updatedExternalStyles.length > 0) {
logBuild(`Updated stylesheets: ${results.updatedExternalStyles.join(', ')}`);
}
if (results.updatedImages.length > 0) {
logBuild(`Updated images: ${results.updatedImages.join(', ')}`);
}
};
export const appReset = (win: d.DevClientWindow, config: d.DevClientConfig, cb: () => void) => {
// we're probably at some ugly url
// let's update the url to be the expect root url: /
// avoiding Promise to keep things simple for our ie11 buddy
win.history.replaceState({}, 'App', config.basePath);
if (!win.navigator.serviceWorker || !win.navigator.serviceWorker.getRegistration) {
cb();
} else {
// it's possible a service worker is already registered
// for this localhost url from some other app's development
// let's ensure we entirely remove the service worker for this domain
win.navigator.serviceWorker
.getRegistration()
.then((swRegistration) => {
if (swRegistration) {
swRegistration.unregister().then((hasUnregistered) => {
if (hasUnregistered) {
logBuild(`unregistered service worker`);
}
cb();
});
} else {
cb();
}
})
.catch((err) => {
logWarn('Service Worker', err);
cb();
});
}
};