Skip to content

Commit b7169a8

Browse files
committed
work
1 parent ee4cb50 commit b7169a8

21 files changed

Lines changed: 175 additions & 67 deletions

File tree

dist/build/build.js

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ ${reason}`,
333333
}
334334
return createFailedToResolveUrlError({
335335
reason: `An error occured during specifier resolution`,
336+
...detailsFromInjectionsOnOwner(reference),
336337
...detailsFromValueThrown(error),
337338
});
338339
};
@@ -394,6 +395,7 @@ ${reason}`,
394395
return createFailedToFetchUrlContentError({
395396
code: "NOT_FOUND",
396397
reason: "no entry on filesystem",
398+
...detailsFromInjectionsOnOwner(urlInfo.firstReference),
397399
});
398400
}
399401
}
@@ -626,6 +628,32 @@ const getFirstReferenceInProject = (reference) => {
626628
return getFirstReferenceInProject(firstReference);
627629
};
628630

631+
// An url written by an injection cannot be resolved: the placeholder is still there
632+
// when references are analyzed. Rather than guessing what a placeholder looks like
633+
// (the key is free-form), tell the file it comes from: injections are configured for it.
634+
const detailsFromInjectionsOnOwner = (reference) => {
635+
if (!reference) {
636+
return {};
637+
}
638+
const ownerUrlInfo = reference.ownerUrlInfo;
639+
if (ownerUrlInfo.type !== "html") {
640+
// "jsenv-ignore" is an html attribute
641+
return {};
642+
}
643+
const { hasInjections } = ownerUrlInfo.context;
644+
if (!hasInjections || !hasInjections(ownerUrlInfo.url)) {
645+
return {};
646+
}
647+
const { node, attributeName } = reference.astInfo || {};
648+
if (!node || !attributeName) {
649+
return {};
650+
}
651+
return {
652+
suggestion: `injections are configured for this file; when "${reference.specifier}" is meant to be written by one of them, add "jsenv-ignore" so jsenv leaves that url alone:
653+
<${node.nodeName} jsenv-ignore ${attributeName}="${reference.specifier}" />`,
654+
};
655+
};
656+
629657
const detailsFromPluginController = (jsenvPluginsController) => {
630658
const currentPlugin = jsenvPluginsController.getCurrentPlugin();
631659
if (!currentPlugin) {
@@ -2511,7 +2539,14 @@ const injectGlobals = (content, globals, urlInfo) => {
25112539
if (urlInfo.type === "js_classic" || urlInfo.type === "js_module") {
25122540
return globalsInjectorOnJs(content, globals, urlInfo);
25132541
}
2514-
throw new Error(`cannot inject globals into "${urlInfo.type}"`);
2542+
throw new Error(
2543+
createDetailedMessage(`cannot inject globals into "${urlInfo.type}"`, {
2544+
file: urlInfo.url,
2545+
...(urlInfo.isInline
2546+
? { "inline content of": urlInfo.inlineUrlSite.url }
2547+
: {}),
2548+
}),
2549+
);
25152550
};
25162551
const globalInjectorOnHtml = (content, globals, urlInfo) => {
25172552
// ideally we would inject an importmap but browser support is too low
@@ -7652,11 +7687,20 @@ const jsenvPluginInjections = (rawAssociations) => {
76527687
{ injectionsGetter: rawAssociations },
76537688
context.rootDirectoryUrl,
76547689
);
7655-
const findInjectionsGetter = (urlInfo) => {
7690+
const findInjectionsGetterForUrl = (url) => {
76567691
const { injectionsGetter } = URL_META.applyAssociations({
7657-
url: asUrlWithoutSearch(urlInfo.url),
7692+
url: asUrlWithoutSearch(url),
76587693
associations: resolvedAssociations,
76597694
});
7695+
return injectionsGetter;
7696+
};
7697+
// an url written by an injection cannot be resolved during reference analysis;
7698+
// errors use this to tell the file holds injections and suggest "jsenv-ignore"
7699+
context.hasInjections = (url) => {
7700+
return Boolean(findInjectionsGetterForUrl(url));
7701+
};
7702+
const findInjectionsGetter = (urlInfo) => {
7703+
const injectionsGetter = findInjectionsGetterForUrl(urlInfo.url);
76607704
if (injectionsGetter) {
76617705
return { injectionsGetter, isInherited: false };
76627706
}
@@ -7688,9 +7732,7 @@ const jsenvPluginInjections = (rawAssociations) => {
76887732
if (!injections || !isInherited) {
76897733
return injections;
76907734
}
7691-
// the file holds several inline contents; a placeholder configured for the file
7692-
// is expected in one of them, not in each
7693-
return asOptionalInjections(injections);
7735+
return asInheritedInjections(injections);
76947736
};
76957737
}
76967738
},
@@ -7717,12 +7759,24 @@ const jsenvPluginInjections = (rawAssociations) => {
77177759
};
77187760
};
77197761

7720-
const asOptionalInjections = (injections) => {
7721-
const optionalInjections = {};
7762+
// What a file inlines (a <script> or a <style> inside html) is authored in that file
7763+
// and inherits its injections, with two adjustments:
7764+
// - a global belongs to the file itself, injecting it into each inline content would
7765+
// repeat it and reach types that cannot receive globals (css)
7766+
// - a placeholder configured for the file is expected in one of its inline contents,
7767+
// not in each, so a missing one is not worth a warning
7768+
const asInheritedInjections = (injections) => {
7769+
const inheritedInjections = {};
77227770
for (const key of Object.keys(injections)) {
7723-
optionalInjections[key] = INJECTIONS.optional(injections[key]);
7771+
const value = injections[key];
7772+
if (isPlaceholderInjection(value)) {
7773+
inheritedInjections[key] = INJECTIONS.optional(value);
7774+
}
7775+
}
7776+
if (Object.keys(inheritedInjections).length === 0) {
7777+
return null;
77247778
}
7725-
return optionalInjections;
7779+
return inheritedInjections;
77267780
};
77277781

77287782
/*

dist/client/html_syntax_error/html_syntax_error.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<body>
1010
<p>Syntax error: <strong>${reasonCode}</strong></p>
11-
<a jsenv-ignore="" href="${errorLinkHref}">${errorLinkText}</a>
11+
<a href="${errorLinkHref}">${errorLinkText}</a>
1212
${syntaxErrorHTML}
1313
</body>
1414
</html>

dist/start_dev_server/start_dev_server.js

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,6 +4563,7 @@ ${reason}`,
45634563
}
45644564
return createFailedToResolveUrlError({
45654565
reason: `An error occured during specifier resolution`,
4566+
...detailsFromInjectionsOnOwner(reference),
45664567
...detailsFromValueThrown(error),
45674568
});
45684569
};
@@ -4624,6 +4625,7 @@ ${reason}`,
46244625
return createFailedToFetchUrlContentError({
46254626
code: "NOT_FOUND",
46264627
reason: "no entry on filesystem",
4628+
...detailsFromInjectionsOnOwner(urlInfo.firstReference),
46274629
});
46284630
}
46294631
}
@@ -4856,6 +4858,32 @@ const getFirstReferenceInProject = (reference) => {
48564858
return getFirstReferenceInProject(firstReference);
48574859
};
48584860

4861+
// An url written by an injection cannot be resolved: the placeholder is still there
4862+
// when references are analyzed. Rather than guessing what a placeholder looks like
4863+
// (the key is free-form), tell the file it comes from: injections are configured for it.
4864+
const detailsFromInjectionsOnOwner = (reference) => {
4865+
if (!reference) {
4866+
return {};
4867+
}
4868+
const ownerUrlInfo = reference.ownerUrlInfo;
4869+
if (ownerUrlInfo.type !== "html") {
4870+
// "jsenv-ignore" is an html attribute
4871+
return {};
4872+
}
4873+
const { hasInjections } = ownerUrlInfo.context;
4874+
if (!hasInjections || !hasInjections(ownerUrlInfo.url)) {
4875+
return {};
4876+
}
4877+
const { node, attributeName } = reference.astInfo || {};
4878+
if (!node || !attributeName) {
4879+
return {};
4880+
}
4881+
return {
4882+
suggestion: `injections are configured for this file; when "${reference.specifier}" is meant to be written by one of them, add "jsenv-ignore" so jsenv leaves that url alone:
4883+
<${node.nodeName} jsenv-ignore ${attributeName}="${reference.specifier}" />`,
4884+
};
4885+
};
4886+
48594887
const detailsFromPluginController = (jsenvPluginsController) => {
48604888
const currentPlugin = jsenvPluginsController.getCurrentPlugin();
48614889
if (!currentPlugin) {
@@ -5145,7 +5173,14 @@ const injectGlobals = (content, globals, urlInfo) => {
51455173
if (urlInfo.type === "js_classic" || urlInfo.type === "js_module") {
51465174
return globalsInjectorOnJs(content, globals, urlInfo);
51475175
}
5148-
throw new Error(`cannot inject globals into "${urlInfo.type}"`);
5176+
throw new Error(
5177+
createDetailedMessage(`cannot inject globals into "${urlInfo.type}"`, {
5178+
file: urlInfo.url,
5179+
...(urlInfo.isInline
5180+
? { "inline content of": urlInfo.inlineUrlSite.url }
5181+
: {}),
5182+
}),
5183+
);
51495184
};
51505185
const globalInjectorOnHtml = (content, globals, urlInfo) => {
51515186
// ideally we would inject an importmap but browser support is too low
@@ -5211,11 +5246,20 @@ const jsenvPluginInjections = (rawAssociations) => {
52115246
{ injectionsGetter: rawAssociations },
52125247
context.rootDirectoryUrl,
52135248
);
5214-
const findInjectionsGetter = (urlInfo) => {
5249+
const findInjectionsGetterForUrl = (url) => {
52155250
const { injectionsGetter } = URL_META.applyAssociations({
5216-
url: asUrlWithoutSearch(urlInfo.url),
5251+
url: asUrlWithoutSearch(url),
52175252
associations: resolvedAssociations,
52185253
});
5254+
return injectionsGetter;
5255+
};
5256+
// an url written by an injection cannot be resolved during reference analysis;
5257+
// errors use this to tell the file holds injections and suggest "jsenv-ignore"
5258+
context.hasInjections = (url) => {
5259+
return Boolean(findInjectionsGetterForUrl(url));
5260+
};
5261+
const findInjectionsGetter = (urlInfo) => {
5262+
const injectionsGetter = findInjectionsGetterForUrl(urlInfo.url);
52195263
if (injectionsGetter) {
52205264
return { injectionsGetter, isInherited: false };
52215265
}
@@ -5247,9 +5291,7 @@ const jsenvPluginInjections = (rawAssociations) => {
52475291
if (!injections || !isInherited) {
52485292
return injections;
52495293
}
5250-
// the file holds several inline contents; a placeholder configured for the file
5251-
// is expected in one of them, not in each
5252-
return asOptionalInjections(injections);
5294+
return asInheritedInjections(injections);
52535295
};
52545296
}
52555297
},
@@ -5276,12 +5318,24 @@ const jsenvPluginInjections = (rawAssociations) => {
52765318
};
52775319
};
52785320

5279-
const asOptionalInjections = (injections) => {
5280-
const optionalInjections = {};
5321+
// What a file inlines (a <script> or a <style> inside html) is authored in that file
5322+
// and inherits its injections, with two adjustments:
5323+
// - a global belongs to the file itself, injecting it into each inline content would
5324+
// repeat it and reach types that cannot receive globals (css)
5325+
// - a placeholder configured for the file is expected in one of its inline contents,
5326+
// not in each, so a missing one is not worth a warning
5327+
const asInheritedInjections = (injections) => {
5328+
const inheritedInjections = {};
52815329
for (const key of Object.keys(injections)) {
5282-
optionalInjections[key] = INJECTIONS.optional(injections[key]);
5330+
const value = injections[key];
5331+
if (isPlaceholderInjection(value)) {
5332+
inheritedInjections[key] = INJECTIONS.optional(value);
5333+
}
5334+
}
5335+
if (Object.keys(inheritedInjections).length === 0) {
5336+
return null;
52835337
}
5284-
return optionalInjections;
5338+
return inheritedInjections;
52855339
};
52865340

52875341
const jsenvPluginInliningAsDataUrl = () => {

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/core",
3-
"version": "41.4.4",
3+
"version": "41.4.5",
44
"type": "module",
55
"description": "Tool to develop, test and build js projects",
66
"repository": {
@@ -72,12 +72,12 @@
7272
"test:snapshot_clear": "npx @jsenv/filesystem clear **/tests/**/side_effects/"
7373
},
7474
"dependencies": {
75-
"@jsenv/ast": "6.8.4",
76-
"@jsenv/js-module-fallback": "1.4.37",
75+
"@jsenv/ast": "6.8.5",
76+
"@jsenv/js-module-fallback": "1.4.38",
7777
"@jsenv/plugin-bundling": "2.10.16",
78-
"@jsenv/plugin-minification": "1.7.5",
79-
"@jsenv/plugin-supervisor": "1.8.8",
80-
"@jsenv/plugin-transpilation": "1.5.78",
78+
"@jsenv/plugin-minification": "1.7.6",
79+
"@jsenv/plugin-supervisor": "1.8.9",
80+
"@jsenv/plugin-transpilation": "1.5.79",
8181
"@jsenv/server": "17.6.0",
8282
"@jsenv/sourcemap": "1.4.2",
8383
"react-table": "7.8.0"

packages/internal/js-module-fallback/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/js-module-fallback",
3-
"version": "1.4.37",
3+
"version": "1.4.38",
44
"type": "module",
55
"repository": {
66
"type": "git",
@@ -32,7 +32,7 @@
3232
"@babel/plugin-transform-dynamic-import": "7.27.1",
3333
"@babel/plugin-transform-modules-systemjs": "7.29.7",
3434
"@babel/plugin-transform-modules-umd": "7.27.1",
35-
"@jsenv/ast": "6.8.4",
35+
"@jsenv/ast": "6.8.5",
3636
"@jsenv/sourcemap": "1.4.2",
3737
"@jsenv/urls": "2.9.10",
3838
"babel-plugin-transform-async-to-promises": "0.8.18"

packages/internal/plugin-minification/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/plugin-minification",
3-
"version": "1.7.5",
3+
"version": "1.7.6",
44
"type": "module",
55
"repository": {
66
"type": "git",
@@ -21,7 +21,7 @@
2121
"@jsenv/core": "*"
2222
},
2323
"dependencies": {
24-
"@jsenv/ast": "6.8.4",
24+
"@jsenv/ast": "6.8.5",
2525
"@jsenv/urls": "2.9.10",
2626
"html-minifier": "4.0.0",
2727
"lightningcss": "1.33.0",

packages/internal/plugin-supervisor/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/plugin-supervisor",
3-
"version": "1.8.8",
3+
"version": "1.8.9",
44
"type": "module",
55
"repository": {
66
"type": "git",
@@ -27,7 +27,7 @@
2727
"prepublishOnly": "npm run build"
2828
},
2929
"dependencies": {
30-
"@jsenv/ast": "6.8.4",
30+
"@jsenv/ast": "6.8.5",
3131
"@jsenv/sourcemap": "1.4.2"
3232
},
3333
"devDependencies": {

packages/internal/plugin-transpilation/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/plugin-transpilation",
3-
"version": "1.5.78",
3+
"version": "1.5.79",
44
"type": "module",
55
"description": "TODO",
66
"repository": {
@@ -48,8 +48,8 @@
4848
"@babel/plugin-transform-typeof-symbol": "7.27.1",
4949
"@babel/plugin-transform-unicode-property-regex": "7.28.6",
5050
"@babel/plugin-transform-unicode-regex": "7.27.1",
51-
"@jsenv/ast": "6.8.4",
52-
"@jsenv/js-module-fallback": "1.4.37",
51+
"@jsenv/ast": "6.8.5",
52+
"@jsenv/js-module-fallback": "1.4.38",
5353
"@jsenv/sourcemap": "1.4.2",
5454
"@jsenv/urls": "2.9.10",
5555
"@jsenv/utils": "2.3.1",

packages/related/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jsenv/cli",
3-
"version": "0.3.131",
3+
"version": "0.3.132",
44
"type": "module",
55
"description": "Command Line Interface for jsenv",
66
"repository": {

packages/related/cli/template-node-package/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
},
1414
"devDependencies": {
1515
"@jsenv/assert": "4.5.7",
16-
"@jsenv/core": "41.4.4",
16+
"@jsenv/core": "41.4.5",
1717
"@jsenv/eslint-config-relax": "1.8.9",
18-
"@jsenv/test": "3.7.29",
18+
"@jsenv/test": "3.7.30",
1919
"eslint": "9.39.2",
2020
"prettier": "3.9.6"
2121
}

0 commit comments

Comments
 (0)