Skip to content

Commit 4382bcb

Browse files
fix: speed up initial client bundling
1 parent 85c56ba commit 4382bcb

File tree

3 files changed

+100
-103
lines changed

3 files changed

+100
-103
lines changed

client-src/index.js

Lines changed: 99 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/* global __resourceQuery, __webpack_hash__ */
22
/// <reference types="webpack/module" />
33
import webpackHotLog from "webpack/hot/log.js";
4-
import parseURL from "./utils/parseURL.js";
54
import socket from "./socket.js";
65
import { formatProblem, createOverlay } from "./overlay.js";
7-
import { log, logEnabledFeatures, setLogLevel } from "./utils/log.js";
6+
import { log, setLogLevel } from "./utils/log.js";
87
import sendMessage from "./utils/sendMessage.js";
98
import reloadApp from "./utils/reloadApp.js";
109
import { isProgressSupported, defineProgressElement } from "./progress.js";
@@ -46,13 +45,11 @@ const decodeOverlayOptions = (overlayOptions) => {
4645
);
4746

4847
// eslint-disable-next-line no-new-func
49-
const overlayFilterFunction = new Function(
48+
overlayOptions[property] = new Function(
5049
"message",
5150
`var callback = ${overlayFilterFunctionString}
5251
return callback(message)`,
5352
);
54-
55-
overlayOptions[property] = overlayFilterFunction;
5653
}
5754
});
5855
}
@@ -67,13 +64,75 @@ const status = {
6764
currentHash: __webpack_hash__,
6865
};
6966

70-
/** @type {Options} */
71-
const options = {
72-
hot: false,
73-
liveReload: false,
74-
progress: false,
75-
overlay: false,
67+
/**
68+
* @returns {string}
69+
*/
70+
const getCurrentScriptSource = () => {
71+
// `document.currentScript` is the most accurate way to find the current script,
72+
// but is not supported in all browsers.
73+
if (document.currentScript) {
74+
return document.currentScript.getAttribute("src");
75+
}
76+
77+
// Fallback to getting all scripts running in the document.
78+
const scriptElements = document.scripts || [];
79+
const scriptElementsWithSrc = Array.prototype.filter.call(
80+
scriptElements,
81+
(element) => element.getAttribute("src"),
82+
);
83+
84+
if (scriptElementsWithSrc.length > 0) {
85+
const currentScript =
86+
scriptElementsWithSrc[scriptElementsWithSrc.length - 1];
87+
88+
return currentScript.getAttribute("src");
89+
}
90+
91+
// Fail as there was no script to use.
92+
throw new Error("[webpack-dev-server] Failed to get current script source.");
93+
};
94+
95+
/**
96+
* @param {string} resourceQuery
97+
* @returns {{ [key: string]: string | boolean }}
98+
*/
99+
const parseURL = (resourceQuery) => {
100+
/** @type {{ [key: string]: string }} */
101+
let result = {};
102+
103+
if (typeof resourceQuery === "string" && resourceQuery !== "") {
104+
const searchParams = resourceQuery.slice(1).split("&");
105+
106+
for (let i = 0; i < searchParams.length; i++) {
107+
const pair = searchParams[i].split("=");
108+
109+
result[pair[0]] = decodeURIComponent(pair[1]);
110+
}
111+
} else {
112+
// Else, get the url from the <script> this file was called with.
113+
const scriptSource = getCurrentScriptSource();
114+
115+
let scriptSourceURL;
116+
117+
try {
118+
// The placeholder `baseURL` with `window.location.href`,
119+
// is to allow parsing of path-relative or protocol-relative URLs,
120+
// and will have no effect if `scriptSource` is a fully valid URL.
121+
scriptSourceURL = new URL(scriptSource, self.location.href);
122+
} catch (error) {
123+
// URL parsing failed, do nothing.
124+
// We will still proceed to see if we can recover using `resourceQuery`
125+
}
126+
127+
if (scriptSourceURL) {
128+
result = scriptSourceURL;
129+
result.fromCurrentScript = true;
130+
}
131+
}
132+
133+
return result;
76134
};
135+
77136
const parsedResourceQuery = parseURL(__resourceQuery);
78137

79138
const enabledFeatures = {
@@ -83,6 +142,14 @@ const enabledFeatures = {
83142
Overlay: false,
84143
};
85144

145+
/** @type {Options} */
146+
const options = {
147+
hot: false,
148+
liveReload: false,
149+
progress: false,
150+
overlay: false,
151+
};
152+
86153
if (parsedResourceQuery.hot === "true") {
87154
options.hot = true;
88155
enabledFeatures["Hot Module Replacement"] = true;
@@ -130,18 +197,37 @@ if (typeof parsedResourceQuery.reconnect !== "undefined") {
130197
/**
131198
* @param {string} level
132199
*/
133-
function setAllLogLevel(level) {
200+
const setAllLogLevel = (level) => {
134201
// This is needed because the HMR logger operate separately from dev server logger
135202
webpackHotLog.setLogLevel(
136203
level === "verbose" || level === "log" ? "info" : level,
137204
);
138205
setLogLevel(level);
139-
}
206+
};
140207

141208
if (options.logging) {
142209
setAllLogLevel(options.logging);
143210
}
144211

212+
const logEnabledFeatures = (features) => {
213+
const listEnabledFeatures = Object.keys(features);
214+
if (!features || listEnabledFeatures.length === 0) {
215+
return;
216+
}
217+
218+
let logString = "Server started:";
219+
220+
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
221+
for (let i = 0; i < listEnabledFeatures.length; i++) {
222+
const key = listEnabledFeatures[i];
223+
logString += ` ${key} ${features[key] ? "enabled" : "disabled"},`;
224+
}
225+
// replace last comma with a period
226+
logString = logString.slice(0, -1).concat(".");
227+
228+
log.info(logString);
229+
};
230+
145231
logEnabledFeatures(enabledFeatures);
146232

147233
self.addEventListener("beforeunload", () => {

client-src/utils/log.js

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,4 @@ setLogLevel(defaultLevel);
1818

1919
const log = logger.getLogger(name);
2020

21-
const logEnabledFeatures = (features) => {
22-
const enabledFeatures = Object.keys(features);
23-
if (!features || enabledFeatures.length === 0) {
24-
return;
25-
}
26-
27-
let logString = "Server started:";
28-
29-
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
30-
for (let i = 0; i < enabledFeatures.length; i++) {
31-
const key = enabledFeatures[i];
32-
logString += ` ${key} ${features[key] ? "enabled" : "disabled"},`;
33-
}
34-
// replace last comma with a period
35-
logString = logString.slice(0, -1).concat(".");
36-
37-
log.info(logString);
38-
};
39-
40-
export { log, logEnabledFeatures, setLogLevel };
21+
export { log, setLogLevel };

client-src/utils/parseURL.js

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)