@jsenv/core 28.1.3 → 28.2.2
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/script_type_module_supervisor.js +8 -13
- package/dist/js/supervisor.js +690 -504
- package/dist/main.js +13332 -13179
- package/package.json +5 -5
- package/readme.md +3 -3
- package/src/build/build.js +980 -713
- package/src/build/inject_global_version_mappings.js +5 -20
- package/src/build/start_build_server.js +2 -2
- package/src/dev/start_dev_server.js +6 -3
- package/src/omega/compat/runtime_compat.js +9 -6
- package/src/omega/errors.js +3 -0
- package/src/omega/fetched_content_compliance.js +2 -2
- package/src/omega/kitchen.js +191 -146
- package/src/omega/server/file_service.js +104 -71
- package/src/omega/url_graph/url_graph_loader.js +77 -0
- package/src/omega/url_graph/url_info_transformations.js +12 -15
- package/src/omega/url_graph.js +118 -101
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +34 -36
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +3 -2
- package/src/plugins/bundling/js_module/{bundle_js_module.js → bundle_js_modules.js} +51 -14
- package/src/plugins/bundling/jsenv_plugin_bundling.js +2 -2
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +11 -0
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +73 -62
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +77 -89
- package/src/plugins/plugin_controller.js +26 -22
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +1 -0
- package/src/plugins/supervisor/client/script_type_module_supervisor.js +7 -9
- package/src/plugins/supervisor/client/supervisor.js +99 -52
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +2 -4
- package/src/plugins/transpilation/as_js_classic/async-to-promises.js +16 -0
- package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +85 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +48 -190
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +104 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +161 -240
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +92 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +19 -12
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -24
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +82 -52
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +12 -13
- package/src/plugins/url_analysis/html/html_urls.js +91 -34
- package/src/plugins/url_analysis/js/js_urls.js +5 -4
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +1 -0
- package/src/test/execute_plan.js +3 -8
- package/src/build/inject_service_worker_urls.js +0 -78
- package/src/build/resync_resource_hints.js +0 -112
- package/src/omega/url_graph/url_graph_load.js +0 -74
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* when {type: "module"} cannot be used on web workers:
|
|
3
|
+
* - new Worker("worker.js", { type: "module" })
|
|
4
|
+
* transformed into
|
|
5
|
+
* new Worker("worker.js?as_js_classic", { type: " lassic" })
|
|
6
|
+
* - navigator.serviceWorker.register("service_worker.js", { type: "module" })
|
|
7
|
+
* transformed into
|
|
8
|
+
* navigator.serviceWorker.register("service_worker.js?as_js_classic", { type: "classic" })
|
|
9
|
+
* - new SharedWorker("shared_worker.js", { type: "module" })
|
|
10
|
+
* transformed into
|
|
11
|
+
* new SharedWorker("shared_worker.js?as_js_classic", { type: "classic" })
|
|
12
|
+
*/
|
|
13
|
+
|
|
1
14
|
import { injectQueryParams } from "@jsenv/urls"
|
|
2
15
|
|
|
3
|
-
export const jsenvPluginAsJsClassicWorkers = ({
|
|
4
|
-
|
|
5
|
-
}) => {
|
|
6
|
-
const updateReference = (reference) => {
|
|
7
|
-
reference.filename = generateJsClassicFilename(reference.url)
|
|
16
|
+
export const jsenvPluginAsJsClassicWorkers = () => {
|
|
17
|
+
const turnIntoJsClassicProxy = (reference) => {
|
|
8
18
|
reference.mutation = (magicSource) => {
|
|
9
19
|
magicSource.replace({
|
|
10
20
|
start: reference.typePropertyNode.value.start,
|
|
@@ -12,10 +22,7 @@ export const jsenvPluginAsJsClassicWorkers = ({
|
|
|
12
22
|
replacement: JSON.stringify("classic"),
|
|
13
23
|
})
|
|
14
24
|
}
|
|
15
|
-
reference.
|
|
16
|
-
return injectQueryParams(reference.url, {
|
|
17
|
-
as_js_classic: "",
|
|
18
|
-
})
|
|
25
|
+
return injectQueryParams(reference.url, { as_js_classic: "" })
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
return {
|
|
@@ -30,7 +37,7 @@ export const jsenvPluginAsJsClassicWorkers = ({
|
|
|
30
37
|
if (context.isSupportedOnCurrentClients("worker_type_module")) {
|
|
31
38
|
return null
|
|
32
39
|
}
|
|
33
|
-
return
|
|
40
|
+
return turnIntoJsClassicProxy(reference)
|
|
34
41
|
}
|
|
35
42
|
if (reference.expectedSubtype === "service_worker") {
|
|
36
43
|
if (
|
|
@@ -38,7 +45,7 @@ export const jsenvPluginAsJsClassicWorkers = ({
|
|
|
38
45
|
) {
|
|
39
46
|
return null
|
|
40
47
|
}
|
|
41
|
-
return
|
|
48
|
+
return turnIntoJsClassicProxy(reference)
|
|
42
49
|
}
|
|
43
50
|
if (reference.expectedSubtype === "shared_worker") {
|
|
44
51
|
if (
|
|
@@ -46,7 +53,7 @@ export const jsenvPluginAsJsClassicWorkers = ({
|
|
|
46
53
|
) {
|
|
47
54
|
return null
|
|
48
55
|
}
|
|
49
|
-
return
|
|
56
|
+
return turnIntoJsClassicProxy(reference)
|
|
50
57
|
}
|
|
51
58
|
return null
|
|
52
59
|
},
|
|
@@ -15,31 +15,9 @@ export const jsenvPluginBabel = ({
|
|
|
15
15
|
} = {}) => {
|
|
16
16
|
const transformWithBabel = async (urlInfo, context) => {
|
|
17
17
|
const isJsModule = urlInfo.type === "js_module"
|
|
18
|
-
const isWorker = urlInfo.subtype === "worker"
|
|
19
|
-
const isServiceWorker = urlInfo.subtype === "service_worker"
|
|
20
|
-
const isSharedWorker = urlInfo.subtype === "shared_worker"
|
|
21
|
-
const isWorkerContext = isWorker || isServiceWorker || isSharedWorker
|
|
22
|
-
|
|
23
|
-
let { clientRuntimeCompat } = context
|
|
24
|
-
if (isWorker) {
|
|
25
|
-
clientRuntimeCompat = RUNTIME_COMPAT.add(clientRuntimeCompat, "worker")
|
|
26
|
-
} else if (isServiceWorker) {
|
|
27
|
-
// when code is executed by a service worker we can assume
|
|
28
|
-
// the execution context supports more than the default one
|
|
29
|
-
// for instance arrow function are supported
|
|
30
|
-
clientRuntimeCompat = RUNTIME_COMPAT.add(
|
|
31
|
-
clientRuntimeCompat,
|
|
32
|
-
"service_worker",
|
|
33
|
-
)
|
|
34
|
-
} else if (isSharedWorker) {
|
|
35
|
-
clientRuntimeCompat = RUNTIME_COMPAT.add(
|
|
36
|
-
clientRuntimeCompat,
|
|
37
|
-
"shared_worker",
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
18
|
|
|
41
19
|
const isSupported = (feature) =>
|
|
42
|
-
RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature)
|
|
20
|
+
RUNTIME_COMPAT.isSupported(context.clientRuntimeCompat, feature)
|
|
43
21
|
const getImportSpecifier = (clientFileUrl) => {
|
|
44
22
|
const [reference] = context.referenceUtils.inject({
|
|
45
23
|
type: "js_import_export",
|
|
@@ -52,7 +30,6 @@ export const jsenvPluginBabel = ({
|
|
|
52
30
|
const babelPluginStructure = getBaseBabelPluginStructure({
|
|
53
31
|
url: urlInfo.url,
|
|
54
32
|
isSupported,
|
|
55
|
-
isWorkerContext,
|
|
56
33
|
isJsModule,
|
|
57
34
|
getImportSpecifier,
|
|
58
35
|
})
|
|
@@ -19,9 +19,22 @@ export const jsenvPluginImportAssertions = ({
|
|
|
19
19
|
css = "auto",
|
|
20
20
|
text = "auto",
|
|
21
21
|
}) => {
|
|
22
|
-
const
|
|
22
|
+
const transpilations = { json, css, text }
|
|
23
|
+
const shouldTranspileImportAssertion = (context, type) => {
|
|
24
|
+
const transpilation = transpilations[type]
|
|
25
|
+
if (transpilation === true) {
|
|
26
|
+
return true
|
|
27
|
+
}
|
|
28
|
+
if (transpilation === "auto") {
|
|
29
|
+
return !context.isSupportedOnCurrentClients(`import_type_${type}`)
|
|
30
|
+
}
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
const markAsJsModuleProxy = (reference) => {
|
|
23
34
|
reference.expectedType = "js_module"
|
|
24
35
|
reference.filename = `${urlToFilename(reference.url)}.js`
|
|
36
|
+
}
|
|
37
|
+
const turnIntoJsModuleProxy = (reference, type) => {
|
|
25
38
|
reference.mutation = (magicSource) => {
|
|
26
39
|
magicSource.remove({
|
|
27
40
|
start: reference.assertNode.start,
|
|
@@ -29,8 +42,9 @@ export const jsenvPluginImportAssertions = ({
|
|
|
29
42
|
})
|
|
30
43
|
}
|
|
31
44
|
const newUrl = injectQueryParams(reference.url, {
|
|
32
|
-
[
|
|
45
|
+
[`as_${type}_module`]: "",
|
|
33
46
|
})
|
|
47
|
+
markAsJsModuleProxy(reference)
|
|
34
48
|
return newUrl
|
|
35
49
|
}
|
|
36
50
|
|
|
@@ -44,9 +58,9 @@ export const jsenvPluginImportAssertions = ({
|
|
|
44
58
|
// - means rollup can bundle more js file together
|
|
45
59
|
// - means url versioning can work for css inlined in js
|
|
46
60
|
if (context.scenarios.build) {
|
|
47
|
-
json = true
|
|
48
|
-
css = true
|
|
49
|
-
text = true
|
|
61
|
+
transpilations.json = true
|
|
62
|
+
transpilations.css = true
|
|
63
|
+
transpilations.text = true
|
|
50
64
|
}
|
|
51
65
|
},
|
|
52
66
|
redirectUrl: {
|
|
@@ -54,41 +68,18 @@ export const jsenvPluginImportAssertions = ({
|
|
|
54
68
|
if (!reference.assert) {
|
|
55
69
|
return null
|
|
56
70
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (shouldTranspileJsonImportAssertion) {
|
|
65
|
-
return updateReference(reference, "as_json_module")
|
|
66
|
-
}
|
|
71
|
+
const { searchParams } = reference
|
|
72
|
+
if (
|
|
73
|
+
searchParams.has("as_json_module") ||
|
|
74
|
+
searchParams.has("as_css_module") ||
|
|
75
|
+
searchParams.has("as_text_module")
|
|
76
|
+
) {
|
|
77
|
+
markAsJsModuleProxy(reference)
|
|
67
78
|
return null
|
|
68
79
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
? true
|
|
73
|
-
: css === "auto"
|
|
74
|
-
? !context.isSupportedOnCurrentClients("import_type_css")
|
|
75
|
-
: false
|
|
76
|
-
if (shouldTranspileCssImportAssertion) {
|
|
77
|
-
return updateReference(reference, "as_css_module")
|
|
78
|
-
}
|
|
79
|
-
return null
|
|
80
|
-
}
|
|
81
|
-
if (reference.assert.type === "text") {
|
|
82
|
-
const shouldTranspileTextImportAssertion =
|
|
83
|
-
text === true
|
|
84
|
-
? true
|
|
85
|
-
: text === "auto"
|
|
86
|
-
? !context.isSupportedOnCurrentClients("import_type_text")
|
|
87
|
-
: false
|
|
88
|
-
if (shouldTranspileTextImportAssertion) {
|
|
89
|
-
return updateReference(reference, "as_text_module")
|
|
90
|
-
}
|
|
91
|
-
return null
|
|
80
|
+
const type = reference.assert.type
|
|
81
|
+
if (shouldTranspileImportAssertion(context, type)) {
|
|
82
|
+
return turnIntoJsModuleProxy(reference, type)
|
|
92
83
|
}
|
|
93
84
|
return null
|
|
94
85
|
},
|
|
@@ -107,16 +98,29 @@ const jsenvPluginAsModules = () => {
|
|
|
107
98
|
name: `jsenv:as_json_module`,
|
|
108
99
|
appliesDuring: "*",
|
|
109
100
|
fetchUrlContent: async (urlInfo, context) => {
|
|
110
|
-
const
|
|
101
|
+
const [jsonReference, jsonUrlInfo] = context.getWithoutSearchParam({
|
|
111
102
|
urlInfo,
|
|
112
103
|
context,
|
|
113
104
|
searchParam: "as_json_module",
|
|
114
105
|
expectedType: "json",
|
|
115
106
|
})
|
|
116
|
-
if (!
|
|
107
|
+
if (!jsonReference) {
|
|
117
108
|
return null
|
|
118
109
|
}
|
|
119
|
-
|
|
110
|
+
await context.fetchUrlContent(jsonUrlInfo, {
|
|
111
|
+
reference: jsonReference,
|
|
112
|
+
})
|
|
113
|
+
if (context.scenarios.dev) {
|
|
114
|
+
context.referenceUtils.found({
|
|
115
|
+
type: "js_import_export",
|
|
116
|
+
subtype: jsonReference.subtype,
|
|
117
|
+
specifier: jsonReference.url,
|
|
118
|
+
expectedType: "js_module",
|
|
119
|
+
})
|
|
120
|
+
} else if (context.scenarios.build && jsonUrlInfo.dependents.size === 0) {
|
|
121
|
+
context.urlGraph.deleteUrlInfo(jsonUrlInfo.url)
|
|
122
|
+
}
|
|
123
|
+
const jsonText = JSON.stringify(jsonUrlInfo.content.trim())
|
|
120
124
|
return {
|
|
121
125
|
// here we could `export default ${jsonText}`:
|
|
122
126
|
// but js engine are optimized to recognize JSON.parse
|
|
@@ -124,8 +128,8 @@ const jsenvPluginAsModules = () => {
|
|
|
124
128
|
content: `export default JSON.parse(${jsonText})`,
|
|
125
129
|
contentType: "text/javascript",
|
|
126
130
|
type: "js_module",
|
|
127
|
-
originalUrl:
|
|
128
|
-
originalContent:
|
|
131
|
+
originalUrl: jsonUrlInfo.originalUrl,
|
|
132
|
+
originalContent: jsonUrlInfo.originalContent,
|
|
129
133
|
}
|
|
130
134
|
},
|
|
131
135
|
}
|
|
@@ -134,16 +138,29 @@ const jsenvPluginAsModules = () => {
|
|
|
134
138
|
name: `jsenv:as_css_module`,
|
|
135
139
|
appliesDuring: "*",
|
|
136
140
|
fetchUrlContent: async (urlInfo, context) => {
|
|
137
|
-
const
|
|
141
|
+
const [cssReference, cssUrlInfo] = context.getWithoutSearchParam({
|
|
138
142
|
urlInfo,
|
|
139
143
|
context,
|
|
140
144
|
searchParam: "as_css_module",
|
|
141
145
|
expectedType: "css",
|
|
142
146
|
})
|
|
143
|
-
if (!
|
|
147
|
+
if (!cssReference) {
|
|
144
148
|
return null
|
|
145
149
|
}
|
|
146
|
-
|
|
150
|
+
await context.fetchUrlContent(cssUrlInfo, {
|
|
151
|
+
reference: cssReference,
|
|
152
|
+
})
|
|
153
|
+
if (context.scenarios.dev) {
|
|
154
|
+
context.referenceUtils.found({
|
|
155
|
+
type: "js_import_export",
|
|
156
|
+
subtype: cssReference.subtype,
|
|
157
|
+
specifier: cssReference.url,
|
|
158
|
+
expectedType: "js_module",
|
|
159
|
+
})
|
|
160
|
+
} else if (context.scenarios.build && cssUrlInfo.dependents.size === 0) {
|
|
161
|
+
context.urlGraph.deleteUrlInfo(cssUrlInfo.url)
|
|
162
|
+
}
|
|
163
|
+
const cssText = JS_QUOTES.escapeSpecialChars(cssUrlInfo.content, {
|
|
147
164
|
// If template string is choosen and runtime do not support template literals
|
|
148
165
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
149
166
|
// and convert template strings into raw strings
|
|
@@ -160,8 +177,8 @@ const jsenvPluginAsModules = () => {
|
|
|
160
177
|
export default stylesheet`,
|
|
161
178
|
contentType: "text/javascript",
|
|
162
179
|
type: "js_module",
|
|
163
|
-
originalUrl:
|
|
164
|
-
originalContent:
|
|
180
|
+
originalUrl: cssUrlInfo.originalUrl,
|
|
181
|
+
originalContent: cssUrlInfo.originalContent,
|
|
165
182
|
}
|
|
166
183
|
},
|
|
167
184
|
}
|
|
@@ -170,15 +187,28 @@ const jsenvPluginAsModules = () => {
|
|
|
170
187
|
name: `jsenv:as_text_module`,
|
|
171
188
|
appliesDuring: "*",
|
|
172
189
|
fetchUrlContent: async (urlInfo, context) => {
|
|
173
|
-
const
|
|
190
|
+
const [textReference, textUrlInfo] = context.getWithoutSearchParam({
|
|
174
191
|
urlInfo,
|
|
175
192
|
context,
|
|
176
193
|
searchParam: "as_text_module",
|
|
177
194
|
expectedType: "text",
|
|
178
195
|
})
|
|
179
|
-
if (!
|
|
196
|
+
if (!textReference) {
|
|
180
197
|
return null
|
|
181
198
|
}
|
|
199
|
+
await context.fetchUrlContent(textUrlInfo, {
|
|
200
|
+
reference: textReference,
|
|
201
|
+
})
|
|
202
|
+
if (context.scenarios.dev) {
|
|
203
|
+
context.referenceUtils.found({
|
|
204
|
+
type: "js_import_export",
|
|
205
|
+
subtype: textReference.subtype,
|
|
206
|
+
specifier: textReference.url,
|
|
207
|
+
expectedType: "js_module",
|
|
208
|
+
})
|
|
209
|
+
} else if (context.scenarios.build && textUrlInfo.dependents.size === 0) {
|
|
210
|
+
context.urlGraph.deleteUrlInfo(textUrlInfo.url)
|
|
211
|
+
}
|
|
182
212
|
const textPlain = JS_QUOTES.escapeSpecialChars(urlInfo.content, {
|
|
183
213
|
// If template string is choosen and runtime do not support template literals
|
|
184
214
|
// it's ok because "jsenv:new_inline_content" plugin executes after this one
|
|
@@ -194,8 +224,8 @@ const inlineContent = new InlineContent(${textPlain}, { type: "text/plain" })
|
|
|
194
224
|
export default inlineContent.text`,
|
|
195
225
|
contentType: "text/javascript",
|
|
196
226
|
type: "js_module",
|
|
197
|
-
originalUrl:
|
|
198
|
-
originalContent:
|
|
227
|
+
originalUrl: textUrlInfo.originalUrl,
|
|
228
|
+
originalContent: textUrlInfo.originalContent,
|
|
199
229
|
}
|
|
200
230
|
},
|
|
201
231
|
}
|
|
@@ -16,7 +16,12 @@ import { jsenvPluginTopLevelAwait } from "./jsenv_plugin_top_level_await.js"
|
|
|
16
16
|
export const jsenvPluginTranspilation = ({
|
|
17
17
|
importAssertions = true,
|
|
18
18
|
css = true,
|
|
19
|
-
|
|
19
|
+
jsClassicLibrary = true,
|
|
20
|
+
// build sets jsClassicFallback: false during first step of the build
|
|
21
|
+
// and re-enable it in the second phase (when performing the bundling)
|
|
22
|
+
// so that bundling is applied on js modules THEN it is converted to js classic if needed
|
|
23
|
+
jsClassicFallback = true,
|
|
24
|
+
systemJsInjection = true,
|
|
20
25
|
topLevelAwait = true,
|
|
21
26
|
babelHelpersAsImport = true,
|
|
22
27
|
getCustomBabelPlugins,
|
|
@@ -24,11 +29,7 @@ export const jsenvPluginTranspilation = ({
|
|
|
24
29
|
if (importAssertions === true) {
|
|
25
30
|
importAssertions = {}
|
|
26
31
|
}
|
|
27
|
-
if (jsModuleAsJsClassic === true) {
|
|
28
|
-
jsModuleAsJsClassic = {}
|
|
29
|
-
}
|
|
30
32
|
return [
|
|
31
|
-
// import assertions we want it all the time
|
|
32
33
|
...(importAssertions
|
|
33
34
|
? [jsenvPluginImportAssertions(importAssertions)]
|
|
34
35
|
: []),
|
|
@@ -38,14 +39,12 @@ export const jsenvPluginTranspilation = ({
|
|
|
38
39
|
getCustomBabelPlugins,
|
|
39
40
|
babelHelpersAsImport,
|
|
40
41
|
}),
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
: []),
|
|
48
|
-
// topLevelAwait must come after js_module_as_js_classic because it's related to the module format
|
|
42
|
+
jsenvPluginAsJsClassic({
|
|
43
|
+
jsClassicLibrary,
|
|
44
|
+
jsClassicFallback,
|
|
45
|
+
systemJsInjection,
|
|
46
|
+
}),
|
|
47
|
+
// topLevelAwait must come after jsenvPluginAsJsClassic because it's related to the module format
|
|
49
48
|
// so we want to wait to know the module format before transforming things related to top level await
|
|
50
49
|
...(topLevelAwait ? [jsenvPluginTopLevelAwait(topLevelAwait)] : []),
|
|
51
50
|
...(css ? [jsenvPluginCssParcel()] : []),
|
|
@@ -13,15 +13,17 @@ import {
|
|
|
13
13
|
export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
14
14
|
const url = urlInfo.originalUrl
|
|
15
15
|
const content = urlInfo.content
|
|
16
|
-
const { scenarios, referenceUtils } = context
|
|
17
16
|
const htmlAst = parseHtmlString(content, {
|
|
18
|
-
storeOriginalPositions: scenarios.dev,
|
|
17
|
+
storeOriginalPositions: context.scenarios.dev,
|
|
19
18
|
})
|
|
20
|
-
const
|
|
21
|
-
visitHtmlUrls({
|
|
19
|
+
const mentions = visitHtmlUrls({
|
|
22
20
|
url,
|
|
23
21
|
htmlAst,
|
|
24
|
-
|
|
22
|
+
})
|
|
23
|
+
const actions = []
|
|
24
|
+
const mutations = []
|
|
25
|
+
mentions.forEach(
|
|
26
|
+
({
|
|
25
27
|
type,
|
|
26
28
|
subtype,
|
|
27
29
|
expectedType,
|
|
@@ -31,10 +33,10 @@ export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
31
33
|
originalColumn,
|
|
32
34
|
node,
|
|
33
35
|
attributeName,
|
|
36
|
+
debug,
|
|
34
37
|
specifier,
|
|
35
38
|
}) => {
|
|
36
39
|
const { crossorigin, integrity } = readFetchMetas(node)
|
|
37
|
-
|
|
38
40
|
const isResourceHint = [
|
|
39
41
|
"preconnect",
|
|
40
42
|
"dns-prefetch",
|
|
@@ -42,8 +44,9 @@ export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
42
44
|
"preload",
|
|
43
45
|
"modulepreload",
|
|
44
46
|
].includes(subtype)
|
|
45
|
-
const [reference] = referenceUtils.found({
|
|
47
|
+
const [reference] = context.referenceUtils.found({
|
|
46
48
|
type,
|
|
49
|
+
subtype,
|
|
47
50
|
expectedType,
|
|
48
51
|
originalLine,
|
|
49
52
|
originalColumn,
|
|
@@ -53,23 +56,26 @@ export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
53
56
|
isResourceHint,
|
|
54
57
|
crossorigin,
|
|
55
58
|
integrity,
|
|
59
|
+
debug,
|
|
56
60
|
})
|
|
57
61
|
actions.push(async () => {
|
|
62
|
+
await context.referenceUtils.readGeneratedSpecifier(reference)
|
|
63
|
+
})
|
|
64
|
+
mutations.push(() => {
|
|
58
65
|
setHtmlNodeAttributes(node, {
|
|
59
|
-
[attributeName]:
|
|
60
|
-
reference,
|
|
61
|
-
),
|
|
66
|
+
[attributeName]: reference.generatedSpecifier,
|
|
62
67
|
})
|
|
63
68
|
})
|
|
64
69
|
},
|
|
65
|
-
|
|
66
|
-
if (actions.length
|
|
67
|
-
|
|
70
|
+
)
|
|
71
|
+
if (actions.length > 0) {
|
|
72
|
+
await Promise.all(actions.map((action) => action()))
|
|
68
73
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
content: stringifyHtmlAst(htmlAst),
|
|
74
|
+
if (mutations.length === 0) {
|
|
75
|
+
return null
|
|
72
76
|
}
|
|
77
|
+
mutations.forEach((mutation) => mutation())
|
|
78
|
+
return stringifyHtmlAst(htmlAst)
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
const crossOriginCompatibleTagNames = ["script", "link", "img", "source"]
|
|
@@ -87,8 +93,10 @@ const readFetchMetas = (node) => {
|
|
|
87
93
|
return meta
|
|
88
94
|
}
|
|
89
95
|
|
|
90
|
-
const visitHtmlUrls = ({ url, htmlAst
|
|
91
|
-
const
|
|
96
|
+
const visitHtmlUrls = ({ url, htmlAst }) => {
|
|
97
|
+
const mentions = []
|
|
98
|
+
const finalizeCallbacks = []
|
|
99
|
+
const addMention = ({
|
|
92
100
|
type,
|
|
93
101
|
subtype,
|
|
94
102
|
expectedType,
|
|
@@ -111,7 +119,8 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
111
119
|
column,
|
|
112
120
|
// originalLine, originalColumn
|
|
113
121
|
} = position
|
|
114
|
-
|
|
122
|
+
const debug = getHtmlNodeAttribute(node, "jsenv-debug") !== undefined
|
|
123
|
+
const mention = {
|
|
115
124
|
type,
|
|
116
125
|
subtype,
|
|
117
126
|
expectedType,
|
|
@@ -121,7 +130,10 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
121
130
|
specifier,
|
|
122
131
|
node,
|
|
123
132
|
attributeName,
|
|
124
|
-
|
|
133
|
+
debug,
|
|
134
|
+
}
|
|
135
|
+
mentions.push(mention)
|
|
136
|
+
return mention
|
|
125
137
|
}
|
|
126
138
|
const visitAttributeAsUrlSpecifier = ({ node, attributeName, ...rest }) => {
|
|
127
139
|
const value = getHtmlNodeAttribute(node, attributeName)
|
|
@@ -130,9 +142,9 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
130
142
|
if (jsenvPluginOwner === "jsenv:importmap") {
|
|
131
143
|
// during build the importmap is inlined
|
|
132
144
|
// and shoud not be considered as a dependency anymore
|
|
133
|
-
return
|
|
145
|
+
return null
|
|
134
146
|
}
|
|
135
|
-
|
|
147
|
+
return addMention({
|
|
136
148
|
...rest,
|
|
137
149
|
node,
|
|
138
150
|
attributeName,
|
|
@@ -142,26 +154,29 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
142
154
|
? new URL(value, url).href
|
|
143
155
|
: value,
|
|
144
156
|
})
|
|
145
|
-
}
|
|
146
|
-
|
|
157
|
+
}
|
|
158
|
+
if (attributeName === "src") {
|
|
159
|
+
return visitAttributeAsUrlSpecifier({
|
|
147
160
|
...rest,
|
|
148
161
|
node,
|
|
149
162
|
attributeName: "inlined-from-src",
|
|
150
163
|
})
|
|
151
|
-
}
|
|
152
|
-
|
|
164
|
+
}
|
|
165
|
+
if (attributeName === "href") {
|
|
166
|
+
return visitAttributeAsUrlSpecifier({
|
|
153
167
|
...rest,
|
|
154
168
|
node,
|
|
155
169
|
attributeName: "inlined-from-href",
|
|
156
170
|
})
|
|
157
171
|
}
|
|
172
|
+
return null
|
|
158
173
|
}
|
|
159
174
|
const visitSrcset = ({ type, node }) => {
|
|
160
175
|
const srcset = getHtmlNodeAttribute(node, "srcset")
|
|
161
176
|
if (srcset) {
|
|
162
177
|
const srcCandidates = parseSrcSet(srcset)
|
|
163
178
|
srcCandidates.forEach((srcCandidate) => {
|
|
164
|
-
|
|
179
|
+
addMention({
|
|
165
180
|
type,
|
|
166
181
|
node,
|
|
167
182
|
attributeName: "srcset",
|
|
@@ -174,18 +189,20 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
174
189
|
link: (node) => {
|
|
175
190
|
const rel = getHtmlNodeAttribute(node, "rel")
|
|
176
191
|
const type = getHtmlNodeAttribute(node, "type")
|
|
177
|
-
visitAttributeAsUrlSpecifier({
|
|
192
|
+
const mention = visitAttributeAsUrlSpecifier({
|
|
178
193
|
type: "link_href",
|
|
179
194
|
subtype: rel,
|
|
180
195
|
node,
|
|
181
196
|
attributeName: "href",
|
|
197
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#including_a_mime_type
|
|
182
198
|
expectedContentType: type,
|
|
183
|
-
expectedType: {
|
|
184
|
-
manifest: "webmanifest",
|
|
185
|
-
modulepreload: "js_module",
|
|
186
|
-
stylesheet: "css",
|
|
187
|
-
}[rel],
|
|
188
199
|
})
|
|
200
|
+
|
|
201
|
+
if (mention) {
|
|
202
|
+
finalizeCallbacks.push(() => {
|
|
203
|
+
mention.expectedType = decideLinkExpectedType(mention, mentions)
|
|
204
|
+
})
|
|
205
|
+
}
|
|
189
206
|
},
|
|
190
207
|
// style: () => {},
|
|
191
208
|
script: (node) => {
|
|
@@ -198,6 +215,7 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
198
215
|
}
|
|
199
216
|
visitAttributeAsUrlSpecifier({
|
|
200
217
|
type: "script_src",
|
|
218
|
+
subtype: type,
|
|
201
219
|
expectedType: type,
|
|
202
220
|
node,
|
|
203
221
|
attributeName: "src",
|
|
@@ -228,7 +246,7 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
228
246
|
node,
|
|
229
247
|
})
|
|
230
248
|
},
|
|
231
|
-
|
|
249
|
+
source: (node) => {
|
|
232
250
|
visitAttributeAsUrlSpecifier({
|
|
233
251
|
type: "source_src",
|
|
234
252
|
node,
|
|
@@ -255,4 +273,43 @@ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
|
|
|
255
273
|
})
|
|
256
274
|
},
|
|
257
275
|
})
|
|
276
|
+
finalizeCallbacks.forEach((finalizeCallback) => {
|
|
277
|
+
finalizeCallback()
|
|
278
|
+
})
|
|
279
|
+
return mentions
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const decideLinkExpectedType = (linkMention, mentions) => {
|
|
283
|
+
const rel = getHtmlNodeAttribute(linkMention.node, "rel")
|
|
284
|
+
if (rel === "webmanifest") {
|
|
285
|
+
return "webmanifest"
|
|
286
|
+
}
|
|
287
|
+
if (rel === "modulepreload") {
|
|
288
|
+
return "js_module"
|
|
289
|
+
}
|
|
290
|
+
if (rel === "stylesheet") {
|
|
291
|
+
return "css"
|
|
292
|
+
}
|
|
293
|
+
if (rel === "preload") {
|
|
294
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#what_types_of_content_can_be_preloaded
|
|
295
|
+
const as = getHtmlNodeAttribute(linkMention.node, "as")
|
|
296
|
+
if (as === "document") {
|
|
297
|
+
return "html"
|
|
298
|
+
}
|
|
299
|
+
if (as === "style") {
|
|
300
|
+
return "css"
|
|
301
|
+
}
|
|
302
|
+
if (as === "script") {
|
|
303
|
+
const firstScriptOnThisUrl = mentions.find(
|
|
304
|
+
(mentionCandidate) =>
|
|
305
|
+
mentionCandidate.url === linkMention.url &&
|
|
306
|
+
mentionCandidate.type === "script_src",
|
|
307
|
+
)
|
|
308
|
+
if (firstScriptOnThisUrl) {
|
|
309
|
+
return firstScriptOnThisUrl.expectedType
|
|
310
|
+
}
|
|
311
|
+
return undefined
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return undefined
|
|
258
315
|
}
|
|
@@ -10,7 +10,6 @@ export const parseAndTransformJsUrls = async (urlInfo, context) => {
|
|
|
10
10
|
isJsModule: urlInfo.type === "js_module",
|
|
11
11
|
isWebWorker: isWebWorkerUrlInfo(urlInfo),
|
|
12
12
|
})
|
|
13
|
-
const { rootDirectoryUrl, referenceUtils } = context
|
|
14
13
|
const actions = []
|
|
15
14
|
const magicSource = createMagicSource(urlInfo.content)
|
|
16
15
|
jsMentions.forEach((jsMention) => {
|
|
@@ -20,7 +19,7 @@ export const parseAndTransformJsUrls = async (urlInfo, context) => {
|
|
|
20
19
|
) {
|
|
21
20
|
urlInfo.data.usesImport = true
|
|
22
21
|
}
|
|
23
|
-
const [reference] = referenceUtils.found({
|
|
22
|
+
const [reference] = context.referenceUtils.found({
|
|
24
23
|
type: jsMention.type,
|
|
25
24
|
subtype: jsMention.subtype,
|
|
26
25
|
expectedType: jsMention.expectedType,
|
|
@@ -33,7 +32,7 @@ export const parseAndTransformJsUrls = async (urlInfo, context) => {
|
|
|
33
32
|
data: jsMention.data,
|
|
34
33
|
baseUrl: {
|
|
35
34
|
"StringLiteral": jsMention.baseUrl,
|
|
36
|
-
"window.origin": rootDirectoryUrl,
|
|
35
|
+
"window.origin": context.rootDirectoryUrl,
|
|
37
36
|
"import.meta.url": urlInfo.url,
|
|
38
37
|
"context.meta.url": urlInfo.url,
|
|
39
38
|
"document.currentScript.src": urlInfo.url,
|
|
@@ -43,7 +42,9 @@ export const parseAndTransformJsUrls = async (urlInfo, context) => {
|
|
|
43
42
|
typePropertyNode: jsMention.typePropertyNode,
|
|
44
43
|
})
|
|
45
44
|
actions.push(async () => {
|
|
46
|
-
const replacement = await referenceUtils.readGeneratedSpecifier(
|
|
45
|
+
const replacement = await context.referenceUtils.readGeneratedSpecifier(
|
|
46
|
+
reference,
|
|
47
|
+
)
|
|
47
48
|
magicSource.replace({
|
|
48
49
|
start: jsMention.specifierStart,
|
|
49
50
|
end: jsMention.specifierEnd,
|