@jsenv/core 41.4.5 → 41.4.7
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/build/build.js +202 -117
- package/dist/start_dev_server/start_dev_server.js +111 -52
- package/package.json +1 -1
- package/src/build/build.js +6 -18
- package/src/build/build_specifier_manager.js +49 -21
- package/src/build/build_urls_generator.js +43 -22
- package/src/dev/dev_server_plugins/dev_server_plugin_serve_source_files.js +10 -1
- package/src/helpers/bare_specifier.js +18 -0
- package/src/kitchen/errors.js +5 -4
- package/src/kitchen/url_graph/url_graph.js +3 -0
- package/src/kitchen/url_graph/url_info_injections.js +11 -4
- package/src/plugins/injections/jsenv_plugin_injections.js +53 -6
- package/src/plugins/plugins.js +3 -1
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +1 -17
- package/src/plugins/resolution_node_esm/node_esm_resolver.js +1 -17
- package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +7 -1
|
@@ -3,6 +3,7 @@ import { asUrlWithoutSearch, urlToRelativeUrl } from "@jsenv/urls";
|
|
|
3
3
|
import {
|
|
4
4
|
INJECTIONS,
|
|
5
5
|
isPlaceholderInjection,
|
|
6
|
+
readInjectionValue,
|
|
6
7
|
} from "../../kitchen/url_graph/url_info_injections.js";
|
|
7
8
|
|
|
8
9
|
export const jsenvPluginInjections = (rawAssociations) => {
|
|
@@ -18,6 +19,7 @@ export const jsenvPluginInjections = (rawAssociations) => {
|
|
|
18
19
|
}
|
|
19
20
|
return null;
|
|
20
21
|
};
|
|
22
|
+
const injectionsForUrlInfoMap = new WeakMap();
|
|
21
23
|
let getInjections = null;
|
|
22
24
|
|
|
23
25
|
return {
|
|
@@ -36,8 +38,8 @@ export const jsenvPluginInjections = (rawAssociations) => {
|
|
|
36
38
|
});
|
|
37
39
|
return injectionsGetter;
|
|
38
40
|
};
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
+
// errors and the build read this to know an unresolved url may come from
|
|
42
|
+
// an injection, and word what they report accordingly
|
|
41
43
|
context.hasInjections = (url) => {
|
|
42
44
|
return Boolean(findInjectionsGetterForUrl(url));
|
|
43
45
|
};
|
|
@@ -91,16 +93,61 @@ export const jsenvPluginInjections = (rawAssociations) => {
|
|
|
91
93
|
contentInjections: defaultInjections,
|
|
92
94
|
};
|
|
93
95
|
}
|
|
96
|
+
injectionsForUrlInfoMap.set(urlInfo, injections);
|
|
94
97
|
return {
|
|
95
|
-
contentInjections: {
|
|
96
|
-
...defaultInjections,
|
|
97
|
-
...injections,
|
|
98
|
-
},
|
|
98
|
+
contentInjections: { ...defaultInjections, ...injections },
|
|
99
99
|
};
|
|
100
100
|
},
|
|
101
|
+
// The content still holds the placeholders when references are analyzed: they are
|
|
102
|
+
// replaced at the very end, once the type of every inline content is known.
|
|
103
|
+
// A specifier must not wait for that, it would resolve "__BACKEND_URL__/users/me"
|
|
104
|
+
// as a file sitting next to the document. Only the placeholder is resolved here,
|
|
105
|
+
// then the specifier goes to whoever resolves this kind of url (node esm, web, ...)
|
|
106
|
+
resolveReference: (reference) => {
|
|
107
|
+
const { ownerUrlInfo } = reference;
|
|
108
|
+
const injections = injectionsForUrlInfoMap.get(ownerUrlInfo);
|
|
109
|
+
if (!injections) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const { specifier, keySet } = injectIntoSpecifier(
|
|
113
|
+
reference.specifier,
|
|
114
|
+
injections,
|
|
115
|
+
);
|
|
116
|
+
if (keySet.size === 0) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
reference.specifier = specifier;
|
|
120
|
+
for (const key of keySet) {
|
|
121
|
+
// rewriting the specifier takes the placeholder out of the content,
|
|
122
|
+
// so the injection step must not expect to find it there
|
|
123
|
+
ownerUrlInfo.contentInjectionUsedKeySet.add(key);
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
},
|
|
101
127
|
};
|
|
102
128
|
};
|
|
103
129
|
|
|
130
|
+
const injectIntoSpecifier = (specifier, injections) => {
|
|
131
|
+
let specifierInjected = specifier;
|
|
132
|
+
const keySet = new Set();
|
|
133
|
+
for (const key of Object.keys(injections)) {
|
|
134
|
+
if (!specifierInjected.includes(key)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const injection = injections[key];
|
|
138
|
+
if (!isPlaceholderInjection(injection)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const value = readInjectionValue(injection);
|
|
142
|
+
if (typeof value !== "string") {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
specifierInjected = specifierInjected.replaceAll(key, value);
|
|
146
|
+
keySet.add(key);
|
|
147
|
+
}
|
|
148
|
+
return { specifier: specifierInjected, keySet };
|
|
149
|
+
};
|
|
150
|
+
|
|
104
151
|
// What a file inlines (a <script> or a <style> inside html) is authored in that file
|
|
105
152
|
// and inherits its injections, with two adjustments:
|
|
106
153
|
// - a global belongs to the file itself, injecting it into each inline content would
|
package/src/plugins/plugins.js
CHANGED
|
@@ -87,8 +87,10 @@ export const getCorePlugins = ({
|
|
|
87
87
|
...(packageBundle
|
|
88
88
|
? [jsenvPluginWorkspaceBundle({ packageDirectory })]
|
|
89
89
|
: []),
|
|
90
|
-
|
|
90
|
+
// before reference analysis: an url written by an injection must hold its
|
|
91
|
+
// final value when references are analyzed
|
|
91
92
|
jsenvPluginInjections(injections),
|
|
93
|
+
jsenvPluginReferenceAnalysis(referenceAnalysis),
|
|
92
94
|
jsenvPluginTranspilation(transpilation),
|
|
93
95
|
// "jsenvPluginInlining" must be very soon because all other plugins will react differently once they see the file is inlined
|
|
94
96
|
...(inlining ? [jsenvPluginInlining()] : []),
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { createMagicSource } from "@jsenv/sourcemap";
|
|
7
7
|
import { urlToExtension } from "@jsenv/urls";
|
|
8
8
|
import { JS_QUOTES } from "@jsenv/utils/src/string/js_quotes.js";
|
|
9
|
+
import { isBareSpecifier } from "../../../helpers/bare_specifier.js";
|
|
9
10
|
|
|
10
11
|
export const jsenvPluginJsReferenceAnalysis = ({ inlineContent }) => {
|
|
11
12
|
return [
|
|
@@ -192,20 +193,3 @@ const parseAndTransformJsReferences = async (
|
|
|
192
193
|
const { content, sourcemap } = magicSource.toContentAndSourcemap();
|
|
193
194
|
return { content, sourcemap };
|
|
194
195
|
};
|
|
195
|
-
|
|
196
|
-
const isBareSpecifier = (specifier) => {
|
|
197
|
-
if (
|
|
198
|
-
specifier[0] === "/" ||
|
|
199
|
-
specifier.startsWith("./") ||
|
|
200
|
-
specifier.startsWith("../")
|
|
201
|
-
) {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
try {
|
|
205
|
-
// eslint-disable-next-line no-new
|
|
206
|
-
new URL(specifier);
|
|
207
|
-
return false;
|
|
208
|
-
} catch {
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
};
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { URL_META } from "@jsenv/url-meta";
|
|
15
15
|
import { urlToBasename, urlToExtension } from "@jsenv/urls";
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
|
+
import { isBareSpecifier } from "../../helpers/bare_specifier.js";
|
|
17
18
|
|
|
18
19
|
export const createNodeEsmResolver = ({
|
|
19
20
|
packageDirectory,
|
|
@@ -487,20 +488,3 @@ const createResolverWithFallbackOnError = (mainResolver, fallbackResolver) => {
|
|
|
487
488
|
}
|
|
488
489
|
};
|
|
489
490
|
};
|
|
490
|
-
|
|
491
|
-
const isBareSpecifier = (specifier) => {
|
|
492
|
-
if (
|
|
493
|
-
specifier[0] === "/" ||
|
|
494
|
-
specifier.startsWith("./") ||
|
|
495
|
-
specifier.startsWith("../")
|
|
496
|
-
) {
|
|
497
|
-
return false;
|
|
498
|
-
}
|
|
499
|
-
try {
|
|
500
|
-
// eslint-disable-next-line no-new
|
|
501
|
-
new URL(specifier);
|
|
502
|
-
return false;
|
|
503
|
-
} catch {
|
|
504
|
-
return true;
|
|
505
|
-
}
|
|
506
|
-
};
|
|
@@ -9,7 +9,13 @@ export const jsenvPluginWebResolution = () => {
|
|
|
9
9
|
if (ownerUrlInfo.originalUrl?.startsWith("http")) {
|
|
10
10
|
return new URL(resource, ownerUrlInfo.originalUrl);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
// "/x" is the web meaning of a root-relative url: the root of what is
|
|
13
|
+
// served, which is the source directory — not the directory the entry
|
|
14
|
+
// point happens to sit in.
|
|
15
|
+
const url = new URL(
|
|
16
|
+
resource.slice(1),
|
|
17
|
+
ownerUrlInfo.context.rootDirectoryUrl,
|
|
18
|
+
);
|
|
13
19
|
return url;
|
|
14
20
|
}
|
|
15
21
|
// baseUrl happens second argument to new URL() is different from
|