@jsenv/core 36.0.2 → 36.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jsenv_core.js +149 -879
- package/package.json +4 -4
- package/src/build/build.js +29 -40
- package/src/dev/file_service.js +18 -3
- package/src/dev/start_dev_server.js +2 -0
- package/src/kitchen/kitchen.js +65 -12
- package/src/kitchen/url_graph/url_graph_report.js +9 -5
- package/src/kitchen/url_graph.js +0 -1
- package/src/plugins/plugin_controller.js +15 -7
- package/src/plugins/plugins.js +2 -1
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +44 -39
- package/src/plugins/protocol_http/jsenv_plugin_protocol_http.js +4 -3
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +0 -88
- package/dist/js/supervisor.js +0 -1175
- package/src/helpers/basic_fetch.js +0 -53
- package/src/helpers/ping_server.js +0 -30
- package/src/plugins/supervisor/client/supervisor.js +0 -1153
- package/src/plugins/supervisor/html_supervisor_injection.js +0 -281
- package/src/plugins/supervisor/js_supervisor_injection.js +0 -283
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +0 -218
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "36.
|
|
3
|
+
"version": "36.1.1",
|
|
4
4
|
"description": "Tool to develop, test and build js projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -69,13 +69,13 @@
|
|
|
69
69
|
"@jsenv/integrity": "0.0.1",
|
|
70
70
|
"@jsenv/log": "3.3.5",
|
|
71
71
|
"@jsenv/node-esm-resolution": "1.0.1",
|
|
72
|
+
"@jsenv/plugin-supervisor": "1.0.0",
|
|
72
73
|
"@jsenv/server": "15.0.3",
|
|
73
74
|
"@jsenv/sourcemap": "1.0.10",
|
|
74
75
|
"@jsenv/url-meta": "8.1.0",
|
|
75
76
|
"@jsenv/urls": "2.0.0",
|
|
76
77
|
"@jsenv/utils": "2.0.1",
|
|
77
78
|
"construct-style-sheets-polyfill": "3.1.0",
|
|
78
|
-
"launch-editor": "2.6.0",
|
|
79
79
|
"lightningcss": "1.20.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
@@ -92,11 +92,11 @@
|
|
|
92
92
|
"@jsenv/plugin-placeholders": "./packages/jsenv-plugin-placeholders/",
|
|
93
93
|
"@jsenv/plugin-as-js-classic": "./packages/jsenv-plugin-as-js-classic/",
|
|
94
94
|
"@jsenv/test": "./packages/test/",
|
|
95
|
-
"eslint": "8.
|
|
95
|
+
"eslint": "8.41.0",
|
|
96
96
|
"eslint-plugin-html": "7.1.0",
|
|
97
97
|
"eslint-plugin-import": "2.27.5",
|
|
98
98
|
"eslint-plugin-react": "7.32.2",
|
|
99
|
-
"playwright": "1.
|
|
99
|
+
"playwright": "1.34.2",
|
|
100
100
|
"prettier": "2.8.8"
|
|
101
101
|
}
|
|
102
102
|
}
|
package/src/build/build.js
CHANGED
|
@@ -130,6 +130,7 @@ export const build = async ({
|
|
|
130
130
|
buildDirectoryUrl,
|
|
131
131
|
entryPoints = {},
|
|
132
132
|
assetsDirectory = "",
|
|
133
|
+
ignore,
|
|
133
134
|
|
|
134
135
|
runtimeCompat = defaultRuntimeCompat,
|
|
135
136
|
base = runtimeCompat.node ? "./" : "/",
|
|
@@ -311,6 +312,10 @@ build ${entryPointKeys.length} entry points`);
|
|
|
311
312
|
signal,
|
|
312
313
|
logLevel,
|
|
313
314
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
315
|
+
ignore,
|
|
316
|
+
// during first pass (craft) we keep "ignore:" when a reference is ignored
|
|
317
|
+
// so that the second pass (shape) properly ignore those urls
|
|
318
|
+
ignoreProtocol: "keep",
|
|
314
319
|
urlGraph: rawGraph,
|
|
315
320
|
build: true,
|
|
316
321
|
runtimeCompat,
|
|
@@ -332,13 +337,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
332
337
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
333
338
|
urlGraph: rawGraph,
|
|
334
339
|
runtimeCompat,
|
|
335
|
-
|
|
336
|
-
referenceAnalysis: {
|
|
337
|
-
...referenceAnalysis,
|
|
338
|
-
// during first pass (craft) we inject "ignore:" when a reference must be ignored
|
|
339
|
-
// so that the second pass (shape) properly ignore those urls
|
|
340
|
-
ignoreProtocol: "inject",
|
|
341
|
-
},
|
|
340
|
+
referenceAnalysis,
|
|
342
341
|
nodeEsmResolution,
|
|
343
342
|
magicExtensions,
|
|
344
343
|
magicDirectoryIndex,
|
|
@@ -383,6 +382,14 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
383
382
|
const finalGraphKitchen = createKitchen({
|
|
384
383
|
logLevel,
|
|
385
384
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
385
|
+
// here most plugins are not there
|
|
386
|
+
// - no external plugin
|
|
387
|
+
// - no plugin putting reference.mustIgnore on https urls
|
|
388
|
+
// At this stage it's only about redirecting urls to the build directory
|
|
389
|
+
// consequently only a subset or urls are supported
|
|
390
|
+
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
391
|
+
ignore,
|
|
392
|
+
ignoreProtocol: versioning ? "keep" : "remove",
|
|
386
393
|
urlGraph: finalGraph,
|
|
387
394
|
build: true,
|
|
388
395
|
runtimeCompat,
|
|
@@ -390,14 +397,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
390
397
|
plugins: [
|
|
391
398
|
jsenvPluginReferenceAnalysis({
|
|
392
399
|
...referenceAnalysis,
|
|
393
|
-
// here most plugins are not there
|
|
394
|
-
// - no external plugin
|
|
395
|
-
// - no plugin putting reference.mustIgnore on https urls
|
|
396
|
-
// At this stage it's only about redirecting urls to the build directory
|
|
397
|
-
// consequently only a subset or urls are supported
|
|
398
|
-
supportedProtocols: ["file:", "data:", "virtual:", "ignore:"],
|
|
399
400
|
fetchInlineUrls: false,
|
|
400
|
-
ignoreProtocol: versioning ? "keep" : "remove",
|
|
401
401
|
}),
|
|
402
402
|
...(lineBreakNormalization
|
|
403
403
|
? [jsenvPluginLineBreakNormalization()]
|
|
@@ -1063,14 +1063,11 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1063
1063
|
const contentVersionMap = new Map();
|
|
1064
1064
|
const hashCallbacks = [];
|
|
1065
1065
|
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
1066
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
1067
|
-
return;
|
|
1068
|
-
}
|
|
1069
1066
|
if (urlInfo.type === "sourcemap") {
|
|
1070
1067
|
return;
|
|
1071
1068
|
}
|
|
1072
1069
|
// ignore:
|
|
1073
|
-
// - inline files:
|
|
1070
|
+
// - inline files and data files:
|
|
1074
1071
|
// they are already taken into account in the file where they appear
|
|
1075
1072
|
// - ignored files:
|
|
1076
1073
|
// we don't know their content
|
|
@@ -1082,7 +1079,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1082
1079
|
if (urlInfo.isInline) {
|
|
1083
1080
|
return;
|
|
1084
1081
|
}
|
|
1085
|
-
if (urlInfo.
|
|
1082
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
1086
1086
|
return;
|
|
1087
1087
|
}
|
|
1088
1088
|
if (urlInfo.dependents.size === 0 && !urlInfo.isEntryPoint) {
|
|
@@ -1116,7 +1116,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1116
1116
|
);
|
|
1117
1117
|
if (!dependencyContentVersion) {
|
|
1118
1118
|
// no content generated for this dependency
|
|
1119
|
-
// (inline, data:, sourcemap,
|
|
1119
|
+
// (inline, data:, ignore:, sourcemap, ...)
|
|
1120
1120
|
return null;
|
|
1121
1121
|
}
|
|
1122
1122
|
if (preferWithoutVersioning(reference)) {
|
|
@@ -1182,20 +1182,15 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1182
1182
|
const versioningKitchen = createKitchen({
|
|
1183
1183
|
logLevel: logger.level,
|
|
1184
1184
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
1185
|
+
ignore,
|
|
1186
|
+
ignoreProtocol: "remove",
|
|
1185
1187
|
urlGraph: finalGraph,
|
|
1186
1188
|
build: true,
|
|
1187
1189
|
runtimeCompat,
|
|
1188
1190
|
...contextSharedDuringBuild,
|
|
1189
1191
|
plugins: [
|
|
1190
|
-
// here most plugins are not there
|
|
1191
|
-
// - no external plugin
|
|
1192
|
-
// - no plugin putting reference.mustIgnore on https urls
|
|
1193
|
-
// At this stage it's only about versioning urls
|
|
1194
|
-
// consequently only a subset or urls are supported
|
|
1195
1192
|
jsenvPluginReferenceAnalysis({
|
|
1196
1193
|
...referenceAnalysis,
|
|
1197
|
-
supportedProtocols: ["file:", "data:", "virtual:"],
|
|
1198
|
-
ignoreProtocol: "remove",
|
|
1199
1194
|
fetchInlineUrls: false,
|
|
1200
1195
|
inlineConvertedScript: true, // to be able to version their urls
|
|
1201
1196
|
allowEscapeForVersioning: true,
|
|
@@ -1238,10 +1233,13 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1238
1233
|
return url;
|
|
1239
1234
|
},
|
|
1240
1235
|
formatReference: (reference) => {
|
|
1241
|
-
if (reference.
|
|
1236
|
+
if (reference.url.startsWith("ignore:")) {
|
|
1237
|
+
return null;
|
|
1238
|
+
}
|
|
1239
|
+
if (reference.isInline) {
|
|
1242
1240
|
return null;
|
|
1243
1241
|
}
|
|
1244
|
-
if (reference.
|
|
1242
|
+
if (reference.url.startsWith("data:")) {
|
|
1245
1243
|
return null;
|
|
1246
1244
|
}
|
|
1247
1245
|
if (reference.isResourceHint) {
|
|
@@ -1255,9 +1253,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1255
1253
|
if (!canUseVersionedUrl(referencedUrlInfo)) {
|
|
1256
1254
|
return reference.specifier;
|
|
1257
1255
|
}
|
|
1258
|
-
if (referencedUrlInfo.mustIgnore) {
|
|
1259
|
-
return null;
|
|
1260
|
-
}
|
|
1261
1256
|
const versionedUrl = versionedUrlMap.get(reference.url);
|
|
1262
1257
|
if (!versionedUrl) {
|
|
1263
1258
|
// happens for sourcemap
|
|
@@ -1384,9 +1379,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1384
1379
|
}
|
|
1385
1380
|
cleanup_jsenv_attributes_from_html: {
|
|
1386
1381
|
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
1387
|
-
if (urlInfo.mustIgnore) {
|
|
1388
|
-
return;
|
|
1389
|
-
}
|
|
1390
1382
|
if (!urlInfo.url.startsWith("file:")) {
|
|
1391
1383
|
return;
|
|
1392
1384
|
}
|
|
@@ -1569,10 +1561,10 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1569
1561
|
if (serviceWorkerEntryUrlInfos.length > 0) {
|
|
1570
1562
|
const serviceWorkerResources = {};
|
|
1571
1563
|
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
1572
|
-
if (urlInfo.
|
|
1564
|
+
if (!urlInfo.url.startsWith("file:")) {
|
|
1573
1565
|
return;
|
|
1574
1566
|
}
|
|
1575
|
-
if (
|
|
1567
|
+
if (urlInfo.isInline) {
|
|
1576
1568
|
return;
|
|
1577
1569
|
}
|
|
1578
1570
|
if (!canUseVersionedUrl(urlInfo)) {
|
|
@@ -1642,9 +1634,6 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
|
|
|
1642
1634
|
return buildRelativeUrl;
|
|
1643
1635
|
};
|
|
1644
1636
|
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
1645
|
-
if (urlInfo.mustIgnore) {
|
|
1646
|
-
return;
|
|
1647
|
-
}
|
|
1648
1637
|
if (!urlInfo.url.startsWith("file:")) {
|
|
1649
1638
|
return;
|
|
1650
1639
|
}
|
package/src/dev/file_service.js
CHANGED
|
@@ -22,6 +22,7 @@ export const createFileService = ({
|
|
|
22
22
|
|
|
23
23
|
sourceDirectoryUrl,
|
|
24
24
|
sourceMainFilePath,
|
|
25
|
+
ignore,
|
|
25
26
|
sourceFilesConfig,
|
|
26
27
|
runtimeCompat,
|
|
27
28
|
|
|
@@ -97,6 +98,7 @@ export const createFileService = ({
|
|
|
97
98
|
logLevel,
|
|
98
99
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
99
100
|
mainFilePath: sourceMainFilePath,
|
|
101
|
+
ignore,
|
|
100
102
|
urlGraph,
|
|
101
103
|
dev: true,
|
|
102
104
|
runtimeCompat,
|
|
@@ -252,7 +254,11 @@ export const createFileService = ({
|
|
|
252
254
|
return responseFromPlugin;
|
|
253
255
|
}
|
|
254
256
|
let reference;
|
|
255
|
-
const parentUrl = inferParentFromRequest(
|
|
257
|
+
const parentUrl = inferParentFromRequest(
|
|
258
|
+
request,
|
|
259
|
+
sourceDirectoryUrl,
|
|
260
|
+
sourceMainFilePath,
|
|
261
|
+
);
|
|
256
262
|
if (parentUrl) {
|
|
257
263
|
reference = urlGraph.inferReference(request.resource, parentUrl);
|
|
258
264
|
}
|
|
@@ -423,7 +429,11 @@ export const createFileService = ({
|
|
|
423
429
|
};
|
|
424
430
|
};
|
|
425
431
|
|
|
426
|
-
const inferParentFromRequest = (
|
|
432
|
+
const inferParentFromRequest = (
|
|
433
|
+
request,
|
|
434
|
+
sourceDirectoryUrl,
|
|
435
|
+
sourceMainFilePath,
|
|
436
|
+
) => {
|
|
427
437
|
const { referer } = request.headers;
|
|
428
438
|
if (!referer) {
|
|
429
439
|
return null;
|
|
@@ -431,7 +441,12 @@ const inferParentFromRequest = (request, sourceDirectoryUrl) => {
|
|
|
431
441
|
const refererUrlObject = new URL(referer);
|
|
432
442
|
refererUrlObject.searchParams.delete("hmr");
|
|
433
443
|
refererUrlObject.searchParams.delete("v");
|
|
434
|
-
|
|
444
|
+
|
|
445
|
+
let refererUrl = refererUrlObject.href;
|
|
446
|
+
if (refererUrl === `${request.origin}/`) {
|
|
447
|
+
refererUrl = new URL(sourceMainFilePath, request.origin).href;
|
|
448
|
+
}
|
|
449
|
+
return WEB_URL_CONVERTER.asFileUrl(refererUrl, {
|
|
435
450
|
origin: request.origin,
|
|
436
451
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
437
452
|
});
|
|
@@ -25,6 +25,7 @@ import { createFileService } from "./file_service.js";
|
|
|
25
25
|
export const startDevServer = async ({
|
|
26
26
|
sourceDirectoryUrl,
|
|
27
27
|
sourceMainFilePath = "./index.html",
|
|
28
|
+
ignore,
|
|
28
29
|
port = 3456,
|
|
29
30
|
hostname,
|
|
30
31
|
acceptAnyIp,
|
|
@@ -186,6 +187,7 @@ export const startDevServer = async ({
|
|
|
186
187
|
|
|
187
188
|
sourceDirectoryUrl,
|
|
188
189
|
sourceMainFilePath,
|
|
190
|
+
ignore,
|
|
189
191
|
sourceFilesConfig,
|
|
190
192
|
runtimeCompat,
|
|
191
193
|
|
package/src/kitchen/kitchen.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
normalizeUrl,
|
|
7
7
|
setUrlFilename,
|
|
8
8
|
} from "@jsenv/urls";
|
|
9
|
+
import { URL_META } from "@jsenv/url-meta";
|
|
9
10
|
import { writeFileSync, ensureWindowsDriveLetter } from "@jsenv/filesystem";
|
|
10
11
|
import { createLogger, createDetailedMessage, ANSI } from "@jsenv/log";
|
|
11
12
|
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
@@ -29,6 +30,9 @@ export const createKitchen = ({
|
|
|
29
30
|
|
|
30
31
|
rootDirectoryUrl,
|
|
31
32
|
mainFilePath,
|
|
33
|
+
ignore,
|
|
34
|
+
ignoreProtocol = "remove",
|
|
35
|
+
supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"],
|
|
32
36
|
urlGraph,
|
|
33
37
|
dev = false,
|
|
34
38
|
build = false,
|
|
@@ -72,6 +76,35 @@ export const createKitchen = ({
|
|
|
72
76
|
pluginController.pushPlugin(pluginEntry);
|
|
73
77
|
});
|
|
74
78
|
|
|
79
|
+
const isIgnoredByProtocol = (url) => {
|
|
80
|
+
const { protocol } = new URL(url);
|
|
81
|
+
const protocolIsSupported = supportedProtocols.some(
|
|
82
|
+
(supportedProtocol) => protocol === supportedProtocol,
|
|
83
|
+
);
|
|
84
|
+
return !protocolIsSupported;
|
|
85
|
+
};
|
|
86
|
+
let isIgnoredByParam = () => false;
|
|
87
|
+
if (ignore) {
|
|
88
|
+
const associations = URL_META.resolveAssociations(
|
|
89
|
+
{ ignore },
|
|
90
|
+
rootDirectoryUrl,
|
|
91
|
+
);
|
|
92
|
+
const cache = new Map();
|
|
93
|
+
isIgnoredByParam = (url) => {
|
|
94
|
+
const fromCache = cache.get(url);
|
|
95
|
+
if (fromCache) return fromCache;
|
|
96
|
+
const { ignore } = URL_META.applyAssociations({
|
|
97
|
+
url,
|
|
98
|
+
associations,
|
|
99
|
+
});
|
|
100
|
+
cache.set(url, ignore);
|
|
101
|
+
return ignore;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const isIgnored = (url) => {
|
|
105
|
+
return isIgnoredByProtocol(url) || isIgnoredByParam(url);
|
|
106
|
+
};
|
|
107
|
+
|
|
75
108
|
/*
|
|
76
109
|
* - "http_request"
|
|
77
110
|
* - "entry_point"
|
|
@@ -116,7 +149,6 @@ export const createKitchen = ({
|
|
|
116
149
|
specifierColumn,
|
|
117
150
|
baseUrl,
|
|
118
151
|
isOriginalPosition,
|
|
119
|
-
mustIgnore,
|
|
120
152
|
isEntryPoint = false,
|
|
121
153
|
isResourceHint = false,
|
|
122
154
|
isImplicit = false,
|
|
@@ -165,7 +197,6 @@ export const createKitchen = ({
|
|
|
165
197
|
specifierColumn,
|
|
166
198
|
isOriginalPosition,
|
|
167
199
|
baseUrl,
|
|
168
|
-
mustIgnore,
|
|
169
200
|
isEntryPoint,
|
|
170
201
|
isResourceHint,
|
|
171
202
|
isImplicit,
|
|
@@ -216,13 +247,36 @@ export const createKitchen = ({
|
|
|
216
247
|
url = normalizeUrl(url);
|
|
217
248
|
let referencedUrlObject;
|
|
218
249
|
let searchParams;
|
|
219
|
-
const
|
|
250
|
+
const setReferenceUrl = (referenceUrl) => {
|
|
251
|
+
// ignored urls are prefixed with "ignore:" so that reference are associated
|
|
252
|
+
// to a dedicated urlInfo that is ignored.
|
|
253
|
+
// this way it's only once a resource is referenced by reference that is not ignored
|
|
254
|
+
// that the resource is cooked
|
|
255
|
+
if (
|
|
256
|
+
reference.specifier[0] === "#" &&
|
|
257
|
+
// For Html, css and "#" refer to a resource in the page, reference must be preserved
|
|
258
|
+
// However for js import specifiers they have a different meaning and we want
|
|
259
|
+
// to resolve them (https://nodejs.org/api/packages.html#imports for instance)
|
|
260
|
+
reference.type !== "js_import"
|
|
261
|
+
) {
|
|
262
|
+
referenceUrl = `ignore:${referenceUrl}`;
|
|
263
|
+
} else if (isIgnored(referenceUrl)) {
|
|
264
|
+
referenceUrl = `ignore:${referenceUrl}`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (
|
|
268
|
+
referenceUrl.startsWith("ignore:") &&
|
|
269
|
+
!reference.specifier.startsWith("ignore:")
|
|
270
|
+
) {
|
|
271
|
+
reference.specifier = `ignore:${reference.specifier}`;
|
|
272
|
+
}
|
|
273
|
+
|
|
220
274
|
referencedUrlObject = new URL(referenceUrl);
|
|
221
275
|
searchParams = referencedUrlObject.searchParams;
|
|
222
276
|
reference.url = referenceUrl;
|
|
223
277
|
reference.searchParams = searchParams;
|
|
224
278
|
};
|
|
225
|
-
|
|
279
|
+
setReferenceUrl(url);
|
|
226
280
|
|
|
227
281
|
if (reference.debug) {
|
|
228
282
|
logger.debug(`url resolved by "${
|
|
@@ -251,7 +305,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
251
305
|
}
|
|
252
306
|
const prevReference = { ...reference };
|
|
253
307
|
updateReference(prevReference, reference);
|
|
254
|
-
|
|
308
|
+
setReferenceUrl(normalizedReturnValue);
|
|
255
309
|
},
|
|
256
310
|
);
|
|
257
311
|
reference.generatedUrl = reference.url;
|
|
@@ -276,12 +330,16 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
276
330
|
reference.generatedUrl = normalizeUrl(referencedUrlObject.href);
|
|
277
331
|
},
|
|
278
332
|
);
|
|
333
|
+
|
|
279
334
|
const returnValue = pluginController.callHooksUntil(
|
|
280
335
|
"formatReference",
|
|
281
336
|
reference,
|
|
282
337
|
referenceContext,
|
|
283
338
|
);
|
|
284
|
-
if (reference.
|
|
339
|
+
if (reference.url.startsWith("ignore:")) {
|
|
340
|
+
if (ignoreProtocol === "remove") {
|
|
341
|
+
reference.specifier = reference.specifier.slice("ignore:".length);
|
|
342
|
+
}
|
|
285
343
|
reference.generatedSpecifier = reference.specifier;
|
|
286
344
|
reference.generatedSpecifier = urlSpecifierEncoding.encode(reference);
|
|
287
345
|
} else {
|
|
@@ -469,7 +527,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
|
|
|
469
527
|
});
|
|
470
528
|
};
|
|
471
529
|
|
|
472
|
-
if (!urlInfo.
|
|
530
|
+
if (!urlInfo.url.startsWith("ignore:")) {
|
|
473
531
|
// references
|
|
474
532
|
const references = [];
|
|
475
533
|
context.referenceUtils = {
|
|
@@ -854,11 +912,6 @@ const traceFromUrlSite = (urlSite) => {
|
|
|
854
912
|
};
|
|
855
913
|
|
|
856
914
|
const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
857
|
-
if (reference.mustIgnore) {
|
|
858
|
-
urlInfo.mustIgnore = true;
|
|
859
|
-
} else {
|
|
860
|
-
urlInfo.mustIgnore = false;
|
|
861
|
-
}
|
|
862
915
|
urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
|
|
863
916
|
|
|
864
917
|
if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
|
|
@@ -30,15 +30,19 @@ const createUrlGraphReport = (urlGraph) => {
|
|
|
30
30
|
total: 0,
|
|
31
31
|
};
|
|
32
32
|
urlGraph.urlInfoMap.forEach((urlInfo) => {
|
|
33
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
33
|
// ignore:
|
|
37
|
-
// - inline files: they are already taken into account in the file where they appear
|
|
38
34
|
// - ignored files: we don't know their content
|
|
39
|
-
|
|
35
|
+
// - inline files and data files: they are already taken into account in the file where they appear
|
|
36
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (urlInfo.isInline) {
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
// file loaded via import assertion are already inside the graph
|
|
43
47
|
// their js module equivalent are ignored to avoid counting it twice
|
|
44
48
|
// in the build graph the file targeted by import assertion will likely be gone
|
package/src/kitchen/url_graph.js
CHANGED
|
@@ -153,7 +153,11 @@ export const createPluginController = (kitchenContext) => {
|
|
|
153
153
|
info.timing[`${hook.name}-${hook.plugin.name.replace("jsenv:", "")}`] =
|
|
154
154
|
performance.now() - startTimestamp;
|
|
155
155
|
}
|
|
156
|
-
valueReturned = assertAndNormalizeReturnValue(
|
|
156
|
+
valueReturned = assertAndNormalizeReturnValue(
|
|
157
|
+
hook.name,
|
|
158
|
+
valueReturned,
|
|
159
|
+
info,
|
|
160
|
+
);
|
|
157
161
|
return valueReturned;
|
|
158
162
|
};
|
|
159
163
|
const callAsyncHook = async (hook, info, context) => {
|
|
@@ -176,7 +180,11 @@ export const createPluginController = (kitchenContext) => {
|
|
|
176
180
|
info.timing[`${hook.name}-${hook.plugin.name.replace("jsenv:", "")}`] =
|
|
177
181
|
performance.now() - startTimestamp;
|
|
178
182
|
}
|
|
179
|
-
valueReturned = assertAndNormalizeReturnValue(
|
|
183
|
+
valueReturned = assertAndNormalizeReturnValue(
|
|
184
|
+
hook.name,
|
|
185
|
+
valueReturned,
|
|
186
|
+
info,
|
|
187
|
+
);
|
|
180
188
|
return valueReturned;
|
|
181
189
|
};
|
|
182
190
|
|
|
@@ -277,7 +285,7 @@ const getHookFunction = (
|
|
|
277
285
|
return hookValue;
|
|
278
286
|
};
|
|
279
287
|
|
|
280
|
-
const assertAndNormalizeReturnValue = (hookName, returnValue) => {
|
|
288
|
+
const assertAndNormalizeReturnValue = (hookName, returnValue, info) => {
|
|
281
289
|
// all hooks are allowed to return null/undefined as a signal of "I don't do anything"
|
|
282
290
|
if (returnValue === null || returnValue === undefined) {
|
|
283
291
|
return returnValue;
|
|
@@ -286,7 +294,7 @@ const assertAndNormalizeReturnValue = (hookName, returnValue) => {
|
|
|
286
294
|
if (!returnValueAssertion.appliesTo.includes(hookName)) {
|
|
287
295
|
continue;
|
|
288
296
|
}
|
|
289
|
-
const assertionResult = returnValueAssertion.assertion(returnValue);
|
|
297
|
+
const assertionResult = returnValueAssertion.assertion(returnValue, info);
|
|
290
298
|
if (assertionResult !== undefined) {
|
|
291
299
|
// normalization
|
|
292
300
|
returnValue = assertionResult;
|
|
@@ -320,13 +328,13 @@ const returnValueAssertions = [
|
|
|
320
328
|
"finalizeUrlContent",
|
|
321
329
|
"optimizeUrlContent",
|
|
322
330
|
],
|
|
323
|
-
assertion: (valueReturned) => {
|
|
331
|
+
assertion: (valueReturned, urlInfo) => {
|
|
324
332
|
if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
|
|
325
333
|
return { content: valueReturned };
|
|
326
334
|
}
|
|
327
335
|
if (typeof valueReturned === "object") {
|
|
328
|
-
const {
|
|
329
|
-
if (
|
|
336
|
+
const { content, body } = valueReturned;
|
|
337
|
+
if (urlInfo.url.startsWith("ignore:")) {
|
|
330
338
|
return undefined;
|
|
331
339
|
}
|
|
332
340
|
if (typeof content !== "string" && !Buffer.isBuffer(content) && !body) {
|
package/src/plugins/plugins.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
2
|
+
|
|
1
3
|
import { jsenvPluginReferenceAnalysis } from "./reference_analysis/jsenv_plugin_reference_analysis.js";
|
|
2
4
|
import { jsenvPluginImportmap } from "./importmap/jsenv_plugin_importmap.js";
|
|
3
5
|
import { jsenvPluginNodeEsmResolution } from "./resolution_node_esm/jsenv_plugin_node_esm_resolution.js";
|
|
@@ -6,7 +8,6 @@ import { jsenvPluginVersionSearchParam } from "./version_search_param/jsenv_plug
|
|
|
6
8
|
import { jsenvPluginProtocolFile } from "./protocol_file/jsenv_plugin_protocol_file.js";
|
|
7
9
|
import { jsenvPluginProtocolHttp } from "./protocol_http/jsenv_plugin_protocol_http.js";
|
|
8
10
|
import { jsenvPluginInlining } from "./inlining/jsenv_plugin_inlining.js";
|
|
9
|
-
import { jsenvPluginSupervisor } from "./supervisor/jsenv_plugin_supervisor.js";
|
|
10
11
|
import { jsenvPluginCommonJsGlobals } from "./commonjs_globals/jsenv_plugin_commonjs_globals.js";
|
|
11
12
|
import { jsenvPluginImportMetaScenarios } from "./import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js";
|
|
12
13
|
import { jsenvPluginGlobalScenarios } from "./global_scenarios/jsenv_plugin_global_scenarios.js";
|
|
@@ -30,6 +30,23 @@ export const jsenvPluginProtocolFile = ({
|
|
|
30
30
|
if (reference.isInline) {
|
|
31
31
|
return null;
|
|
32
32
|
}
|
|
33
|
+
// ignore root file url
|
|
34
|
+
if (reference.url === "file:///" || reference.url === "file://") {
|
|
35
|
+
reference.leadsToADirectory = true;
|
|
36
|
+
return `ignore:file:///`;
|
|
37
|
+
}
|
|
38
|
+
// ignore "./" on new URL("./")
|
|
39
|
+
if (
|
|
40
|
+
reference.subtype === "new_url_first_arg" &&
|
|
41
|
+
reference.specifier === "./"
|
|
42
|
+
) {
|
|
43
|
+
return `ignore:${reference.url}`;
|
|
44
|
+
}
|
|
45
|
+
// ignore all new URL second arg
|
|
46
|
+
if (reference.subtype === "new_url_second_arg") {
|
|
47
|
+
return `ignore:${reference.url}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
const urlObject = new URL(reference.url);
|
|
34
51
|
let stat;
|
|
35
52
|
try {
|
|
@@ -41,11 +58,13 @@ export const jsenvPluginProtocolFile = ({
|
|
|
41
58
|
throw e;
|
|
42
59
|
}
|
|
43
60
|
}
|
|
61
|
+
|
|
44
62
|
const { search, hash } = urlObject;
|
|
45
63
|
let { pathname } = urlObject;
|
|
46
64
|
const pathnameUsesTrailingSlash = pathname.endsWith("/");
|
|
47
65
|
urlObject.search = "";
|
|
48
66
|
urlObject.hash = "";
|
|
67
|
+
|
|
49
68
|
// force trailing slash on directories
|
|
50
69
|
if (stat && stat.isDirectory() && !pathnameUsesTrailingSlash) {
|
|
51
70
|
urlObject.pathname = `${pathname}/`;
|
|
@@ -57,46 +76,32 @@ export const jsenvPluginProtocolFile = ({
|
|
|
57
76
|
}
|
|
58
77
|
|
|
59
78
|
let url = urlObject.href;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
reference.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
reference.type === "js_import";
|
|
75
|
-
if (shouldApplyDilesystemMagicResolution) {
|
|
76
|
-
const filesystemResolution = applyFileSystemMagicResolution(url, {
|
|
77
|
-
fileStat: stat,
|
|
78
|
-
magicDirectoryIndex,
|
|
79
|
-
magicExtensions: getExtensionsToTry(
|
|
80
|
-
magicExtensions,
|
|
81
|
-
reference.parentUrl,
|
|
82
|
-
),
|
|
83
|
-
});
|
|
84
|
-
if (filesystemResolution.stat) {
|
|
85
|
-
stat = filesystemResolution.stat;
|
|
86
|
-
url = filesystemResolution.url;
|
|
87
|
-
}
|
|
79
|
+
const shouldApplyDilesystemMagicResolution =
|
|
80
|
+
reference.type === "js_import";
|
|
81
|
+
if (shouldApplyDilesystemMagicResolution) {
|
|
82
|
+
const filesystemResolution = applyFileSystemMagicResolution(url, {
|
|
83
|
+
fileStat: stat,
|
|
84
|
+
magicDirectoryIndex,
|
|
85
|
+
magicExtensions: getExtensionsToTry(
|
|
86
|
+
magicExtensions,
|
|
87
|
+
reference.parentUrl,
|
|
88
|
+
),
|
|
89
|
+
});
|
|
90
|
+
if (filesystemResolution.stat) {
|
|
91
|
+
stat = filesystemResolution.stat;
|
|
92
|
+
url = filesystemResolution.url;
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
directoryReferenceAllowed
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
}
|
|
95
|
+
if (stat && stat.isDirectory()) {
|
|
96
|
+
const directoryAllowed =
|
|
97
|
+
reference.type === "filesystem" ||
|
|
98
|
+
(typeof directoryReferenceAllowed === "function" &&
|
|
99
|
+
directoryReferenceAllowed(reference)) ||
|
|
100
|
+
directoryReferenceAllowed;
|
|
101
|
+
if (!directoryAllowed) {
|
|
102
|
+
const error = new Error("Reference leads to a directory");
|
|
103
|
+
error.code = "DIRECTORY_REFERENCE_NOT_ALLOWED";
|
|
104
|
+
throw error;
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
reference.leadsToADirectory = stat && stat.isDirectory();
|
|
@@ -3,14 +3,15 @@ export const jsenvPluginProtocolHttp = () => {
|
|
|
3
3
|
name: "jsenv:protocol_http",
|
|
4
4
|
appliesDuring: "*",
|
|
5
5
|
redirectReference: (reference) => {
|
|
6
|
+
// TODO: according to some pattern matching jsenv could be allowed
|
|
7
|
+
// to fetch and transform http urls
|
|
6
8
|
if (
|
|
7
9
|
reference.url.startsWith("http:") ||
|
|
8
10
|
reference.url.startsWith("https:")
|
|
9
11
|
) {
|
|
10
|
-
reference.
|
|
12
|
+
return `ignore:${reference.url}`;
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
// to fetch and transform http urls
|
|
14
|
+
return null;
|
|
14
15
|
},
|
|
15
16
|
};
|
|
16
17
|
};
|