@jsenv/core 39.14.3 → 40.0.0
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/js/directory_listing.js +16 -9
- package/dist/js/server_events_client.js +2 -2
- package/dist/jsenv_core.js +7220 -11089
- package/package.json +22 -19
- package/src/build/build.js +122 -93
- package/src/build/build_specifier_manager.js +103 -94
- package/src/build/build_urls_generator.js +1 -1
- package/src/build/{version_mappings_injection.js → mappings_injection.js} +62 -21
- package/src/build/start_build_server.js +46 -36
- package/src/dev/start_dev_server.js +246 -248
- package/src/helpers/watch_source_files.js +50 -36
- package/src/kitchen/fetched_content_compliance.js +4 -2
- package/src/kitchen/kitchen.js +31 -24
- package/src/kitchen/url_graph/references.js +10 -2
- package/src/kitchen/url_graph/url_graph.js +3 -0
- package/src/kitchen/url_graph/url_graph_visitor.js +3 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +29 -16
- package/src/plugins/html_syntax_error_fallback/jsenv_plugin_html_syntax_error_fallback.js +1 -1
- package/src/plugins/plugin_controller.js +194 -200
- package/src/plugins/plugins.js +5 -0
- package/src/plugins/protocol_file/client/directory_listing.jsx +5 -0
- package/src/plugins/protocol_file/jsenv_plugin_directory_listing.js +92 -67
- package/src/plugins/protocol_file/jsenv_plugin_fs_redirection.js +17 -7
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +6 -0
- package/src/plugins/protocol_http/jsenv_plugin_protocol_http.js +33 -3
- package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +15 -22
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +53 -2
- package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +37 -30
- package/src/plugins/resolution_node_esm/node_esm_resolver.js +4 -8
- package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +8 -6
- package/src/plugins/server_events/client/server_events_client.js +2 -2
- package/src/plugins/server_events/jsenv_plugin_server_events.js +18 -16
- package/dist/js/ws.js +0 -6863
- package/src/helpers/lookup_package_directory.js +0 -9
|
@@ -28,9 +28,9 @@ import { GRAPH_VISITOR } from "../kitchen/url_graph/url_graph_visitor.js";
|
|
|
28
28
|
import { isWebWorkerUrlInfo } from "../kitchen/web_workers.js";
|
|
29
29
|
import { createBuildUrlsGenerator } from "./build_urls_generator.js";
|
|
30
30
|
import {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} from "./
|
|
31
|
+
injectGlobalMappings,
|
|
32
|
+
injectImportmapMappings,
|
|
33
|
+
} from "./mappings_injection.js";
|
|
34
34
|
|
|
35
35
|
export const createBuildSpecifierManager = ({
|
|
36
36
|
rawKitchen,
|
|
@@ -131,18 +131,18 @@ export const createBuildSpecifierManager = ({
|
|
|
131
131
|
},
|
|
132
132
|
urlInfosToBundle,
|
|
133
133
|
);
|
|
134
|
-
Object.keys(urlInfosBundled)
|
|
134
|
+
for (const url of Object.keys(urlInfosBundled)) {
|
|
135
135
|
const urlInfoBundled = urlInfosBundled[url];
|
|
136
136
|
if (urlInfoBundled.sourceUrls) {
|
|
137
|
-
urlInfoBundled.sourceUrls
|
|
137
|
+
for (const sourceUrl of urlInfoBundled.sourceUrls) {
|
|
138
138
|
const sourceRawUrlInfo = rawKitchen.graph.getUrlInfo(sourceUrl);
|
|
139
139
|
if (sourceRawUrlInfo) {
|
|
140
140
|
sourceRawUrlInfo.data.bundled = true;
|
|
141
141
|
}
|
|
142
|
-
}
|
|
142
|
+
}
|
|
143
143
|
}
|
|
144
144
|
bundleInfoMap.set(url, urlInfoBundled);
|
|
145
|
-
}
|
|
145
|
+
}
|
|
146
146
|
};
|
|
147
147
|
|
|
148
148
|
const jsenvPluginMoveToBuildDirectory = {
|
|
@@ -338,7 +338,7 @@ export const createBuildSpecifierManager = ({
|
|
|
338
338
|
|
|
339
339
|
const versionMap = new Map();
|
|
340
340
|
|
|
341
|
-
const
|
|
341
|
+
const referenceInSeparateContextSet = new Set();
|
|
342
342
|
const referenceVersioningInfoMap = new Map();
|
|
343
343
|
const _getReferenceVersioningInfo = (reference) => {
|
|
344
344
|
if (!shouldApplyVersioningOnReference(reference)) {
|
|
@@ -395,7 +395,7 @@ export const createBuildSpecifierManager = ({
|
|
|
395
395
|
},
|
|
396
396
|
};
|
|
397
397
|
}
|
|
398
|
-
if (canUseImportmap && !
|
|
398
|
+
if (canUseImportmap && !isInsideSeparateContext(reference)) {
|
|
399
399
|
return {
|
|
400
400
|
type: "importmap",
|
|
401
401
|
render: (buildSpecifier) => {
|
|
@@ -422,8 +422,8 @@ export const createBuildSpecifierManager = ({
|
|
|
422
422
|
referenceVersioningInfoMap.set(reference, info);
|
|
423
423
|
return info;
|
|
424
424
|
};
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
425
|
+
const isInsideSeparateContext = (reference) => {
|
|
426
|
+
if (referenceInSeparateContextSet.has(reference)) {
|
|
427
427
|
return true;
|
|
428
428
|
}
|
|
429
429
|
const referenceOwnerUrllInfo = reference.ownerUrlInfo;
|
|
@@ -443,7 +443,7 @@ export const createBuildSpecifierManager = ({
|
|
|
443
443
|
);
|
|
444
444
|
}
|
|
445
445
|
if (is) {
|
|
446
|
-
|
|
446
|
+
referenceInSeparateContextSet.add(reference);
|
|
447
447
|
return true;
|
|
448
448
|
}
|
|
449
449
|
return false;
|
|
@@ -646,6 +646,9 @@ export const createBuildSpecifierManager = ({
|
|
|
646
646
|
}
|
|
647
647
|
};
|
|
648
648
|
|
|
649
|
+
const importMappings = {};
|
|
650
|
+
const globalMappings = {};
|
|
651
|
+
|
|
649
652
|
const applyVersioningOnBuildSpecifier = (buildSpecifier, reference) => {
|
|
650
653
|
if (!versioning) {
|
|
651
654
|
return buildSpecifier;
|
|
@@ -671,10 +674,6 @@ export const createBuildSpecifierManager = ({
|
|
|
671
674
|
};
|
|
672
675
|
const finishVersioning = async () => {
|
|
673
676
|
inject_global_registry_and_importmap: {
|
|
674
|
-
const actions = [];
|
|
675
|
-
const visitors = [];
|
|
676
|
-
const globalMappings = {};
|
|
677
|
-
const importmapMappings = {};
|
|
678
677
|
for (const [reference, versioningInfo] of referenceVersioningInfoMap) {
|
|
679
678
|
if (versioningInfo.type === "global") {
|
|
680
679
|
const urlInfo = reference.urlInfo;
|
|
@@ -690,37 +689,7 @@ export const createBuildSpecifierManager = ({
|
|
|
690
689
|
const buildSpecifier = buildUrlToBuildSpecifierMap.get(buildUrl);
|
|
691
690
|
const buildSpecifierVersioned =
|
|
692
691
|
buildSpecifierToBuildSpecifierVersionedMap.get(buildSpecifier);
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
if (Object.keys(globalMappings).length > 0) {
|
|
697
|
-
visitors.push((urlInfo) => {
|
|
698
|
-
if (urlInfo.isEntryPoint) {
|
|
699
|
-
actions.push(async () => {
|
|
700
|
-
await injectVersionMappingsAsGlobal(urlInfo, globalMappings);
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
}
|
|
705
|
-
if (Object.keys(importmapMappings).length > 0) {
|
|
706
|
-
visitors.push((urlInfo) => {
|
|
707
|
-
if (urlInfo.type === "html" && urlInfo.isEntryPoint) {
|
|
708
|
-
actions.push(async () => {
|
|
709
|
-
await injectVersionMappingsAsImportmap(
|
|
710
|
-
urlInfo,
|
|
711
|
-
importmapMappings,
|
|
712
|
-
);
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
if (visitors.length) {
|
|
718
|
-
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
719
|
-
if (urlInfo.isRoot) return;
|
|
720
|
-
visitors.forEach((visitor) => visitor(urlInfo));
|
|
721
|
-
});
|
|
722
|
-
if (actions.length) {
|
|
723
|
-
await Promise.all(actions.map((action) => action()));
|
|
692
|
+
importMappings[buildSpecifier] = buildSpecifierVersioned;
|
|
724
693
|
}
|
|
725
694
|
}
|
|
726
695
|
}
|
|
@@ -751,7 +720,6 @@ export const createBuildSpecifierManager = ({
|
|
|
751
720
|
if (versioning) {
|
|
752
721
|
prepareVersioning();
|
|
753
722
|
}
|
|
754
|
-
|
|
755
723
|
const urlInfoSet = new Set();
|
|
756
724
|
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
757
725
|
finalKitchen.graph.rootUrlInfo,
|
|
@@ -788,11 +756,73 @@ export const createBuildSpecifierManager = ({
|
|
|
788
756
|
}
|
|
789
757
|
},
|
|
790
758
|
);
|
|
791
|
-
|
|
792
|
-
workerReferenceSet.clear();
|
|
759
|
+
referenceInSeparateContextSet.clear();
|
|
793
760
|
if (versioning) {
|
|
794
761
|
await finishVersioning();
|
|
795
762
|
}
|
|
763
|
+
const actions = [];
|
|
764
|
+
const visitors = [];
|
|
765
|
+
if (Object.keys(globalMappings).length > 0) {
|
|
766
|
+
visitors.push((urlInfo) => {
|
|
767
|
+
if (urlInfo.isRoot) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
if (!urlInfo.isEntryPoint) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
actions.push(async () => {
|
|
774
|
+
await injectGlobalMappings(urlInfo, globalMappings);
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
sync_importmap: {
|
|
779
|
+
visitors.push((urlInfo) => {
|
|
780
|
+
if (urlInfo.isRoot) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
if (!urlInfo.isEntryPoint) {
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (urlInfo.type !== "html") {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
actions.push(async () => {
|
|
791
|
+
await injectImportmapMappings(urlInfo, (topLevelMappings) => {
|
|
792
|
+
if (!topLevelMappings) {
|
|
793
|
+
return importMappings;
|
|
794
|
+
}
|
|
795
|
+
const topLevelMappingsToKeep = {};
|
|
796
|
+
for (const topLevelMappingKey of Object.keys(topLevelMappings)) {
|
|
797
|
+
const topLevelMappingValue =
|
|
798
|
+
topLevelMappings[topLevelMappingKey];
|
|
799
|
+
const urlInfo = finalKitchen.graph.getUrlInfo(
|
|
800
|
+
`ignore:${topLevelMappingKey}`,
|
|
801
|
+
);
|
|
802
|
+
if (urlInfo) {
|
|
803
|
+
topLevelMappingsToKeep[topLevelMappingKey] =
|
|
804
|
+
topLevelMappingValue;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return {
|
|
808
|
+
...topLevelMappingsToKeep,
|
|
809
|
+
...importMappings,
|
|
810
|
+
};
|
|
811
|
+
});
|
|
812
|
+
});
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (visitors.length) {
|
|
817
|
+
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
818
|
+
for (const visitor of visitors) {
|
|
819
|
+
visitor(urlInfo);
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
if (actions.length) {
|
|
823
|
+
await Promise.all(actions.map((action) => action()));
|
|
824
|
+
}
|
|
825
|
+
}
|
|
796
826
|
|
|
797
827
|
for (const urlInfo of urlInfoSet) {
|
|
798
828
|
urlInfo.kitchen.urlInfoTransformer.applySourcemapOnContent(
|
|
@@ -809,19 +839,9 @@ export const createBuildSpecifierManager = ({
|
|
|
809
839
|
urlInfoSet.clear();
|
|
810
840
|
},
|
|
811
841
|
|
|
812
|
-
prepareResyncResourceHints: () => {
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
if (urlInfo.type !== "html") {
|
|
816
|
-
return;
|
|
817
|
-
}
|
|
818
|
-
const htmlAst = parseHtml({
|
|
819
|
-
html: urlInfo.content,
|
|
820
|
-
url: urlInfo.url,
|
|
821
|
-
storeOriginalPositions: false,
|
|
822
|
-
});
|
|
823
|
-
const mutations = [];
|
|
824
|
-
const hintToInjectMap = new Map();
|
|
842
|
+
prepareResyncResourceHints: ({ registerHtmlRefine }) => {
|
|
843
|
+
const hintToInjectMap = new Map();
|
|
844
|
+
registerHtmlRefine((htmlAst, { registerHtmlMutation }) => {
|
|
825
845
|
visitHtmlNodes(htmlAst, {
|
|
826
846
|
link: (node) => {
|
|
827
847
|
const href = getHtmlNodeAttribute(node, "href");
|
|
@@ -846,7 +866,7 @@ export const createBuildSpecifierManager = ({
|
|
|
846
866
|
logger.warn(
|
|
847
867
|
`${UNICODE.WARNING} remove resource hint because cannot find "${href}" in the graph`,
|
|
848
868
|
);
|
|
849
|
-
|
|
869
|
+
registerHtmlMutation(() => {
|
|
850
870
|
removeHtmlNode(node);
|
|
851
871
|
});
|
|
852
872
|
return;
|
|
@@ -857,7 +877,7 @@ export const createBuildSpecifierManager = ({
|
|
|
857
877
|
logger.warn(
|
|
858
878
|
`${UNICODE.WARNING} remove resource hint on "${href}" because it was bundled`,
|
|
859
879
|
);
|
|
860
|
-
|
|
880
|
+
registerHtmlMutation(() => {
|
|
861
881
|
removeHtmlNode(node);
|
|
862
882
|
});
|
|
863
883
|
return;
|
|
@@ -865,13 +885,13 @@ export const createBuildSpecifierManager = ({
|
|
|
865
885
|
logger.warn(
|
|
866
886
|
`${UNICODE.WARNING} remove resource hint on "${href}" because it is not used anymore`,
|
|
867
887
|
);
|
|
868
|
-
|
|
888
|
+
registerHtmlMutation(() => {
|
|
869
889
|
removeHtmlNode(node);
|
|
870
890
|
});
|
|
871
891
|
return;
|
|
872
892
|
}
|
|
873
893
|
const buildGeneratedSpecifier = getBuildGeneratedSpecifier(urlInfo);
|
|
874
|
-
|
|
894
|
+
registerHtmlMutation(() => {
|
|
875
895
|
setHtmlNodeAttributes(node, {
|
|
876
896
|
href: buildGeneratedSpecifier,
|
|
877
897
|
...(urlInfo.type === "js_classic"
|
|
@@ -890,43 +910,31 @@ export const createBuildSpecifierManager = ({
|
|
|
890
910
|
}
|
|
891
911
|
},
|
|
892
912
|
});
|
|
893
|
-
|
|
894
|
-
const buildGeneratedSpecifier =
|
|
913
|
+
for (const [referencedUrlInfo, { node }] of hintToInjectMap) {
|
|
914
|
+
const buildGeneratedSpecifier =
|
|
915
|
+
getBuildGeneratedSpecifier(referencedUrlInfo);
|
|
895
916
|
const found = findHtmlNode(htmlAst, (htmlNode) => {
|
|
896
917
|
return (
|
|
897
918
|
htmlNode.nodeName === "link" &&
|
|
898
919
|
getHtmlNodeAttribute(htmlNode, "href") === buildGeneratedSpecifier
|
|
899
920
|
);
|
|
900
921
|
});
|
|
901
|
-
if (
|
|
902
|
-
|
|
903
|
-
const nodeToInsert = createHtmlNode({
|
|
904
|
-
tagName: "link",
|
|
905
|
-
rel: getHtmlNodeAttribute(node, "rel"),
|
|
906
|
-
href: buildGeneratedSpecifier,
|
|
907
|
-
as: getHtmlNodeAttribute(node, "as"),
|
|
908
|
-
type: getHtmlNodeAttribute(node, "type"),
|
|
909
|
-
crossorigin: getHtmlNodeAttribute(node, "crossorigin"),
|
|
910
|
-
});
|
|
911
|
-
insertHtmlNodeAfter(nodeToInsert, node);
|
|
912
|
-
});
|
|
922
|
+
if (found) {
|
|
923
|
+
continue;
|
|
913
924
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
925
|
+
registerHtmlMutation(() => {
|
|
926
|
+
const nodeToInsert = createHtmlNode({
|
|
927
|
+
tagName: "link",
|
|
928
|
+
rel: getHtmlNodeAttribute(node, "rel"),
|
|
929
|
+
href: buildGeneratedSpecifier,
|
|
930
|
+
as: getHtmlNodeAttribute(node, "as"),
|
|
931
|
+
type: getHtmlNodeAttribute(node, "type"),
|
|
932
|
+
crossorigin: getHtmlNodeAttribute(node, "crossorigin"),
|
|
920
933
|
});
|
|
934
|
+
insertHtmlNodeAfter(nodeToInsert, node);
|
|
921
935
|
});
|
|
922
936
|
}
|
|
923
937
|
});
|
|
924
|
-
if (actions.length === 0) {
|
|
925
|
-
return null;
|
|
926
|
-
}
|
|
927
|
-
return () => {
|
|
928
|
-
actions.map((resourceHintAction) => resourceHintAction());
|
|
929
|
-
};
|
|
930
938
|
},
|
|
931
939
|
|
|
932
940
|
prepareServiceWorkerUrlInjection: () => {
|
|
@@ -1071,7 +1079,8 @@ const findRawUrlInfoWhenInline = (reference, rawKitchen) => {
|
|
|
1071
1079
|
if (
|
|
1072
1080
|
inlineUrlSite.url === reference.ownerUrlInfo.url &&
|
|
1073
1081
|
inlineUrlSite.line === reference.specifierLine &&
|
|
1074
|
-
inlineUrlSite.column === reference.specifierColumn
|
|
1082
|
+
inlineUrlSite.column === reference.specifierColumn &&
|
|
1083
|
+
rawUrlInfoCandidate.contentType === reference.contentType
|
|
1075
1084
|
) {
|
|
1076
1085
|
return true;
|
|
1077
1086
|
}
|
|
@@ -2,23 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
createHtmlNode,
|
|
5
|
+
findHtmlNode,
|
|
6
|
+
getHtmlNodeAttribute,
|
|
7
|
+
getHtmlNodeText,
|
|
5
8
|
injectHtmlNodeAsEarlyAsPossible,
|
|
6
9
|
parseHtml,
|
|
10
|
+
removeHtmlNode,
|
|
11
|
+
setHtmlNodeText,
|
|
7
12
|
stringifyHtmlAst,
|
|
8
13
|
} from "@jsenv/ast";
|
|
9
14
|
|
|
10
15
|
import { isWebWorkerUrlInfo } from "@jsenv/core/src/kitchen/web_workers.js";
|
|
11
16
|
import { prependContent } from "../kitchen/prepend_content.js";
|
|
12
17
|
|
|
13
|
-
export const
|
|
14
|
-
urlInfo,
|
|
15
|
-
versionMappings,
|
|
16
|
-
) => {
|
|
18
|
+
export const injectGlobalMappings = async (urlInfo, mappings) => {
|
|
17
19
|
if (urlInfo.type === "html") {
|
|
18
20
|
const minification = Boolean(
|
|
19
21
|
urlInfo.context.getPluginMeta("willMinifyJsClassic"),
|
|
20
22
|
);
|
|
21
|
-
const content =
|
|
23
|
+
const content = generateClientCodeForMappings(mappings, {
|
|
22
24
|
globalName: "window",
|
|
23
25
|
minification,
|
|
24
26
|
});
|
|
@@ -29,7 +31,7 @@ export const injectVersionMappingsAsGlobal = async (
|
|
|
29
31
|
const minification = Boolean(
|
|
30
32
|
urlInfo.context.getPluginMeta("willMinifyJsClassic"),
|
|
31
33
|
);
|
|
32
|
-
const content =
|
|
34
|
+
const content = generateClientCodeForMappings(mappings, {
|
|
33
35
|
globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
|
|
34
36
|
minification,
|
|
35
37
|
});
|
|
@@ -38,7 +40,7 @@ export const injectVersionMappingsAsGlobal = async (
|
|
|
38
40
|
}
|
|
39
41
|
};
|
|
40
42
|
|
|
41
|
-
const
|
|
43
|
+
const generateClientCodeForMappings = (
|
|
42
44
|
versionMappings,
|
|
43
45
|
{ globalName, minification },
|
|
44
46
|
) => {
|
|
@@ -57,7 +59,7 @@ const generateClientCodeForVersionMappings = (
|
|
|
57
59
|
})();`;
|
|
58
60
|
};
|
|
59
61
|
|
|
60
|
-
export const
|
|
62
|
+
export const injectImportmapMappings = (urlInfo, getMappings) => {
|
|
61
63
|
const htmlAst = parseHtml({
|
|
62
64
|
html: urlInfo.content,
|
|
63
65
|
url: urlInfo.url,
|
|
@@ -69,20 +71,59 @@ export const injectVersionMappingsAsImportmap = (urlInfo, versionMappings) => {
|
|
|
69
71
|
const importmapMinification = Boolean(
|
|
70
72
|
urlInfo.context.getPluginMeta("willMinifyJson"),
|
|
71
73
|
);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
const importmapNode = findHtmlNode(htmlAst, (node) => {
|
|
75
|
+
return (
|
|
76
|
+
node.tagName === "script" &&
|
|
77
|
+
getHtmlNodeAttribute(node, "type") === "importmap"
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
const generateMappingText = (mappings) => {
|
|
81
|
+
if (importmapMinification) {
|
|
82
|
+
return JSON.stringify({ imports: mappings });
|
|
83
|
+
}
|
|
84
|
+
return JSON.stringify({ imports: mappings }, null, " ");
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const mutate = (mutation) => {
|
|
88
|
+
mutation();
|
|
89
|
+
urlInfo.mutateContent({
|
|
90
|
+
content: stringifyHtmlAst(htmlAst),
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
if (importmapNode) {
|
|
95
|
+
// we want to remove some mappings, override others, add eventually add new
|
|
96
|
+
const currentMappings = JSON.parse(getHtmlNodeText(importmapNode));
|
|
97
|
+
const mappings = getMappings(currentMappings.imports);
|
|
98
|
+
if (!mappings || Object.keys(mappings).length === 0) {
|
|
99
|
+
mutate(() => {
|
|
100
|
+
removeHtmlNode(importmapNode);
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
mutate(() => {
|
|
105
|
+
setHtmlNodeText(importmapNode, generateMappingText(mappings), {
|
|
106
|
+
indentation: "auto",
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const mappings = getMappings(null);
|
|
112
|
+
if (!mappings || Object.keys(mappings).length === 0) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
mutate(() => {
|
|
116
|
+
injectHtmlNodeAsEarlyAsPossible(
|
|
117
|
+
htmlAst,
|
|
118
|
+
createHtmlNode({
|
|
119
|
+
tagName: "script",
|
|
120
|
+
type: "importmap",
|
|
121
|
+
children: generateMappingText(getMappings(null)),
|
|
122
|
+
}),
|
|
123
|
+
"jsenv:versioning",
|
|
124
|
+
);
|
|
85
125
|
});
|
|
126
|
+
return;
|
|
86
127
|
};
|
|
87
128
|
|
|
88
129
|
const stringifyParams = (params, prefix = "") => {
|
|
@@ -17,7 +17,7 @@ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort";
|
|
|
17
17
|
import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
|
|
18
18
|
import { createLogger, createTaskLog } from "@jsenv/humanize";
|
|
19
19
|
import {
|
|
20
|
-
|
|
20
|
+
createFileSystemFetch,
|
|
21
21
|
jsenvAccessControlAllowedHeaders,
|
|
22
22
|
jsenvServiceCORS,
|
|
23
23
|
jsenvServiceErrorHandler,
|
|
@@ -36,6 +36,7 @@ export const startBuildServer = async ({
|
|
|
36
36
|
buildDirectoryUrl,
|
|
37
37
|
buildMainFilePath = "index.html",
|
|
38
38
|
port = 9779,
|
|
39
|
+
routes,
|
|
39
40
|
services = [],
|
|
40
41
|
acceptAnyIp,
|
|
41
42
|
hostname,
|
|
@@ -120,6 +121,7 @@ export const startBuildServer = async ({
|
|
|
120
121
|
port,
|
|
121
122
|
serverTiming: true,
|
|
122
123
|
requestWaitingMs: 60_000,
|
|
124
|
+
routes,
|
|
123
125
|
services: [
|
|
124
126
|
jsenvServiceCORS({
|
|
125
127
|
accessControlAllowRequestOrigin: true,
|
|
@@ -130,13 +132,10 @@ export const startBuildServer = async ({
|
|
|
130
132
|
timingAllowOrigin: true,
|
|
131
133
|
}),
|
|
132
134
|
...services,
|
|
133
|
-
{
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
buildMainFilePath,
|
|
138
|
-
}),
|
|
139
|
-
},
|
|
135
|
+
jsenvBuildFileService({
|
|
136
|
+
buildDirectoryUrl,
|
|
137
|
+
buildMainFilePath,
|
|
138
|
+
}),
|
|
140
139
|
jsenvServiceErrorHandler({
|
|
141
140
|
sendErrorDetails: true,
|
|
142
141
|
}),
|
|
@@ -160,35 +159,46 @@ export const startBuildServer = async ({
|
|
|
160
159
|
};
|
|
161
160
|
};
|
|
162
161
|
|
|
163
|
-
const
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
162
|
+
const jsenvBuildFileService = ({ buildDirectoryUrl, buildMainFilePath }) => {
|
|
163
|
+
return {
|
|
164
|
+
name: "jsenv:build_files",
|
|
165
|
+
routes: [
|
|
166
|
+
{
|
|
167
|
+
endpoint: "GET *",
|
|
168
|
+
description: "Serve static files.",
|
|
169
|
+
fetch: (request, helpers) => {
|
|
170
|
+
const urlIsVersioned = new URL(request.url).searchParams.has("v");
|
|
171
|
+
if (buildMainFilePath && request.resource === "/") {
|
|
172
|
+
request = {
|
|
173
|
+
...request,
|
|
174
|
+
resource: `/${buildMainFilePath}`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const urlObject = new URL(
|
|
178
|
+
request.resource.slice(1),
|
|
179
|
+
buildDirectoryUrl,
|
|
180
|
+
);
|
|
181
|
+
return createFileSystemFetch(buildDirectoryUrl, {
|
|
182
|
+
cacheControl: urlIsVersioned
|
|
183
|
+
? `private,max-age=${SECONDS_IN_30_DAYS},immutable`
|
|
184
|
+
: "private,max-age=0,must-revalidate",
|
|
185
|
+
etagEnabled: true,
|
|
186
|
+
compressionEnabled: true,
|
|
187
|
+
rootDirectoryUrl: buildDirectoryUrl,
|
|
188
|
+
canReadDirectory: true,
|
|
189
|
+
ENOENTFallback: () => {
|
|
190
|
+
if (
|
|
191
|
+
!urlToExtension(urlObject) &&
|
|
192
|
+
!urlToPathname(urlObject).endsWith("/")
|
|
193
|
+
) {
|
|
194
|
+
return new URL(buildMainFilePath, buildDirectoryUrl);
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
},
|
|
198
|
+
})(request, helpers);
|
|
199
|
+
},
|
|
190
200
|
},
|
|
191
|
-
|
|
201
|
+
],
|
|
192
202
|
};
|
|
193
203
|
};
|
|
194
204
|
|