@jsenv/core 25.1.1 → 25.2.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/browser_runtime/browser_runtime_91c5a3b8.js.map +2 -2
- package/dist/build_manifest.js +4 -4
- package/dist/compile_proxy/asset-manifest.json +2 -2
- package/dist/compile_proxy/{compile_proxy_e3b0c442_809f35f7.js.map → compile_proxy.html__inline__20_809f35f7.js.map} +0 -0
- package/dist/compile_proxy/{compile_proxy_7ad5faa6.html → compile_proxy_8dfaee51.html} +3 -4
- package/dist/redirector/asset-manifest.json +2 -2
- package/dist/redirector/{redirector_e3b0c442_e391410e.js.map → redirector.html__inline__15_e391410e.js.map} +0 -0
- package/dist/redirector/{redirector_eb92e8a7.html → redirector_3e9a97b9.html} +3 -4
- package/dist/toolbar/asset-manifest.json +1 -1
- package/dist/toolbar/{toolbar_f7b8a263.html → toolbar_361afb84.html} +2 -3
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/{toolbar_injector_49e4756e.js → toolbar_injector_fac1e995.js} +2 -2
- package/dist/toolbar_injector/{toolbar_injector_49e4756e.js.map → toolbar_injector_fac1e995.js.map} +2 -2
- package/package.json +7 -7
- package/readme.md +43 -49
- package/src/buildProject.js +21 -13
- package/src/commonJsToJavaScriptModule.js +8 -7
- package/src/execute.js +2 -0
- package/src/executeTestPlan.js +4 -1
- package/src/internal/building/buildUsingRollup.js +4 -2
- package/src/internal/building/build_stats.js +3 -0
- package/src/internal/building/build_url_generator.js +153 -0
- package/src/internal/building/css/parseCssRessource.js +32 -26
- package/src/internal/building/html/parseHtmlRessource.js +92 -68
- package/src/internal/building/js/parseJsRessource.js +4 -7
- package/src/internal/building/parseRessource.js +3 -0
- package/src/internal/building/ressource_builder.js +64 -62
- package/src/internal/building/ressource_builder_util.js +17 -5
- package/src/internal/building/rollup_plugin_jsenv.js +259 -189
- package/src/internal/building/url_fetcher.js +16 -7
- package/src/internal/building/url_loader.js +1 -5
- package/src/internal/building/url_versioning.js +0 -173
- package/src/internal/compiling/babel_plugin_import_metadata.js +7 -11
- package/src/internal/compiling/babel_plugin_proxy_external_imports.js +31 -0
- package/src/internal/compiling/compile-directory/compile-asset.js +8 -4
- package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +43 -8
- package/src/internal/compiling/compile-directory/updateMeta.js +2 -8
- package/src/internal/compiling/compile-directory/validateCache.js +1 -2
- package/src/internal/compiling/compileFile.js +22 -10
- package/src/internal/compiling/createCompiledFileService.js +22 -24
- package/src/internal/compiling/html_source_file_service.js +9 -9
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +14 -4
- package/src/internal/compiling/js-compilation-service/transformJs.js +9 -5
- package/src/internal/compiling/jsenvCompilerForHtml.js +221 -182
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +15 -11
- package/src/internal/compiling/startCompileServer.js +79 -19
- package/src/internal/compiling/transformResultToCompilationResult.js +47 -25
- package/src/internal/executing/executePlan.js +2 -0
- package/src/internal/fetchUrl.js +3 -2
- package/src/internal/integrity/integrity_algorithms.js +26 -0
- package/src/internal/integrity/integrity_parsing.js +50 -0
- package/src/internal/integrity/integrity_update.js +23 -0
- package/src/internal/integrity/integrity_validation.js +49 -0
- package/src/internal/jsenv_remote_directory.js +156 -0
- package/src/internal/origin_directory_converter.js +62 -0
- package/src/internal/response_validation.js +11 -24
- package/src/internal/sourceMappingURLUtils.js +10 -0
- package/src/internal/url_conversion.js +1 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveUrl,
|
|
3
3
|
urlToFilename,
|
|
4
|
-
urlToBasename,
|
|
5
4
|
urlToRelativeUrl,
|
|
6
5
|
urlIsInsideOf,
|
|
7
6
|
} from "@jsenv/filesystem"
|
|
@@ -18,6 +17,7 @@ import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
|
|
|
18
17
|
import { getDefaultImportmap } from "@jsenv/core/src/internal/import-resolution/importmap_default.js"
|
|
19
18
|
|
|
20
19
|
import {
|
|
20
|
+
generateSourcemapUrl,
|
|
21
21
|
setJavaScriptSourceMappingUrl,
|
|
22
22
|
sourcemapToBase64Url,
|
|
23
23
|
} from "../sourceMappingURLUtils.js"
|
|
@@ -34,44 +34,42 @@ import {
|
|
|
34
34
|
removeHtmlNodeAttribute,
|
|
35
35
|
setHtmlNodeText,
|
|
36
36
|
visitHtmlAst,
|
|
37
|
-
|
|
37
|
+
addHtmlNodeAttribute,
|
|
38
38
|
} from "./compileHtml.js"
|
|
39
|
-
import {
|
|
39
|
+
import { generateCompilationAssetUrl } from "./compile-directory/compile-asset.js"
|
|
40
40
|
|
|
41
41
|
export const compileHtml = async ({
|
|
42
42
|
// cancellationToken,
|
|
43
43
|
logger,
|
|
44
|
-
// request,
|
|
45
|
-
code,
|
|
46
44
|
url,
|
|
47
45
|
compiledUrl,
|
|
48
46
|
projectDirectoryUrl,
|
|
47
|
+
jsenvRemoteDirectory,
|
|
49
48
|
compileServerOrigin,
|
|
50
49
|
outDirectoryRelativeUrl,
|
|
51
|
-
compileId,
|
|
52
50
|
|
|
51
|
+
compileId,
|
|
53
52
|
babelPluginMap,
|
|
54
53
|
moduleOutFormat,
|
|
55
54
|
importMetaFormat,
|
|
56
55
|
topLevelAwait,
|
|
57
|
-
|
|
58
|
-
sourcemapMethod,
|
|
59
|
-
|
|
60
56
|
jsenvScriptInjection = true,
|
|
61
57
|
jsenvEventSourceClientInjection,
|
|
62
58
|
jsenvToolbarInjection,
|
|
63
59
|
onHtmlImportmapInfo,
|
|
60
|
+
|
|
61
|
+
sourcemapMethod,
|
|
62
|
+
code,
|
|
64
63
|
}) => {
|
|
64
|
+
const compileDirectoryUrl = `${projectDirectoryUrl}${outDirectoryRelativeUrl}${compileId}/`
|
|
65
65
|
const browserRuntimeBuildUrlRelativeToProject = urlToRelativeUrl(
|
|
66
66
|
BROWSER_RUNTIME_BUILD_URL,
|
|
67
67
|
projectDirectoryUrl,
|
|
68
68
|
)
|
|
69
|
-
|
|
70
69
|
const eventSourceClientBuildRelativeUrlForProject = urlToRelativeUrl(
|
|
71
70
|
EVENT_SOURCE_CLIENT_BUILD_URL,
|
|
72
71
|
projectDirectoryUrl,
|
|
73
72
|
)
|
|
74
|
-
|
|
75
73
|
const toolbarInjectorBuildRelativeUrlForProject = urlToRelativeUrl(
|
|
76
74
|
TOOLBAR_INJECTOR_BUILD_URL,
|
|
77
75
|
projectDirectoryUrl,
|
|
@@ -79,11 +77,6 @@ export const compileHtml = async ({
|
|
|
79
77
|
|
|
80
78
|
// ideally we should try/catch html syntax error
|
|
81
79
|
const htmlAst = parseHtmlString(code)
|
|
82
|
-
|
|
83
|
-
if (moduleOutFormat !== "esmodule") {
|
|
84
|
-
await mutateRessourceHints(htmlAst)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
80
|
manipulateHtmlAst(htmlAst, {
|
|
88
81
|
scriptInjections: [
|
|
89
82
|
...(jsenvScriptInjection
|
|
@@ -140,70 +133,45 @@ export const compileHtml = async ({
|
|
|
140
133
|
specifier,
|
|
141
134
|
})
|
|
142
135
|
}
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
if (moduleOutFormat !== "esmodule") {
|
|
137
|
+
const ressourceHints = collectRessourceHints(htmlAst)
|
|
138
|
+
await visitRessourceHints({
|
|
139
|
+
ressourceHints,
|
|
140
|
+
addHtmlMutation,
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
await visitImportmapScript({
|
|
144
|
+
htmlAst,
|
|
145
145
|
logger,
|
|
146
146
|
url,
|
|
147
147
|
compiledUrl,
|
|
148
148
|
projectDirectoryUrl,
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
compileDirectoryUrl,
|
|
150
|
+
moduleOutFormat,
|
|
151
151
|
scripts,
|
|
152
|
+
addHtmlMutation,
|
|
152
153
|
addHtmlSourceFile,
|
|
154
|
+
onHtmlImportmapInfo,
|
|
153
155
|
})
|
|
154
|
-
const importmap = (await importmapInfo.load()) || {}
|
|
155
|
-
const importmapAsText = JSON.stringify(importmap, null, " ")
|
|
156
|
-
importmapInfo.inlinedFrom = importmapInfo.url
|
|
157
|
-
importmapInfo.text = importmapAsText
|
|
158
|
-
addHtmlMutation(() => {
|
|
159
|
-
if (importmapInfo.needsInjection) {
|
|
160
|
-
manipulateHtmlAst(htmlAst, {
|
|
161
|
-
scriptInjections: [
|
|
162
|
-
{
|
|
163
|
-
type:
|
|
164
|
-
moduleOutFormat === "systemjs"
|
|
165
|
-
? "systemjs-importmap"
|
|
166
|
-
: "importmap",
|
|
167
|
-
// in case there is no importmap, force the presence
|
|
168
|
-
// so that '@jsenv/core/' are still remapped
|
|
169
|
-
text: importmapAsText,
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
})
|
|
173
|
-
} else {
|
|
174
|
-
replaceHtmlNode(
|
|
175
|
-
importmapInfo.script,
|
|
176
|
-
`<script type="${
|
|
177
|
-
moduleOutFormat === "systemjs" ? "systemjs-importmap" : "importmap"
|
|
178
|
-
}">${importmapAsText}</script>`,
|
|
179
|
-
{
|
|
180
|
-
attributesToIgnore: ["src"],
|
|
181
|
-
},
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
onHtmlImportmapInfo({
|
|
186
|
-
htmlUrl: url,
|
|
187
|
-
importmapInfo,
|
|
188
|
-
})
|
|
189
|
-
|
|
190
156
|
await visitScripts({
|
|
191
157
|
logger,
|
|
192
158
|
projectDirectoryUrl,
|
|
159
|
+
jsenvRemoteDirectory,
|
|
193
160
|
compileServerOrigin,
|
|
194
161
|
url,
|
|
195
162
|
compiledUrl,
|
|
196
|
-
scripts,
|
|
197
|
-
addHtmlSourceFile,
|
|
198
|
-
addHtmlAssetGenerator,
|
|
199
|
-
addHtmlMutation,
|
|
200
|
-
addHtmlDependency,
|
|
201
163
|
|
|
202
164
|
babelPluginMap,
|
|
203
165
|
moduleOutFormat,
|
|
204
166
|
importMetaFormat,
|
|
205
167
|
topLevelAwait,
|
|
206
168
|
sourcemapMethod,
|
|
169
|
+
|
|
170
|
+
scripts,
|
|
171
|
+
addHtmlSourceFile,
|
|
172
|
+
addHtmlAssetGenerator,
|
|
173
|
+
addHtmlMutation,
|
|
174
|
+
addHtmlDependency,
|
|
207
175
|
})
|
|
208
176
|
await Promise.all(
|
|
209
177
|
htmlAssetGenerators.map(async (htmlAssetGenerator) => {
|
|
@@ -215,13 +183,11 @@ export const compileHtml = async ({
|
|
|
215
183
|
}),
|
|
216
184
|
)
|
|
217
185
|
htmlAssetGenerators.length = 0
|
|
218
|
-
|
|
219
186
|
htmlMutations.forEach((htmlMutation) => {
|
|
220
187
|
htmlMutation()
|
|
221
188
|
})
|
|
222
189
|
htmlMutations.length = 0
|
|
223
190
|
const htmlAfterTransformation = stringifyHtmlAst(htmlAst)
|
|
224
|
-
|
|
225
191
|
return {
|
|
226
192
|
contentType: "text/html",
|
|
227
193
|
compiledSource: htmlAfterTransformation,
|
|
@@ -235,35 +201,95 @@ export const compileHtml = async ({
|
|
|
235
201
|
}
|
|
236
202
|
}
|
|
237
203
|
|
|
204
|
+
// transform <link type="modulepreload"> into <link type="preload">
|
|
205
|
+
// also remove integrity attributes because we don't know in advance
|
|
206
|
+
// the result of the file compilation
|
|
207
|
+
const visitRessourceHints = async ({ ressourceHints, addHtmlMutation }) => {
|
|
208
|
+
await Promise.all(
|
|
209
|
+
ressourceHints.map(async (ressourceHint) => {
|
|
210
|
+
const hrefAttribute = getHtmlNodeAttributeByName(ressourceHint, "href")
|
|
211
|
+
const href = hrefAttribute ? hrefAttribute.value : ""
|
|
212
|
+
if (!href) {
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
const integrityAttribute = getHtmlNodeAttributeByName(
|
|
216
|
+
ressourceHint,
|
|
217
|
+
"integrity",
|
|
218
|
+
)
|
|
219
|
+
if (integrityAttribute) {
|
|
220
|
+
addHtmlMutation(() => {
|
|
221
|
+
removeHtmlNodeAttribute(ressourceHint, integrityAttribute)
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
const relAttribute = getHtmlNodeAttributeByName(ressourceHint, "rel")
|
|
225
|
+
const asAttribute = getHtmlNodeAttributeByName(ressourceHint, "as")
|
|
226
|
+
// - "modulepreload" -> "preload" because it's now regular js script
|
|
227
|
+
if (ressourceHint.rel === "modulepreload") {
|
|
228
|
+
addHtmlMutation(() => {
|
|
229
|
+
relAttribute.value = "preload"
|
|
230
|
+
if (asAttribute) {
|
|
231
|
+
asAttribute.value = "script"
|
|
232
|
+
} else {
|
|
233
|
+
addHtmlNodeAttribute(ressourceHint, { name: "as", value: "script" })
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
// if (asAttribute && asAttribute.value === "script") {
|
|
239
|
+
// addHtmlMutation(() => {
|
|
240
|
+
// replaceHtmlNode(htmlNode, `<link as="script" />`)
|
|
241
|
+
// })
|
|
242
|
+
// return
|
|
243
|
+
// }
|
|
244
|
+
}),
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
238
248
|
const visitImportmapScript = async ({
|
|
249
|
+
htmlAst,
|
|
239
250
|
logger,
|
|
240
251
|
url,
|
|
241
252
|
compiledUrl,
|
|
242
253
|
projectDirectoryUrl,
|
|
243
|
-
|
|
244
|
-
|
|
254
|
+
compileDirectoryUrl,
|
|
255
|
+
moduleOutFormat,
|
|
245
256
|
scripts,
|
|
257
|
+
addHtmlMutation,
|
|
246
258
|
addHtmlSourceFile,
|
|
259
|
+
onHtmlImportmapInfo,
|
|
247
260
|
}) => {
|
|
248
261
|
const importmapScripts = scripts.filter((script) => {
|
|
249
262
|
const typeAttribute = getHtmlNodeAttributeByName(script, "type")
|
|
250
263
|
const type = typeAttribute ? typeAttribute.value : "application/javascript"
|
|
251
264
|
return type === "importmap"
|
|
252
265
|
})
|
|
266
|
+
// in case there is no importmap, force the presence
|
|
267
|
+
// so that '@jsenv/core/' are still remapped
|
|
253
268
|
if (importmapScripts.length === 0) {
|
|
254
|
-
|
|
255
|
-
|
|
269
|
+
const defaultImportMap = getDefaultImportmap(compiledUrl, {
|
|
270
|
+
projectDirectoryUrl,
|
|
271
|
+
compileDirectoryUrl,
|
|
272
|
+
})
|
|
273
|
+
const defaultImportMapAsText = JSON.stringify(defaultImportMap, null, " ")
|
|
274
|
+
onHtmlImportmapInfo({
|
|
256
275
|
url: compiledUrl,
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
276
|
+
text: defaultImportMapAsText,
|
|
277
|
+
})
|
|
278
|
+
addHtmlMutation(() => {
|
|
279
|
+
manipulateHtmlAst(htmlAst, {
|
|
280
|
+
scriptInjections: [
|
|
281
|
+
{
|
|
282
|
+
type:
|
|
283
|
+
moduleOutFormat === "systemjs"
|
|
284
|
+
? "systemjs-importmap"
|
|
285
|
+
: "importmap",
|
|
286
|
+
text: defaultImportMapAsText,
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
return
|
|
265
292
|
}
|
|
266
|
-
|
|
267
293
|
if (importmapScripts.length > 1) {
|
|
268
294
|
logger.error("HTML file must contain max 1 importmap")
|
|
269
295
|
}
|
|
@@ -272,94 +298,131 @@ const visitImportmapScript = async ({
|
|
|
272
298
|
const src = srcAttribute ? srcAttribute.value : ""
|
|
273
299
|
if (src) {
|
|
274
300
|
const importmapUrl = resolveUrl(src, url)
|
|
275
|
-
const
|
|
276
|
-
|
|
301
|
+
const importMapResponse = await fetchUrl(importmapUrl)
|
|
302
|
+
let importmap
|
|
303
|
+
if (importMapResponse.status === 200) {
|
|
304
|
+
const importmapAsText = await importMapResponse.text()
|
|
305
|
+
addHtmlSourceFile({
|
|
306
|
+
url: importmapUrl,
|
|
307
|
+
content: importmapAsText,
|
|
308
|
+
})
|
|
309
|
+
let htmlImportmap = JSON.parse(importmapAsText)
|
|
310
|
+
importmap = moveImportMap(htmlImportmap, importmapUrl, url)
|
|
311
|
+
} else {
|
|
312
|
+
logger.warn(
|
|
313
|
+
createDetailedMessage(
|
|
314
|
+
importMapResponse.status === 404
|
|
315
|
+
? `importmap script file cannot be found.`
|
|
316
|
+
: `importmap script file unexpected response status (${importMapResponse.status}).`,
|
|
317
|
+
{
|
|
318
|
+
"importmap url": importmapUrl,
|
|
319
|
+
"html url": url,
|
|
320
|
+
},
|
|
321
|
+
),
|
|
322
|
+
)
|
|
323
|
+
importmap = {}
|
|
324
|
+
}
|
|
325
|
+
const importmapAsText = JSON.stringify(importmap, null, " ")
|
|
326
|
+
onHtmlImportmapInfo({
|
|
277
327
|
url: importmapUrl,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
htmlImportmap = moveImportMap(htmlImportmap, importmapUrl, url)
|
|
288
|
-
return htmlImportmap
|
|
289
|
-
}
|
|
290
|
-
logger.warn(
|
|
291
|
-
createDetailedMessage(
|
|
292
|
-
importMapResponse.status === 404
|
|
293
|
-
? `importmap script file cannot be found.`
|
|
294
|
-
: `importmap script file unexpected response status (${importMapResponse.status}).`,
|
|
295
|
-
{
|
|
296
|
-
"importmap url": importmapInfo.url,
|
|
297
|
-
"html url": url,
|
|
298
|
-
},
|
|
299
|
-
),
|
|
328
|
+
text: importmapAsText,
|
|
329
|
+
})
|
|
330
|
+
addHtmlMutation(() => {
|
|
331
|
+
removeHtmlNodeAttribute(firstImportmapScript, srcAttribute)
|
|
332
|
+
setHtmlNodeText(firstImportmapScript, importmapAsText)
|
|
333
|
+
if (moduleOutFormat === "systemjs") {
|
|
334
|
+
const typeAttribute = getHtmlNodeAttributeByName(
|
|
335
|
+
firstImportmapScript,
|
|
336
|
+
"type",
|
|
300
337
|
)
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return
|
|
338
|
+
typeAttribute.value = "systemjs-importmap"
|
|
339
|
+
}
|
|
340
|
+
})
|
|
341
|
+
return
|
|
305
342
|
}
|
|
306
|
-
|
|
307
|
-
|
|
343
|
+
|
|
344
|
+
const jsenvImportmap = getDefaultImportmap(compiledUrl, {
|
|
345
|
+
projectDirectoryUrl,
|
|
346
|
+
compileDirectoryUrl,
|
|
347
|
+
})
|
|
348
|
+
const htmlImportmap = JSON.parse(
|
|
349
|
+
getHtmlNodeTextNode(firstImportmapScript).value,
|
|
350
|
+
)
|
|
351
|
+
const importmap = composeTwoImportMaps(jsenvImportmap, htmlImportmap)
|
|
352
|
+
const importmapAsText = JSON.stringify(importmap, null, " ")
|
|
353
|
+
onHtmlImportmapInfo({
|
|
308
354
|
url: compiledUrl,
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
355
|
+
text: importmapAsText,
|
|
356
|
+
})
|
|
357
|
+
addHtmlMutation(() => {
|
|
358
|
+
removeHtmlNodeAttribute(firstImportmapScript, srcAttribute)
|
|
359
|
+
setHtmlNodeText(firstImportmapScript, importmapAsText)
|
|
360
|
+
if (moduleOutFormat === "systemjs") {
|
|
361
|
+
const typeAttribute = getHtmlNodeAttributeByName(
|
|
362
|
+
firstImportmapScript,
|
|
363
|
+
"type",
|
|
316
364
|
)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return importmapInfo
|
|
365
|
+
typeAttribute.value = "systemjs-importmap"
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
return
|
|
322
369
|
}
|
|
323
370
|
|
|
324
371
|
const visitScripts = async ({
|
|
325
372
|
logger,
|
|
326
373
|
projectDirectoryUrl,
|
|
327
374
|
compileServerOrigin,
|
|
375
|
+
jsenvRemoteDirectory,
|
|
328
376
|
url,
|
|
329
377
|
compiledUrl,
|
|
330
|
-
scripts,
|
|
331
|
-
addHtmlSourceFile,
|
|
332
|
-
addHtmlAssetGenerator,
|
|
333
|
-
addHtmlMutation,
|
|
334
|
-
addHtmlDependency,
|
|
335
378
|
|
|
336
379
|
babelPluginMap,
|
|
337
380
|
moduleOutFormat,
|
|
338
381
|
importMetaFormat,
|
|
339
382
|
topLevelAwait,
|
|
340
383
|
sourcemapMethod,
|
|
384
|
+
|
|
385
|
+
scripts,
|
|
386
|
+
addHtmlSourceFile,
|
|
387
|
+
addHtmlAssetGenerator,
|
|
388
|
+
addHtmlMutation,
|
|
389
|
+
addHtmlDependency,
|
|
341
390
|
}) => {
|
|
342
391
|
scripts.forEach((script) => {
|
|
343
392
|
const typeAttribute = getHtmlNodeAttributeByName(script, "type")
|
|
344
393
|
const type = typeAttribute ? typeAttribute.value : "application/javascript"
|
|
345
394
|
const srcAttribute = getHtmlNodeAttributeByName(script, "src")
|
|
346
395
|
const src = srcAttribute ? srcAttribute.value : ""
|
|
396
|
+
const integrityAttribute = getHtmlNodeAttributeByName(script, "integrity")
|
|
347
397
|
const textNode = getHtmlNodeTextNode(script)
|
|
348
|
-
|
|
349
398
|
if (type === "module") {
|
|
350
399
|
if (src) {
|
|
351
400
|
addHtmlMutation(() => {
|
|
352
401
|
if (moduleOutFormat === "systemjs") {
|
|
353
402
|
removeHtmlNodeAttribute(script, typeAttribute)
|
|
354
403
|
}
|
|
404
|
+
if (integrityAttribute) {
|
|
405
|
+
removeHtmlNodeAttribute(script, integrityAttribute)
|
|
406
|
+
}
|
|
355
407
|
removeHtmlNodeAttribute(script, srcAttribute)
|
|
356
408
|
const jsenvMethod =
|
|
357
409
|
moduleOutFormat === "systemjs"
|
|
358
410
|
? "executeFileUsingSystemJs"
|
|
359
411
|
: "executeFileUsingDynamicImport"
|
|
412
|
+
let specifier
|
|
413
|
+
if (
|
|
414
|
+
jsenvRemoteDirectory.isRemoteUrl(src) &&
|
|
415
|
+
!jsenvRemoteDirectory.isPreservedUrl(src)
|
|
416
|
+
) {
|
|
417
|
+
const fileUrl = jsenvRemoteDirectory.fileUrlFromRemoteUrl(src)
|
|
418
|
+
const fileUrlRelativeToHtml = urlToRelativeUrl(fileUrl, url)
|
|
419
|
+
specifier = `./${fileUrlRelativeToHtml}`
|
|
420
|
+
} else {
|
|
421
|
+
specifier = src
|
|
422
|
+
}
|
|
360
423
|
setHtmlNodeText(
|
|
361
424
|
script,
|
|
362
|
-
`window.__jsenv__.${jsenvMethod}(${JSON.stringify(
|
|
425
|
+
`window.__jsenv__.${jsenvMethod}(${JSON.stringify(specifier)})`,
|
|
363
426
|
)
|
|
364
427
|
})
|
|
365
428
|
return
|
|
@@ -368,23 +431,25 @@ const visitScripts = async ({
|
|
|
368
431
|
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
369
432
|
const inlineScriptName = `${scriptId}.js`
|
|
370
433
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
371
|
-
const scriptCompiledUrl =
|
|
434
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
372
435
|
compiledUrl,
|
|
373
436
|
inlineScriptName,
|
|
374
437
|
)
|
|
375
438
|
addHtmlAssetGenerator(async () => {
|
|
376
439
|
return transformHtmlScript({
|
|
377
440
|
projectDirectoryUrl,
|
|
441
|
+
jsenvRemoteDirectory,
|
|
378
442
|
url: scriptOriginalUrl,
|
|
379
443
|
compiledUrl: scriptCompiledUrl,
|
|
380
|
-
code: textNode.value,
|
|
381
444
|
|
|
382
445
|
type: "module",
|
|
383
446
|
babelPluginMap,
|
|
384
447
|
moduleOutFormat,
|
|
385
448
|
importMetaFormat,
|
|
386
449
|
topLevelAwait,
|
|
450
|
+
|
|
387
451
|
sourcemapMethod,
|
|
452
|
+
code: textNode.value,
|
|
388
453
|
})
|
|
389
454
|
})
|
|
390
455
|
const specifier = `./${urlToRelativeUrl(scriptCompiledUrl, compiledUrl)}`
|
|
@@ -408,7 +473,6 @@ const visitScripts = async ({
|
|
|
408
473
|
})
|
|
409
474
|
return
|
|
410
475
|
}
|
|
411
|
-
|
|
412
476
|
if (type === "application/javascript" || type === "text/javascript") {
|
|
413
477
|
if (src) {
|
|
414
478
|
const htmlServerUrl = url.replace(
|
|
@@ -428,7 +492,7 @@ const visitScripts = async ({
|
|
|
428
492
|
return
|
|
429
493
|
}
|
|
430
494
|
|
|
431
|
-
const scriptCompiledUrl =
|
|
495
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
432
496
|
compiledUrl,
|
|
433
497
|
urlToFilename(scriptOriginalUrl),
|
|
434
498
|
)
|
|
@@ -459,19 +523,24 @@ const visitScripts = async ({
|
|
|
459
523
|
})
|
|
460
524
|
return transformHtmlScript({
|
|
461
525
|
projectDirectoryUrl,
|
|
526
|
+
jsenvRemoteDirectory,
|
|
462
527
|
url: scriptOriginalUrl,
|
|
463
528
|
compiledUrl: scriptCompiledUrl,
|
|
464
|
-
code: scriptAsText,
|
|
465
529
|
|
|
466
530
|
type: "classic",
|
|
467
531
|
babelPluginMap,
|
|
468
532
|
moduleOutFormat,
|
|
469
533
|
importMetaFormat,
|
|
470
534
|
topLevelAwait,
|
|
535
|
+
|
|
471
536
|
sourcemapMethod,
|
|
537
|
+
code: scriptAsText,
|
|
472
538
|
})
|
|
473
539
|
})
|
|
474
540
|
addHtmlMutation(() => {
|
|
541
|
+
if (integrityAttribute) {
|
|
542
|
+
removeHtmlNodeAttribute(script, integrityAttribute)
|
|
543
|
+
}
|
|
475
544
|
srcAttribute.value = `./${urlToRelativeUrl(
|
|
476
545
|
scriptCompiledUrl,
|
|
477
546
|
compiledUrl,
|
|
@@ -482,22 +551,24 @@ const visitScripts = async ({
|
|
|
482
551
|
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
483
552
|
const inlineScriptName = `${scriptId}.js`
|
|
484
553
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
485
|
-
const scriptCompiledUrl =
|
|
554
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
486
555
|
compiledUrl,
|
|
487
556
|
inlineScriptName,
|
|
488
557
|
)
|
|
489
558
|
addHtmlAssetGenerator(async () => {
|
|
490
559
|
const htmlAssets = await transformHtmlScript({
|
|
491
560
|
projectDirectoryUrl,
|
|
561
|
+
jsenvRemoteDirectory,
|
|
492
562
|
url: scriptOriginalUrl,
|
|
493
563
|
compiledUrl: scriptCompiledUrl,
|
|
494
|
-
code: textNode.value,
|
|
495
564
|
|
|
496
565
|
type: "classic",
|
|
497
566
|
babelPluginMap,
|
|
498
567
|
moduleOutFormat,
|
|
499
568
|
importMetaFormat,
|
|
500
569
|
topLevelAwait,
|
|
570
|
+
|
|
571
|
+
code: textNode.value,
|
|
501
572
|
sourcemapMethod,
|
|
502
573
|
})
|
|
503
574
|
addHtmlMutation(() => {
|
|
@@ -512,30 +583,34 @@ const visitScripts = async ({
|
|
|
512
583
|
|
|
513
584
|
const transformHtmlScript = async ({
|
|
514
585
|
projectDirectoryUrl,
|
|
586
|
+
jsenvRemoteDirectory,
|
|
515
587
|
url,
|
|
516
588
|
compiledUrl,
|
|
517
|
-
code,
|
|
518
|
-
type,
|
|
519
589
|
|
|
590
|
+
type,
|
|
520
591
|
babelPluginMap,
|
|
521
592
|
moduleOutFormat,
|
|
522
593
|
importMetaFormat,
|
|
523
594
|
topLevelAwait,
|
|
595
|
+
|
|
596
|
+
code,
|
|
524
597
|
sourcemapMethod,
|
|
525
598
|
}) => {
|
|
526
599
|
let transformResult
|
|
527
600
|
try {
|
|
528
601
|
transformResult = await transformJs({
|
|
529
|
-
|
|
602
|
+
projectDirectoryUrl,
|
|
603
|
+
jsenvRemoteDirectory,
|
|
530
604
|
url,
|
|
531
605
|
compiledUrl,
|
|
532
|
-
projectDirectoryUrl,
|
|
533
606
|
|
|
534
607
|
babelPluginMap,
|
|
535
608
|
moduleOutFormat: type === "module" ? moduleOutFormat : "global",
|
|
536
609
|
importMetaFormat,
|
|
537
610
|
topLevelAwait: type === "module" ? topLevelAwait : false,
|
|
538
611
|
babelHelpersInjectionAsImport: type === "module" ? undefined : false,
|
|
612
|
+
|
|
613
|
+
code,
|
|
539
614
|
})
|
|
540
615
|
} catch (e) {
|
|
541
616
|
// If there is a syntax error in inline script
|
|
@@ -553,10 +628,7 @@ const transformHtmlScript = async ({
|
|
|
553
628
|
|
|
554
629
|
code = transformResult.code
|
|
555
630
|
let map = transformResult.map
|
|
556
|
-
const sourcemapUrl =
|
|
557
|
-
`${urlToBasename(compiledUrl)}.map`,
|
|
558
|
-
compiledUrl,
|
|
559
|
-
)
|
|
631
|
+
const sourcemapUrl = generateSourcemapUrl(compiledUrl)
|
|
560
632
|
if (sourcemapMethod === "inline") {
|
|
561
633
|
code = setJavaScriptSourceMappingUrl(code, sourcemapToBase64Url(map))
|
|
562
634
|
return [
|
|
@@ -580,11 +652,12 @@ const transformHtmlScript = async ({
|
|
|
580
652
|
]
|
|
581
653
|
}
|
|
582
654
|
|
|
583
|
-
|
|
584
|
-
const mutateRessourceHints = async (htmlAst) => {
|
|
655
|
+
const collectRessourceHints = (htmlAst) => {
|
|
585
656
|
const ressourceHints = []
|
|
586
657
|
visitHtmlAst(htmlAst, (htmlNode) => {
|
|
587
|
-
if (htmlNode.nodeName !== "link")
|
|
658
|
+
if (htmlNode.nodeName !== "link") {
|
|
659
|
+
return
|
|
660
|
+
}
|
|
588
661
|
const relAttribute = getHtmlNodeAttributeByName(htmlNode, "rel")
|
|
589
662
|
const rel = relAttribute ? relAttribute.value : ""
|
|
590
663
|
const isRessourceHint = [
|
|
@@ -594,44 +667,10 @@ const mutateRessourceHints = async (htmlAst) => {
|
|
|
594
667
|
"preload",
|
|
595
668
|
"modulepreload",
|
|
596
669
|
].includes(rel)
|
|
597
|
-
if (!isRessourceHint)
|
|
598
|
-
|
|
599
|
-
|
|
670
|
+
if (!isRessourceHint) {
|
|
671
|
+
return
|
|
672
|
+
}
|
|
673
|
+
ressourceHints.push(htmlNode)
|
|
600
674
|
})
|
|
601
|
-
|
|
602
|
-
const mutations = []
|
|
603
|
-
await Promise.all(
|
|
604
|
-
ressourceHints.map(async (ressourceHint) => {
|
|
605
|
-
const hrefAttribute = getHtmlNodeAttributeByName(
|
|
606
|
-
ressourceHint.htmlNode,
|
|
607
|
-
"href",
|
|
608
|
-
)
|
|
609
|
-
const href = hrefAttribute ? hrefAttribute.value : ""
|
|
610
|
-
if (!href) return
|
|
611
|
-
|
|
612
|
-
// - "modulepreload" -> "preload" because it's now regular js script
|
|
613
|
-
const asAttribute = getHtmlNodeAttributeByName(
|
|
614
|
-
ressourceHint.htmlNode,
|
|
615
|
-
"as",
|
|
616
|
-
)
|
|
617
|
-
|
|
618
|
-
if (ressourceHint.rel === "modulepreload") {
|
|
619
|
-
mutations.push(() => {
|
|
620
|
-
replaceHtmlNode(
|
|
621
|
-
ressourceHint.htmlNode,
|
|
622
|
-
`<link rel="preload" as="script" />`,
|
|
623
|
-
)
|
|
624
|
-
})
|
|
625
|
-
return
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
if (asAttribute && asAttribute.value === "script") {
|
|
629
|
-
mutations.push(() => {
|
|
630
|
-
replaceHtmlNode(ressourceHint.htmlNode, `<link as="script" />`)
|
|
631
|
-
})
|
|
632
|
-
return
|
|
633
|
-
}
|
|
634
|
-
}),
|
|
635
|
-
)
|
|
636
|
-
mutations.forEach((mutation) => mutation())
|
|
675
|
+
return ressourceHints
|
|
637
676
|
}
|