@jsenv/core 38.4.16 → 38.4.17
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
CHANGED
|
@@ -13,7 +13,7 @@ import http from "node:http";
|
|
|
13
13
|
import { Readable, Stream, Writable } from "node:stream";
|
|
14
14
|
import { Http2ServerResponse } from "node:http2";
|
|
15
15
|
import { lookup } from "node:dns";
|
|
16
|
-
import { injectJsImport, visitJsAstUntil, applyBabelPlugins, parseHtml, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, getHtmlNodeText, stringifyHtmlAst, setHtmlNodeAttributes, parseJsUrls, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn, getHtmlNodePosition,
|
|
16
|
+
import { injectJsImport, visitJsAstUntil, applyBabelPlugins, parseHtml, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, getHtmlNodeText, stringifyHtmlAst, setHtmlNodeAttributes, parseJsUrls, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn, getHtmlNodePosition, getHtmlNodeAttributePosition, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, removeHtmlNode, parseCssUrls, getUrlForContentInsideJs, analyzeLinkNode, findHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
17
17
|
import { sourcemapConverter, createMagicSource, composeTwoSourcemaps, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
18
18
|
import { createRequire } from "node:module";
|
|
19
19
|
import { systemJsClientFileUrlDefault, convertJsModuleToJsClassic } from "@jsenv/js-module-fallback";
|
|
@@ -11528,13 +11528,14 @@ const createDependencies = (ownerUrlInfo) => {
|
|
|
11528
11528
|
const parentContent = isOriginalPosition
|
|
11529
11529
|
? ownerUrlInfo.originalContent
|
|
11530
11530
|
: ownerUrlInfo.content;
|
|
11531
|
+
const trace = traceFromUrlSite({
|
|
11532
|
+
url: parentUrl,
|
|
11533
|
+
content: parentContent,
|
|
11534
|
+
line: specifierLine,
|
|
11535
|
+
column: specifierColumn,
|
|
11536
|
+
});
|
|
11531
11537
|
const reference = createResolveAndFinalize({
|
|
11532
|
-
trace
|
|
11533
|
-
url: parentUrl,
|
|
11534
|
-
content: parentContent,
|
|
11535
|
-
line: specifierLine,
|
|
11536
|
-
column: specifierColumn,
|
|
11537
|
-
}),
|
|
11538
|
+
trace,
|
|
11538
11539
|
isOriginalPosition,
|
|
11539
11540
|
specifierLine,
|
|
11540
11541
|
specifierColumn,
|
|
@@ -13747,9 +13748,12 @@ const createTransformUrlContentError = ({
|
|
|
13747
13748
|
if (code === "PARSE_ERROR") {
|
|
13748
13749
|
transformError.reason = `parse error on ${urlInfo.type}`;
|
|
13749
13750
|
transformError.cause = error;
|
|
13751
|
+
let line = error.line;
|
|
13752
|
+
if (urlInfo.type === "js_module") {
|
|
13753
|
+
line = line - 1;
|
|
13754
|
+
}
|
|
13750
13755
|
if (urlInfo.isInline) {
|
|
13751
|
-
transformError.trace.line =
|
|
13752
|
-
urlInfo.firstReference.trace.line + error.line - 1;
|
|
13756
|
+
transformError.trace.line = urlInfo.firstReference.trace.line + line;
|
|
13753
13757
|
transformError.trace.column =
|
|
13754
13758
|
urlInfo.firstReference.trace.column + error.column;
|
|
13755
13759
|
transformError.trace.codeFrame = generateContentFrame({
|
|
@@ -13766,16 +13770,16 @@ const createTransformUrlContentError = ({
|
|
|
13766
13770
|
} else {
|
|
13767
13771
|
transformError.trace = {
|
|
13768
13772
|
url: urlInfo.url,
|
|
13769
|
-
line
|
|
13773
|
+
line,
|
|
13770
13774
|
column: error.column,
|
|
13771
13775
|
codeFrame: generateContentFrame({
|
|
13772
|
-
line
|
|
13776
|
+
line,
|
|
13773
13777
|
column: error.column,
|
|
13774
13778
|
content: urlInfo.content,
|
|
13775
13779
|
}),
|
|
13776
13780
|
message: stringifyUrlSite({
|
|
13777
13781
|
url: urlInfo.url,
|
|
13778
|
-
line
|
|
13782
|
+
line,
|
|
13779
13783
|
column: error.column,
|
|
13780
13784
|
content: urlInfo.content,
|
|
13781
13785
|
}),
|
|
@@ -15888,420 +15892,441 @@ const jsenvPluginHtmlReferenceAnalysis = ({
|
|
|
15888
15892
|
let importmapFound = false;
|
|
15889
15893
|
const importmapLoaded = startLoadingImportmap(urlInfo);
|
|
15890
15894
|
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
15895
|
+
try {
|
|
15896
|
+
const htmlAst = parseHtml({
|
|
15897
|
+
html: urlInfo.content,
|
|
15898
|
+
url: urlInfo.url,
|
|
15899
|
+
});
|
|
15895
15900
|
|
|
15896
|
-
|
|
15897
|
-
|
|
15898
|
-
|
|
15901
|
+
const mutations = [];
|
|
15902
|
+
const actions = [];
|
|
15903
|
+
const finalizeCallbacks = [];
|
|
15899
15904
|
|
|
15900
|
-
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
attributeValue,
|
|
15904
|
-
{ type, subtype, expectedType, ...rest },
|
|
15905
|
-
) => {
|
|
15906
|
-
let position;
|
|
15907
|
-
if (getHtmlNodeAttribute(node, "jsenv-cooked-by")) {
|
|
15908
|
-
// when generated from inline content,
|
|
15909
|
-
// line, column is not "src" nor "inlined-from-src" but "original-position"
|
|
15910
|
-
position = getHtmlNodePosition(node);
|
|
15911
|
-
} else {
|
|
15912
|
-
position = getHtmlNodeAttributePosition(node, attributeName);
|
|
15913
|
-
}
|
|
15914
|
-
const {
|
|
15915
|
-
line,
|
|
15916
|
-
column,
|
|
15917
|
-
// originalLine, originalColumn
|
|
15918
|
-
} = position;
|
|
15919
|
-
const debug = getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
|
|
15920
|
-
|
|
15921
|
-
const { crossorigin, integrity } = readFetchMetas(node);
|
|
15922
|
-
const isResourceHint = [
|
|
15923
|
-
"preconnect",
|
|
15924
|
-
"dns-prefetch",
|
|
15925
|
-
"prefetch",
|
|
15926
|
-
"preload",
|
|
15927
|
-
"modulepreload",
|
|
15928
|
-
].includes(subtype);
|
|
15929
|
-
let attributeLocation = node.sourceCodeLocation.attrs[attributeName];
|
|
15930
|
-
if (
|
|
15931
|
-
!attributeLocation &&
|
|
15932
|
-
attributeName === "href" &&
|
|
15933
|
-
(node.tagName === "use" || node.tagName === "image")
|
|
15934
|
-
) {
|
|
15935
|
-
attributeLocation = node.sourceCodeLocation.attrs["xlink:href"];
|
|
15936
|
-
}
|
|
15937
|
-
const attributeStart = attributeLocation.startOffset;
|
|
15938
|
-
const attributeValueStart = urlInfo.content.indexOf(
|
|
15905
|
+
const createExternalReference = (
|
|
15906
|
+
node,
|
|
15907
|
+
attributeName,
|
|
15939
15908
|
attributeValue,
|
|
15940
|
-
|
|
15941
|
-
)
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
15964
|
-
|
|
15909
|
+
{ type, subtype, expectedType, ...rest },
|
|
15910
|
+
) => {
|
|
15911
|
+
let position;
|
|
15912
|
+
if (getHtmlNodeAttribute(node, "jsenv-cooked-by")) {
|
|
15913
|
+
// when generated from inline content,
|
|
15914
|
+
// line, column is not "src" nor "inlined-from-src" but "original-position"
|
|
15915
|
+
position = getHtmlNodePosition(node);
|
|
15916
|
+
} else {
|
|
15917
|
+
position = getHtmlNodeAttributePosition(node, attributeName);
|
|
15918
|
+
}
|
|
15919
|
+
const {
|
|
15920
|
+
line,
|
|
15921
|
+
column,
|
|
15922
|
+
// originalLine, originalColumn
|
|
15923
|
+
} = position;
|
|
15924
|
+
const debug =
|
|
15925
|
+
getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
|
|
15926
|
+
|
|
15927
|
+
const { crossorigin, integrity } = readFetchMetas(node);
|
|
15928
|
+
const isResourceHint = [
|
|
15929
|
+
"preconnect",
|
|
15930
|
+
"dns-prefetch",
|
|
15931
|
+
"prefetch",
|
|
15932
|
+
"preload",
|
|
15933
|
+
"modulepreload",
|
|
15934
|
+
].includes(subtype);
|
|
15935
|
+
let attributeLocation =
|
|
15936
|
+
node.sourceCodeLocation.attrs[attributeName];
|
|
15937
|
+
if (
|
|
15938
|
+
!attributeLocation &&
|
|
15939
|
+
attributeName === "href" &&
|
|
15940
|
+
(node.tagName === "use" || node.tagName === "image")
|
|
15941
|
+
) {
|
|
15942
|
+
attributeLocation = node.sourceCodeLocation.attrs["xlink:href"];
|
|
15943
|
+
}
|
|
15944
|
+
const attributeStart = attributeLocation.startOffset;
|
|
15945
|
+
const attributeValueStart = urlInfo.content.indexOf(
|
|
15946
|
+
attributeValue,
|
|
15947
|
+
attributeStart + `${attributeName}=`.length,
|
|
15948
|
+
);
|
|
15949
|
+
const attributeValueEnd =
|
|
15950
|
+
attributeValueStart + attributeValue.length;
|
|
15951
|
+
const reference = urlInfo.dependencies.found({
|
|
15952
|
+
type,
|
|
15953
|
+
subtype,
|
|
15954
|
+
expectedType,
|
|
15955
|
+
specifier: attributeValue,
|
|
15956
|
+
specifierLine: line,
|
|
15957
|
+
specifierColumn: column,
|
|
15958
|
+
specifierStart: attributeValueStart,
|
|
15959
|
+
specifierEnd: attributeValueEnd,
|
|
15960
|
+
isResourceHint,
|
|
15961
|
+
isWeak: isResourceHint,
|
|
15962
|
+
crossorigin,
|
|
15963
|
+
integrity,
|
|
15964
|
+
debug,
|
|
15965
|
+
astInfo: { node, attributeName },
|
|
15966
|
+
...rest,
|
|
15967
|
+
});
|
|
15968
|
+
actions.push(async () => {
|
|
15969
|
+
await reference.readGeneratedSpecifier();
|
|
15970
|
+
mutations.push(() => {
|
|
15971
|
+
setHtmlNodeAttributes(node, {
|
|
15972
|
+
[attributeName]: reference.generatedSpecifier,
|
|
15973
|
+
});
|
|
15965
15974
|
});
|
|
15966
15975
|
});
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
if (href) {
|
|
15973
|
-
return createExternalReference(node, "href", href, referenceProps);
|
|
15974
|
-
}
|
|
15975
|
-
return null;
|
|
15976
|
-
};
|
|
15977
|
-
const visitSrc = (node, referenceProps) => {
|
|
15978
|
-
const src = getHtmlNodeAttribute(node, "src");
|
|
15979
|
-
if (src) {
|
|
15980
|
-
return createExternalReference(node, "src", src, referenceProps);
|
|
15981
|
-
}
|
|
15982
|
-
return null;
|
|
15983
|
-
};
|
|
15984
|
-
const visitSrcset = (node, referenceProps) => {
|
|
15985
|
-
const srcset = getHtmlNodeAttribute(node, "srcset");
|
|
15986
|
-
if (srcset) {
|
|
15987
|
-
const srcCandidates = parseSrcSet(srcset);
|
|
15988
|
-
return srcCandidates.map((srcCandidate) => {
|
|
15976
|
+
return reference;
|
|
15977
|
+
};
|
|
15978
|
+
const visitHref = (node, referenceProps) => {
|
|
15979
|
+
const href = getHtmlNodeAttribute(node, "href");
|
|
15980
|
+
if (href) {
|
|
15989
15981
|
return createExternalReference(
|
|
15990
15982
|
node,
|
|
15991
|
-
"
|
|
15992
|
-
|
|
15983
|
+
"href",
|
|
15984
|
+
href,
|
|
15993
15985
|
referenceProps,
|
|
15994
15986
|
);
|
|
15987
|
+
}
|
|
15988
|
+
return null;
|
|
15989
|
+
};
|
|
15990
|
+
const visitSrc = (node, referenceProps) => {
|
|
15991
|
+
const src = getHtmlNodeAttribute(node, "src");
|
|
15992
|
+
if (src) {
|
|
15993
|
+
return createExternalReference(node, "src", src, referenceProps);
|
|
15994
|
+
}
|
|
15995
|
+
return null;
|
|
15996
|
+
};
|
|
15997
|
+
const visitSrcset = (node, referenceProps) => {
|
|
15998
|
+
const srcset = getHtmlNodeAttribute(node, "srcset");
|
|
15999
|
+
if (srcset) {
|
|
16000
|
+
const srcCandidates = parseSrcSet(srcset);
|
|
16001
|
+
return srcCandidates.map((srcCandidate) => {
|
|
16002
|
+
return createExternalReference(
|
|
16003
|
+
node,
|
|
16004
|
+
"srcset",
|
|
16005
|
+
srcCandidate.specifier,
|
|
16006
|
+
referenceProps,
|
|
16007
|
+
);
|
|
16008
|
+
});
|
|
16009
|
+
}
|
|
16010
|
+
return null;
|
|
16011
|
+
};
|
|
16012
|
+
const createInlineReference = (
|
|
16013
|
+
node,
|
|
16014
|
+
inlineContent,
|
|
16015
|
+
{ type, expectedType, contentType },
|
|
16016
|
+
) => {
|
|
16017
|
+
const hotAccept =
|
|
16018
|
+
getHtmlNodeAttribute(node, "hot-accept") !== undefined;
|
|
16019
|
+
const { line, column, isOriginal } = getHtmlNodePosition(node, {
|
|
16020
|
+
preferOriginal: true,
|
|
15995
16021
|
});
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
};
|
|
15999
|
-
|
|
16000
|
-
const createInlineReference = (
|
|
16001
|
-
node,
|
|
16002
|
-
inlineContent,
|
|
16003
|
-
{ type, expectedType, contentType },
|
|
16004
|
-
) => {
|
|
16005
|
-
const hotAccept =
|
|
16006
|
-
getHtmlNodeAttribute(node, "hot-accept") !== undefined;
|
|
16007
|
-
const { line, column, isOriginal } = getHtmlNodePosition(node, {
|
|
16008
|
-
preferOriginal: true,
|
|
16009
|
-
});
|
|
16010
|
-
const inlineContentUrl = getUrlForContentInsideHtml(node, {
|
|
16011
|
-
htmlUrl: urlInfo.url,
|
|
16012
|
-
});
|
|
16013
|
-
const debug = getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
|
|
16014
|
-
const inlineReference = urlInfo.dependencies.foundInline({
|
|
16015
|
-
type,
|
|
16016
|
-
expectedType,
|
|
16017
|
-
isOriginalPosition: isOriginal,
|
|
16018
|
-
// we remove 1 to the line because imagine the following html:
|
|
16019
|
-
// <style>body { color: red; }</style>
|
|
16020
|
-
// -> content starts same line as <style> (same for <script>)
|
|
16021
|
-
specifierLine: line - 1,
|
|
16022
|
-
specifierColumn: column,
|
|
16023
|
-
specifier: inlineContentUrl,
|
|
16024
|
-
contentType,
|
|
16025
|
-
content: inlineContent,
|
|
16026
|
-
debug,
|
|
16027
|
-
astInfo: { node },
|
|
16028
|
-
});
|
|
16029
|
-
|
|
16030
|
-
actions.push(async () => {
|
|
16031
|
-
await inlineReference.urlInfo.cook();
|
|
16032
|
-
mutations.push(() => {
|
|
16033
|
-
if (hotAccept) {
|
|
16034
|
-
removeHtmlNodeText(node);
|
|
16035
|
-
setHtmlNodeAttributes(node, {
|
|
16036
|
-
"jsenv-cooked-by": "jsenv:html_inline_content_analysis",
|
|
16037
|
-
});
|
|
16038
|
-
} else {
|
|
16039
|
-
setHtmlNodeText(node, inlineReference.urlInfo.content, {
|
|
16040
|
-
indentation: false, // indentation would decrease stack trace precision
|
|
16041
|
-
});
|
|
16042
|
-
setHtmlNodeAttributes(node, {
|
|
16043
|
-
"jsenv-cooked-by": "jsenv:html_inline_content_analysis",
|
|
16044
|
-
});
|
|
16045
|
-
}
|
|
16022
|
+
const inlineContentUrl = getUrlForContentInsideHtml(node, {
|
|
16023
|
+
htmlUrl: urlInfo.url,
|
|
16046
16024
|
});
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
|
|
16053
|
-
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16059
|
-
|
|
16060
|
-
|
|
16061
|
-
|
|
16062
|
-
|
|
16063
|
-
});
|
|
16064
|
-
};
|
|
16065
|
-
|
|
16066
|
-
visitHtmlNodes(htmlAst, {
|
|
16067
|
-
link: (linkNode) => {
|
|
16068
|
-
const rel = getHtmlNodeAttribute(linkNode, "rel");
|
|
16069
|
-
const type = getHtmlNodeAttribute(linkNode, "type");
|
|
16070
|
-
const ref = visitHref(linkNode, {
|
|
16071
|
-
type: "link_href",
|
|
16072
|
-
subtype: rel,
|
|
16073
|
-
// https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#including_a_mime_type
|
|
16074
|
-
expectedContentType: type,
|
|
16025
|
+
const debug =
|
|
16026
|
+
getHtmlNodeAttribute(node, "jsenv-debug") !== undefined;
|
|
16027
|
+
const inlineReference = urlInfo.dependencies.foundInline({
|
|
16028
|
+
type,
|
|
16029
|
+
expectedType,
|
|
16030
|
+
isOriginalPosition: isOriginal,
|
|
16031
|
+
// we remove 1 to the line because imagine the following html:
|
|
16032
|
+
// <style>body { color: red; }</style>
|
|
16033
|
+
// -> content starts same line as <style> (same for <script>)
|
|
16034
|
+
specifierLine: line - 1,
|
|
16035
|
+
specifierColumn: column,
|
|
16036
|
+
specifier: inlineContentUrl,
|
|
16037
|
+
contentType,
|
|
16038
|
+
content: inlineContent,
|
|
16039
|
+
debug,
|
|
16040
|
+
astInfo: { node },
|
|
16075
16041
|
});
|
|
16076
|
-
|
|
16077
|
-
|
|
16078
|
-
|
|
16079
|
-
|
|
16042
|
+
|
|
16043
|
+
actions.push(async () => {
|
|
16044
|
+
await inlineReference.urlInfo.cook();
|
|
16045
|
+
mutations.push(() => {
|
|
16046
|
+
if (hotAccept) {
|
|
16047
|
+
removeHtmlNodeText(node);
|
|
16048
|
+
setHtmlNodeAttributes(node, {
|
|
16049
|
+
"jsenv-cooked-by": "jsenv:html_inline_content_analysis",
|
|
16050
|
+
});
|
|
16051
|
+
} else {
|
|
16052
|
+
setHtmlNodeText(node, inlineReference.urlInfo.content, {
|
|
16053
|
+
indentation: false, // indentation would decrease stack trace precision
|
|
16054
|
+
});
|
|
16055
|
+
setHtmlNodeAttributes(node, {
|
|
16056
|
+
"jsenv-cooked-by": "jsenv:html_inline_content_analysis",
|
|
16057
|
+
});
|
|
16080
16058
|
}
|
|
16081
16059
|
});
|
|
16060
|
+
});
|
|
16061
|
+
return inlineReference;
|
|
16062
|
+
};
|
|
16063
|
+
const visitTextContent = (
|
|
16064
|
+
node,
|
|
16065
|
+
{ type, subtype, expectedType, contentType },
|
|
16066
|
+
) => {
|
|
16067
|
+
const inlineContent = getHtmlNodeText(node);
|
|
16068
|
+
if (!inlineContent) {
|
|
16069
|
+
return null;
|
|
16082
16070
|
}
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16089
|
-
|
|
16071
|
+
return createInlineReference(node, inlineContent, {
|
|
16072
|
+
type,
|
|
16073
|
+
subtype,
|
|
16074
|
+
expectedType,
|
|
16075
|
+
contentType,
|
|
16076
|
+
});
|
|
16077
|
+
};
|
|
16078
|
+
|
|
16079
|
+
visitHtmlNodes(htmlAst, {
|
|
16080
|
+
link: (linkNode) => {
|
|
16081
|
+
const rel = getHtmlNodeAttribute(linkNode, "rel");
|
|
16082
|
+
const type = getHtmlNodeAttribute(linkNode, "type");
|
|
16083
|
+
const ref = visitHref(linkNode, {
|
|
16084
|
+
type: "link_href",
|
|
16085
|
+
subtype: rel,
|
|
16086
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#including_a_mime_type
|
|
16087
|
+
expectedContentType: type,
|
|
16088
|
+
});
|
|
16089
|
+
if (ref) {
|
|
16090
|
+
finalizeCallbacks.push(() => {
|
|
16091
|
+
if (ref.expectedType) {
|
|
16092
|
+
// might be set by other plugins, in that case respect it
|
|
16093
|
+
} else {
|
|
16094
|
+
ref.expectedType = decideLinkExpectedType(ref, urlInfo);
|
|
16095
|
+
}
|
|
16090
16096
|
});
|
|
16091
16097
|
}
|
|
16092
|
-
|
|
16093
|
-
|
|
16094
|
-
|
|
16095
|
-
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
return;
|
|
16100
|
-
}
|
|
16101
|
-
if (type === "importmap") {
|
|
16102
|
-
importmapFound = true;
|
|
16103
|
-
|
|
16104
|
-
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
16105
|
-
if (src) {
|
|
16106
|
-
// Browser would throw on remote importmap
|
|
16107
|
-
// and won't sent a request to the server for it
|
|
16108
|
-
// We must precook the importmap to know its content and inline it into the HTML
|
|
16109
|
-
const importmapReference = createExternalReference(
|
|
16110
|
-
scriptNode,
|
|
16111
|
-
"src",
|
|
16112
|
-
src,
|
|
16113
|
-
{
|
|
16114
|
-
type: "script",
|
|
16115
|
-
subtype: "importmap",
|
|
16116
|
-
expectedType: "importmap",
|
|
16117
|
-
},
|
|
16118
|
-
);
|
|
16119
|
-
const { line, column, isOriginal } = getHtmlNodePosition(
|
|
16120
|
-
scriptNode,
|
|
16121
|
-
{
|
|
16122
|
-
preferOriginal: true,
|
|
16123
|
-
},
|
|
16124
|
-
);
|
|
16125
|
-
const importmapInlineUrl = getUrlForContentInsideHtml(
|
|
16126
|
-
scriptNode,
|
|
16127
|
-
{
|
|
16128
|
-
htmlUrl: urlInfo.url,
|
|
16129
|
-
},
|
|
16130
|
-
);
|
|
16131
|
-
const importmapReferenceInlined = importmapReference.inline({
|
|
16132
|
-
line: line - 1,
|
|
16133
|
-
column,
|
|
16134
|
-
isOriginal,
|
|
16135
|
-
specifier: importmapInlineUrl,
|
|
16136
|
-
contentType: "application/importmap+json",
|
|
16137
|
-
});
|
|
16138
|
-
const importmapInlineUrlInfo =
|
|
16139
|
-
importmapReferenceInlined.urlInfo;
|
|
16140
|
-
actions.push(async () => {
|
|
16141
|
-
await importmapInlineUrlInfo.cook();
|
|
16142
|
-
importmapLoaded(importmapInlineUrlInfo);
|
|
16143
|
-
mutations.push(() => {
|
|
16144
|
-
setHtmlNodeText(
|
|
16145
|
-
scriptNode,
|
|
16146
|
-
importmapInlineUrlInfo.content,
|
|
16147
|
-
{
|
|
16148
|
-
indentation: "auto",
|
|
16149
|
-
},
|
|
16150
|
-
);
|
|
16151
|
-
setHtmlNodeAttributes(scriptNode, {
|
|
16152
|
-
"src": undefined,
|
|
16153
|
-
"jsenv-inlined-by": "jsenv:html_reference_analysis",
|
|
16154
|
-
"inlined-from-src": src,
|
|
16155
|
-
});
|
|
16098
|
+
},
|
|
16099
|
+
style: inlineContent
|
|
16100
|
+
? (styleNode) => {
|
|
16101
|
+
visitTextContent(styleNode, {
|
|
16102
|
+
type: "style",
|
|
16103
|
+
expectedType: "css",
|
|
16104
|
+
contentType: "text/css",
|
|
16156
16105
|
});
|
|
16157
|
-
}
|
|
16158
|
-
|
|
16159
|
-
|
|
16160
|
-
|
|
16161
|
-
|
|
16106
|
+
}
|
|
16107
|
+
: null,
|
|
16108
|
+
script: (scriptNode) => {
|
|
16109
|
+
const { type, subtype, contentType, extension } =
|
|
16110
|
+
analyzeScriptNode(scriptNode);
|
|
16111
|
+
if (type === "text") {
|
|
16112
|
+
// ignore <script type="whatever">foobar</script>
|
|
16113
|
+
// per HTML spec https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
|
|
16114
|
+
return;
|
|
16115
|
+
}
|
|
16116
|
+
if (type === "importmap") {
|
|
16117
|
+
importmapFound = true;
|
|
16118
|
+
|
|
16119
|
+
const src = getHtmlNodeAttribute(scriptNode, "src");
|
|
16120
|
+
if (src) {
|
|
16121
|
+
// Browser would throw on remote importmap
|
|
16122
|
+
// and won't sent a request to the server for it
|
|
16123
|
+
// We must precook the importmap to know its content and inline it into the HTML
|
|
16124
|
+
const importmapReference = createExternalReference(
|
|
16162
16125
|
scriptNode,
|
|
16163
|
-
|
|
16126
|
+
"src",
|
|
16127
|
+
src,
|
|
16164
16128
|
{
|
|
16165
16129
|
type: "script",
|
|
16130
|
+
subtype: "importmap",
|
|
16166
16131
|
expectedType: "importmap",
|
|
16167
|
-
contentType: "application/importmap+json",
|
|
16168
16132
|
},
|
|
16169
16133
|
);
|
|
16170
|
-
const
|
|
16134
|
+
const { line, column, isOriginal } = getHtmlNodePosition(
|
|
16135
|
+
scriptNode,
|
|
16136
|
+
{
|
|
16137
|
+
preferOriginal: true,
|
|
16138
|
+
},
|
|
16139
|
+
);
|
|
16140
|
+
const importmapInlineUrl = getUrlForContentInsideHtml(
|
|
16141
|
+
scriptNode,
|
|
16142
|
+
{
|
|
16143
|
+
htmlUrl: urlInfo.url,
|
|
16144
|
+
},
|
|
16145
|
+
);
|
|
16146
|
+
const importmapReferenceInlined = importmapReference.inline({
|
|
16147
|
+
line: line - 1,
|
|
16148
|
+
column,
|
|
16149
|
+
isOriginal,
|
|
16150
|
+
specifier: importmapInlineUrl,
|
|
16151
|
+
contentType: "application/importmap+json",
|
|
16152
|
+
});
|
|
16153
|
+
const importmapInlineUrlInfo =
|
|
16154
|
+
importmapReferenceInlined.urlInfo;
|
|
16171
16155
|
actions.push(async () => {
|
|
16172
|
-
|
|
16173
|
-
|
|
16156
|
+
try {
|
|
16157
|
+
await importmapInlineUrlInfo.cook();
|
|
16158
|
+
} finally {
|
|
16159
|
+
importmapLoaded(importmapInlineUrlInfo);
|
|
16160
|
+
}
|
|
16174
16161
|
mutations.push(() => {
|
|
16175
16162
|
setHtmlNodeText(
|
|
16176
16163
|
scriptNode,
|
|
16177
|
-
|
|
16164
|
+
importmapInlineUrlInfo.content,
|
|
16178
16165
|
{
|
|
16179
16166
|
indentation: "auto",
|
|
16180
16167
|
},
|
|
16181
16168
|
);
|
|
16182
16169
|
setHtmlNodeAttributes(scriptNode, {
|
|
16183
|
-
"
|
|
16170
|
+
"src": undefined,
|
|
16171
|
+
"jsenv-inlined-by": "jsenv:html_reference_analysis",
|
|
16172
|
+
"inlined-from-src": src,
|
|
16173
|
+
});
|
|
16174
|
+
});
|
|
16175
|
+
});
|
|
16176
|
+
} else {
|
|
16177
|
+
const htmlNodeText = getHtmlNodeText(scriptNode);
|
|
16178
|
+
if (htmlNodeText) {
|
|
16179
|
+
const importmapReference = createInlineReference(
|
|
16180
|
+
scriptNode,
|
|
16181
|
+
htmlNodeText,
|
|
16182
|
+
{
|
|
16183
|
+
type: "script",
|
|
16184
|
+
expectedType: "importmap",
|
|
16185
|
+
contentType: "application/importmap+json",
|
|
16186
|
+
},
|
|
16187
|
+
);
|
|
16188
|
+
const inlineImportmapUrlInfo = importmapReference.urlInfo;
|
|
16189
|
+
actions.push(async () => {
|
|
16190
|
+
try {
|
|
16191
|
+
await inlineImportmapUrlInfo.cook();
|
|
16192
|
+
} finally {
|
|
16193
|
+
importmapLoaded(inlineImportmapUrlInfo);
|
|
16194
|
+
}
|
|
16195
|
+
mutations.push(() => {
|
|
16196
|
+
setHtmlNodeText(
|
|
16197
|
+
scriptNode,
|
|
16198
|
+
inlineImportmapUrlInfo.content,
|
|
16199
|
+
{
|
|
16200
|
+
indentation: "auto",
|
|
16201
|
+
},
|
|
16202
|
+
);
|
|
16203
|
+
setHtmlNodeAttributes(scriptNode, {
|
|
16204
|
+
"jsenv-cooked-by": "jsenv:html_reference_analysis",
|
|
16205
|
+
});
|
|
16184
16206
|
});
|
|
16185
16207
|
});
|
|
16208
|
+
}
|
|
16209
|
+
}
|
|
16210
|
+
// once this plugin knows the importmap, it will use it
|
|
16211
|
+
// to map imports. These import specifiers will be normalized
|
|
16212
|
+
// by "formatReference" making the importmap presence useless.
|
|
16213
|
+
// In dev/test we keep importmap into the HTML to see it even if useless
|
|
16214
|
+
// Duing build we get rid of it
|
|
16215
|
+
if (urlInfo.context.build) {
|
|
16216
|
+
mutations.push(() => {
|
|
16217
|
+
removeHtmlNode(scriptNode);
|
|
16186
16218
|
});
|
|
16187
16219
|
}
|
|
16220
|
+
return;
|
|
16188
16221
|
}
|
|
16189
|
-
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16194
|
-
if (
|
|
16195
|
-
|
|
16196
|
-
removeHtmlNode(scriptNode);
|
|
16197
|
-
});
|
|
16222
|
+
const externalRef = visitSrc(scriptNode, {
|
|
16223
|
+
type: "script",
|
|
16224
|
+
subtype: type,
|
|
16225
|
+
expectedType: type,
|
|
16226
|
+
});
|
|
16227
|
+
if (externalRef) {
|
|
16228
|
+
return;
|
|
16198
16229
|
}
|
|
16199
|
-
return;
|
|
16200
|
-
}
|
|
16201
|
-
const externalRef = visitSrc(scriptNode, {
|
|
16202
|
-
type: "script",
|
|
16203
|
-
subtype: type,
|
|
16204
|
-
expectedType: type,
|
|
16205
|
-
});
|
|
16206
|
-
if (externalRef) {
|
|
16207
|
-
return;
|
|
16208
|
-
}
|
|
16209
16230
|
|
|
16210
|
-
|
|
16211
|
-
|
|
16212
|
-
|
|
16213
|
-
|
|
16214
|
-
|
|
16215
|
-
|
|
16216
|
-
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16231
|
+
// now visit the content, if any
|
|
16232
|
+
if (!inlineContent) {
|
|
16233
|
+
return;
|
|
16234
|
+
}
|
|
16235
|
+
// If the inline script was already handled by an other plugin, ignore it
|
|
16236
|
+
// - we want to preserve inline scripts generated by html supervisor during dev
|
|
16237
|
+
// - we want to avoid cooking twice a script during build
|
|
16238
|
+
if (
|
|
16239
|
+
!inlineConvertedScript &&
|
|
16240
|
+
getHtmlNodeAttribute(scriptNode, "jsenv-injected-by") ===
|
|
16241
|
+
"jsenv:js_module_fallback"
|
|
16242
|
+
) {
|
|
16243
|
+
return;
|
|
16244
|
+
}
|
|
16224
16245
|
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16246
|
+
const inlineRef = visitTextContent(scriptNode, {
|
|
16247
|
+
type: "script",
|
|
16248
|
+
subtype,
|
|
16249
|
+
expectedType: type,
|
|
16250
|
+
contentType,
|
|
16251
|
+
});
|
|
16252
|
+
if (inlineRef) {
|
|
16253
|
+
// 1. <script type="jsx"> becomes <script>
|
|
16254
|
+
if (type === "js_classic" && extension !== ".js") {
|
|
16255
|
+
mutations.push(() => {
|
|
16256
|
+
setHtmlNodeAttributes(scriptNode, {
|
|
16257
|
+
type: undefined,
|
|
16258
|
+
});
|
|
16237
16259
|
});
|
|
16238
|
-
}
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16243
|
-
|
|
16244
|
-
|
|
16260
|
+
}
|
|
16261
|
+
// 2. <script type="module/jsx"> becomes <script type="module">
|
|
16262
|
+
if (type === "js_module" && extension !== ".js") {
|
|
16263
|
+
mutations.push(() => {
|
|
16264
|
+
setHtmlNodeAttributes(scriptNode, {
|
|
16265
|
+
type: "module",
|
|
16266
|
+
});
|
|
16245
16267
|
});
|
|
16246
|
-
}
|
|
16268
|
+
}
|
|
16247
16269
|
}
|
|
16248
|
-
}
|
|
16249
|
-
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
}
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
}
|
|
16259
|
-
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
16264
|
-
|
|
16265
|
-
|
|
16266
|
-
}
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
|
|
16274
|
-
}
|
|
16275
|
-
|
|
16276
|
-
|
|
16277
|
-
|
|
16278
|
-
|
|
16279
|
-
|
|
16280
|
-
}
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
}
|
|
16286
|
-
}
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
});
|
|
16270
|
+
},
|
|
16271
|
+
a: (aNode) => {
|
|
16272
|
+
visitHref(aNode, {
|
|
16273
|
+
type: "a_href",
|
|
16274
|
+
});
|
|
16275
|
+
},
|
|
16276
|
+
iframe: (iframeNode) => {
|
|
16277
|
+
visitSrc(iframeNode, {
|
|
16278
|
+
type: "iframe_src",
|
|
16279
|
+
});
|
|
16280
|
+
},
|
|
16281
|
+
img: (imgNode) => {
|
|
16282
|
+
visitSrc(imgNode, {
|
|
16283
|
+
type: "img_src",
|
|
16284
|
+
});
|
|
16285
|
+
visitSrcset(imgNode, {
|
|
16286
|
+
type: "img_srcset",
|
|
16287
|
+
});
|
|
16288
|
+
},
|
|
16289
|
+
source: (sourceNode) => {
|
|
16290
|
+
visitSrc(sourceNode, {
|
|
16291
|
+
type: "source_src",
|
|
16292
|
+
});
|
|
16293
|
+
visitSrcset(sourceNode, {
|
|
16294
|
+
type: "source_srcset",
|
|
16295
|
+
});
|
|
16296
|
+
},
|
|
16297
|
+
// svg <image> tag
|
|
16298
|
+
image: (imageNode) => {
|
|
16299
|
+
visitHref(imageNode, {
|
|
16300
|
+
type: "image_href",
|
|
16301
|
+
});
|
|
16302
|
+
},
|
|
16303
|
+
use: (useNode) => {
|
|
16304
|
+
visitHref(useNode, {
|
|
16305
|
+
type: "use_href",
|
|
16306
|
+
});
|
|
16307
|
+
},
|
|
16308
|
+
});
|
|
16309
|
+
if (!importmapFound) {
|
|
16310
|
+
importmapLoaded();
|
|
16311
|
+
}
|
|
16312
|
+
finalizeCallbacks.forEach((finalizeCallback) => {
|
|
16313
|
+
finalizeCallback();
|
|
16314
|
+
});
|
|
16294
16315
|
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16298
|
-
|
|
16299
|
-
|
|
16300
|
-
|
|
16316
|
+
if (actions.length > 0) {
|
|
16317
|
+
await Promise.all(actions.map((action) => action()));
|
|
16318
|
+
actions.length = 0;
|
|
16319
|
+
}
|
|
16320
|
+
if (mutations.length === 0) {
|
|
16321
|
+
return null;
|
|
16322
|
+
}
|
|
16323
|
+
mutations.forEach((mutation) => mutation());
|
|
16324
|
+
mutations.length = 0;
|
|
16325
|
+
return stringifyHtmlAst(htmlAst);
|
|
16326
|
+
} catch (e) {
|
|
16327
|
+
importmapLoaded();
|
|
16328
|
+
throw e;
|
|
16301
16329
|
}
|
|
16302
|
-
mutations.forEach((mutation) => mutation());
|
|
16303
|
-
mutations.length = 0;
|
|
16304
|
-
return stringifyHtmlAst(htmlAst);
|
|
16305
16330
|
},
|
|
16306
16331
|
},
|
|
16307
16332
|
};
|
|
@@ -22302,6 +22327,9 @@ const startDevServer = async ({
|
|
|
22302
22327
|
sourceDirectoryUrl,
|
|
22303
22328
|
"sourceDirectoryUrl",
|
|
22304
22329
|
);
|
|
22330
|
+
if (!existsSync(new URL(sourceDirectoryUrl))) {
|
|
22331
|
+
throw new Error(`ENOENT on sourceDirectoryUrl at ${sourceDirectoryUrl}`);
|
|
22332
|
+
}
|
|
22305
22333
|
if (typeof sourceMainFilePath !== "string") {
|
|
22306
22334
|
throw new TypeError(
|
|
22307
22335
|
`sourceMainFilePath must be a string, got ${sourceMainFilePath}`,
|