Skip to content

Commit 914b03d

Browse files
committed
work
1 parent 3d32139 commit 914b03d

25 files changed

Lines changed: 6433 additions & 5649 deletions

File tree

dist/build/build.js

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ const jsenvCoreDirectoryUrl = new URL("../", import.meta.url);
149149
* Only exact declared versions ("1.2.3") are compared: a range ("^1.2.3"), a
150150
* file/workspace protocol or a tag cannot be checked without resolving what npm
151151
* would pick, which is way beyond what is needed here.
152+
*
153+
* A status carries a severity so that every consumer (server log, browser
154+
* overlay, reload on install) reads the same decision: a missing package or an
155+
* outdated runtime dependency is a "warning", the page is not running what the
156+
* project asks for. An outdated devDependency is only "info": the installed
157+
* version runs, what may differ is tooling, and that is worth a line in the
158+
* console, not a dialog nor a reload once installed.
152159
*/
153160

154161

@@ -180,31 +187,40 @@ const readDependencyStatus = (
180187
if (!packageJSON) {
181188
return null;
182189
}
183-
const declaredVersion = readDeclaredVersion(packageJSON, packageName);
184-
if (!declaredVersion) {
190+
const declaration = readDeclaration(packageJSON, packageName);
191+
if (!declaration) {
185192
return null;
186193
}
187194
return createStatus(packageDirectory, {
188195
packageName,
189-
declaredVersion,
196+
declaredVersion: declaration.version,
197+
declaredIn: declaration.field,
190198
declaringDirectoryUrl,
191199
declaredBy: packageJSON.name,
192200
});
193201
};
194202

195203
const createStatus = (
196204
packageDirectory,
197-
{ packageName, declaredVersion, declaringDirectoryUrl, declaredBy },
205+
{
206+
packageName,
207+
declaredVersion,
208+
declaredIn,
209+
declaringDirectoryUrl,
210+
declaredBy,
211+
},
198212
) => {
199213
const status = {
200214
packageName,
201215
declaredVersion,
216+
declaredIn,
202217
declaredBy,
203218
installedVersion: null,
204219
// the file telling this dependency apart; it is what an install rewrites and
205220
// what the dev server looks at to know the dependency became the declared one
206221
watchedPath: null,
207222
state: "missing",
223+
severity: "warning",
208224
};
209225
const installedDirectoryUrl = findInstalledDirectoryUrl(
210226
declaringDirectoryUrl,
@@ -226,11 +242,16 @@ const createStatus = (
226242
status.installedVersion = installedPackageJSON
227243
? installedPackageJSON.version
228244
: null;
229-
status.state =
230-
isExactVersion(declaredVersion) &&
231-
status.installedVersion !== declaredVersion
232-
? "outdated"
233-
: "installed";
245+
if (
246+
!isExactVersion(declaredVersion) ||
247+
status.installedVersion === declaredVersion
248+
) {
249+
status.state = "installed";
250+
status.severity = null;
251+
return status;
252+
}
253+
status.state = "outdated";
254+
status.severity = declaredIn === "devDependencies" ? "info" : "warning";
234255
return status;
235256
};
236257

@@ -258,11 +279,11 @@ const findInstalledDirectoryUrl = (declaringDirectoryUrl, packageName) => {
258279
return null;
259280
};
260281

261-
const readDeclaredVersion = (packageJSON, packageName) => {
282+
const readDeclaration = (packageJSON, packageName) => {
262283
for (const field of DEPENDENCY_FIELDS) {
263284
const dependencies = packageJSON[field];
264285
if (dependencies && dependencies[packageName]) {
265-
return dependencies[packageName];
286+
return { field, version: dependencies[packageName] };
266287
}
267288
}
268289
return null;

dist/js/dependency_status.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
* A missing dependency is not handled here: it makes the import fail, so the
55
* error overlay already says it, with more precision (which import, where).
66
*
7+
* The overlay is for the problems the server marks as "warning" (see severity
8+
* in package_dependencies.js). An outdated devDependency is "info": it goes to
9+
* the console as a line, said once, followed by an other line when it gets
10+
* installed; no overlay, and the server does not reload the page for it.
11+
*
712
* The overlay does not only describe the problem, it shows the dev server
813
* watching for the fix: the paths being looked at are named and kept alive on
914
* screen, so waiting for "npm install" feels like waiting for something that is
@@ -16,6 +21,9 @@ let watchInfoFromServer = {};
1621
// what leaves this map has been installed while the overlay was open, which is
1722
// worth showing as such
1823
const outdatedPathMap = new Map();
24+
// the console is append-only: a problem is said when it appears or changes,
25+
// and its resolution when it leaves the list
26+
const consoleLineMap = new Map();
1927

2028
const initDependencyStatus = ({ problems, watchInfo }) => {
2129
watchInfoFromServer = watchInfo || {};
@@ -32,7 +40,10 @@ const initDependencyStatus = ({ problems, watchInfo }) => {
3240
};
3341

3442
const render = (problems) => {
35-
const outdatedList = problems.filter(({ state }) => state === "outdated");
43+
logInfoProblems(problems.filter(({ severity }) => severity === "info"));
44+
const outdatedList = problems.filter(
45+
({ state, severity }) => state === "outdated" && severity === "warning",
46+
);
3647
removeOverlay();
3748
removeOverlay = () => {};
3849
const installedList = [];
@@ -67,6 +78,28 @@ const render = (problems) => {
6778
});
6879
};
6980

81+
const logInfoProblems = (infoList) => {
82+
for (const problem of infoList) {
83+
const { packageName, declaredIn, declaredVersion, installedVersion } =
84+
problem;
85+
const line = `[jsenv] "${packageName}" is installed in ${
86+
installedVersion || "an unknown version"
87+
} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
88+
if (consoleLineMap.get(packageName) === line) {
89+
continue;
90+
}
91+
consoleLineMap.set(packageName, line);
92+
console.info(line);
93+
}
94+
for (const packageName of consoleLineMap.keys()) {
95+
if (infoList.some((problem) => problem.packageName === packageName)) {
96+
continue;
97+
}
98+
consoleLineMap.delete(packageName);
99+
console.info(`[jsenv] "${packageName}" is now installed`);
100+
}
101+
};
102+
70103
const describe = ({ packageName, declaredVersion, installedVersion }) => {
71104
return `${packageName}
72105
package.json declares ${declaredVersion}

dist/start_dev_server/start_dev_server.js

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ const createEventEmitter = () => {
6262
* Only exact declared versions ("1.2.3") are compared: a range ("^1.2.3"), a
6363
* file/workspace protocol or a tag cannot be checked without resolving what npm
6464
* would pick, which is way beyond what is needed here.
65+
*
66+
* A status carries a severity so that every consumer (server log, browser
67+
* overlay, reload on install) reads the same decision: a missing package or an
68+
* outdated runtime dependency is a "warning", the page is not running what the
69+
* project asks for. An outdated devDependency is only "info": the installed
70+
* version runs, what may differ is tooling, and that is worth a line in the
71+
* console, not a dialog nor a reload once installed.
6572
*/
6673

6774

@@ -93,13 +100,14 @@ const readDependencyStatus = (
93100
if (!packageJSON) {
94101
return null;
95102
}
96-
const declaredVersion = readDeclaredVersion(packageJSON, packageName);
97-
if (!declaredVersion) {
103+
const declaration = readDeclaration(packageJSON, packageName);
104+
if (!declaration) {
98105
return null;
99106
}
100107
return createStatus(packageDirectory, {
101108
packageName,
102-
declaredVersion,
109+
declaredVersion: declaration.version,
110+
declaredIn: declaration.field,
103111
declaringDirectoryUrl,
104112
declaredBy: packageJSON.name,
105113
});
@@ -126,6 +134,7 @@ const readDependencyStatuses = (packageDirectory) => {
126134
createStatus(packageDirectory, {
127135
packageName,
128136
declaredVersion: dependencies[packageName],
137+
declaredIn: field,
129138
declaringDirectoryUrl: packageDirectory.url,
130139
declaredBy: packageJSON.name,
131140
}),
@@ -137,17 +146,25 @@ const readDependencyStatuses = (packageDirectory) => {
137146

138147
const createStatus = (
139148
packageDirectory,
140-
{ packageName, declaredVersion, declaringDirectoryUrl, declaredBy },
149+
{
150+
packageName,
151+
declaredVersion,
152+
declaredIn,
153+
declaringDirectoryUrl,
154+
declaredBy,
155+
},
141156
) => {
142157
const status = {
143158
packageName,
144159
declaredVersion,
160+
declaredIn,
145161
declaredBy,
146162
installedVersion: null,
147163
// the file telling this dependency apart; it is what an install rewrites and
148164
// what the dev server looks at to know the dependency became the declared one
149165
watchedPath: null,
150166
state: "missing",
167+
severity: "warning",
151168
};
152169
const installedDirectoryUrl = findInstalledDirectoryUrl(
153170
declaringDirectoryUrl,
@@ -169,11 +186,16 @@ const createStatus = (
169186
status.installedVersion = installedPackageJSON
170187
? installedPackageJSON.version
171188
: null;
172-
status.state =
173-
isExactVersion(declaredVersion) &&
174-
status.installedVersion !== declaredVersion
175-
? "outdated"
176-
: "installed";
189+
if (
190+
!isExactVersion(declaredVersion) ||
191+
status.installedVersion === declaredVersion
192+
) {
193+
status.state = "installed";
194+
status.severity = null;
195+
return status;
196+
}
197+
status.state = "outdated";
198+
status.severity = declaredIn === "devDependencies" ? "info" : "warning";
177199
return status;
178200
};
179201

@@ -201,11 +223,11 @@ const findInstalledDirectoryUrl = (declaringDirectoryUrl, packageName) => {
201223
return null;
202224
};
203225

204-
const readDeclaredVersion = (packageJSON, packageName) => {
226+
const readDeclaration = (packageJSON, packageName) => {
205227
for (const field of DEPENDENCY_FIELDS) {
206228
const dependencies = packageJSON[field];
207229
if (dependencies && dependencies[packageName]) {
208-
return dependencies[packageName];
230+
return { field, version: dependencies[packageName] };
209231
}
210232
}
211233
return null;
@@ -12152,15 +12174,29 @@ const startDevServer = async ({
1215212174
onChange: (problems) => {
1215312175
dependencyProblemEventEmitter.emit(problems);
1215412176
},
12155-
onProblem: ({ packageName, declaredVersion, installedVersion, state }) => {
12156-
logger.warn(
12177+
onProblem: ({
12178+
packageName,
12179+
declaredVersion,
12180+
installedVersion,
12181+
declaredIn,
12182+
state,
12183+
severity,
12184+
}) => {
12185+
const message =
1215712186
state === "missing"
1215812187
? `"${packageName}@${declaredVersion}" is declared in package.json but not installed, run npm install`
12159-
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion}, run npm install`,
12160-
);
12188+
: `"${packageName}" is installed in ${installedVersion} but package.json declares ${declaredVersion} in ${declaredIn}, run npm install`;
12189+
if (severity === "warning") {
12190+
logger.warn(message);
12191+
} else {
12192+
logger.info(message);
12193+
}
1216112194
},
12162-
onInstalled: ({ packageName, declaredVersion }) => {
12195+
onInstalled: ({ packageName, declaredVersion, severity }) => {
1216312196
logger.info(`"${packageName}@${declaredVersion}" is now installed`);
12197+
if (severity !== "warning") {
12198+
return;
12199+
}
1216412200
reloadRequestEventEmitter.emit({
1216512201
cause: `${packageName}@${declaredVersion} installed`,
1216612202
reason: `a dependency became available in node_modules`,

0 commit comments

Comments
 (0)