@jsenv/core 25.1.1 → 25.3.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 +13 -9
- package/readme.md +73 -79
- package/src/buildProject.js +21 -13
- package/src/commonJsToJavaScriptModule.js +8 -7
- package/src/dev_server.js +2 -0
- 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 +93 -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 +4 -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/babelHelper.js +10 -13
- package/src/internal/compiling/js-compilation-service/babel_plugin_babel_helpers_as_jsenv_imports.js +4 -2
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +16 -7
- package/src/internal/compiling/js-compilation-service/transformJs.js +9 -5
- package/src/internal/compiling/jsenvCompilerForHtml.js +226 -184
- 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/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,119 +298,157 @@ 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
|
|
366
429
|
}
|
|
367
|
-
|
|
368
430
|
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
369
431
|
const inlineScriptName = `${scriptId}.js`
|
|
370
432
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
371
|
-
const scriptCompiledUrl =
|
|
433
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
372
434
|
compiledUrl,
|
|
373
435
|
inlineScriptName,
|
|
374
436
|
)
|
|
375
437
|
addHtmlAssetGenerator(async () => {
|
|
376
438
|
return transformHtmlScript({
|
|
377
439
|
projectDirectoryUrl,
|
|
440
|
+
jsenvRemoteDirectory,
|
|
378
441
|
url: scriptOriginalUrl,
|
|
379
442
|
compiledUrl: scriptCompiledUrl,
|
|
380
|
-
code: textNode.value,
|
|
381
443
|
|
|
382
444
|
type: "module",
|
|
383
445
|
babelPluginMap,
|
|
384
446
|
moduleOutFormat,
|
|
385
447
|
importMetaFormat,
|
|
386
448
|
topLevelAwait,
|
|
449
|
+
|
|
387
450
|
sourcemapMethod,
|
|
451
|
+
code: textNode.value,
|
|
388
452
|
})
|
|
389
453
|
})
|
|
390
454
|
const specifier = `./${urlToRelativeUrl(scriptCompiledUrl, compiledUrl)}`
|
|
@@ -408,7 +472,6 @@ const visitScripts = async ({
|
|
|
408
472
|
})
|
|
409
473
|
return
|
|
410
474
|
}
|
|
411
|
-
|
|
412
475
|
if (type === "application/javascript" || type === "text/javascript") {
|
|
413
476
|
if (src) {
|
|
414
477
|
const htmlServerUrl = url.replace(
|
|
@@ -427,8 +490,11 @@ const visitScripts = async ({
|
|
|
427
490
|
if (fileIsInsideJsenvDistDirectory) {
|
|
428
491
|
return
|
|
429
492
|
}
|
|
430
|
-
|
|
431
|
-
|
|
493
|
+
const isRemoteUrl = jsenvRemoteDirectory.isRemoteUrl(src)
|
|
494
|
+
if (isRemoteUrl && jsenvRemoteDirectory.isPreservedUrl(src)) {
|
|
495
|
+
return
|
|
496
|
+
}
|
|
497
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
432
498
|
compiledUrl,
|
|
433
499
|
urlToFilename(scriptOriginalUrl),
|
|
434
500
|
)
|
|
@@ -437,6 +503,7 @@ const visitScripts = async ({
|
|
|
437
503
|
// the transformation here and not in compile server
|
|
438
504
|
// (because compile server would think it's a module script
|
|
439
505
|
// and add things like systemjs)
|
|
506
|
+
// we could take into account the integrity her
|
|
440
507
|
const scriptResponse = await fetchUrl(scriptOriginalUrl)
|
|
441
508
|
if (scriptResponse.status !== 200) {
|
|
442
509
|
logger.warn(
|
|
@@ -459,19 +526,24 @@ const visitScripts = async ({
|
|
|
459
526
|
})
|
|
460
527
|
return transformHtmlScript({
|
|
461
528
|
projectDirectoryUrl,
|
|
529
|
+
jsenvRemoteDirectory,
|
|
462
530
|
url: scriptOriginalUrl,
|
|
463
531
|
compiledUrl: scriptCompiledUrl,
|
|
464
|
-
code: scriptAsText,
|
|
465
532
|
|
|
466
533
|
type: "classic",
|
|
467
534
|
babelPluginMap,
|
|
468
535
|
moduleOutFormat,
|
|
469
536
|
importMetaFormat,
|
|
470
537
|
topLevelAwait,
|
|
538
|
+
|
|
471
539
|
sourcemapMethod,
|
|
540
|
+
code: scriptAsText,
|
|
472
541
|
})
|
|
473
542
|
})
|
|
474
543
|
addHtmlMutation(() => {
|
|
544
|
+
if (integrityAttribute) {
|
|
545
|
+
removeHtmlNodeAttribute(script, integrityAttribute)
|
|
546
|
+
}
|
|
475
547
|
srcAttribute.value = `./${urlToRelativeUrl(
|
|
476
548
|
scriptCompiledUrl,
|
|
477
549
|
compiledUrl,
|
|
@@ -482,22 +554,24 @@ const visitScripts = async ({
|
|
|
482
554
|
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
483
555
|
const inlineScriptName = `${scriptId}.js`
|
|
484
556
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
485
|
-
const scriptCompiledUrl =
|
|
557
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
486
558
|
compiledUrl,
|
|
487
559
|
inlineScriptName,
|
|
488
560
|
)
|
|
489
561
|
addHtmlAssetGenerator(async () => {
|
|
490
562
|
const htmlAssets = await transformHtmlScript({
|
|
491
563
|
projectDirectoryUrl,
|
|
564
|
+
jsenvRemoteDirectory,
|
|
492
565
|
url: scriptOriginalUrl,
|
|
493
566
|
compiledUrl: scriptCompiledUrl,
|
|
494
|
-
code: textNode.value,
|
|
495
567
|
|
|
496
568
|
type: "classic",
|
|
497
569
|
babelPluginMap,
|
|
498
570
|
moduleOutFormat,
|
|
499
571
|
importMetaFormat,
|
|
500
572
|
topLevelAwait,
|
|
573
|
+
|
|
574
|
+
code: textNode.value,
|
|
501
575
|
sourcemapMethod,
|
|
502
576
|
})
|
|
503
577
|
addHtmlMutation(() => {
|
|
@@ -512,30 +586,34 @@ const visitScripts = async ({
|
|
|
512
586
|
|
|
513
587
|
const transformHtmlScript = async ({
|
|
514
588
|
projectDirectoryUrl,
|
|
589
|
+
jsenvRemoteDirectory,
|
|
515
590
|
url,
|
|
516
591
|
compiledUrl,
|
|
517
|
-
code,
|
|
518
|
-
type,
|
|
519
592
|
|
|
593
|
+
type,
|
|
520
594
|
babelPluginMap,
|
|
521
595
|
moduleOutFormat,
|
|
522
596
|
importMetaFormat,
|
|
523
597
|
topLevelAwait,
|
|
598
|
+
|
|
599
|
+
code,
|
|
524
600
|
sourcemapMethod,
|
|
525
601
|
}) => {
|
|
526
602
|
let transformResult
|
|
527
603
|
try {
|
|
528
604
|
transformResult = await transformJs({
|
|
529
|
-
|
|
605
|
+
projectDirectoryUrl,
|
|
606
|
+
jsenvRemoteDirectory,
|
|
530
607
|
url,
|
|
531
608
|
compiledUrl,
|
|
532
|
-
projectDirectoryUrl,
|
|
533
609
|
|
|
534
610
|
babelPluginMap,
|
|
535
611
|
moduleOutFormat: type === "module" ? moduleOutFormat : "global",
|
|
536
612
|
importMetaFormat,
|
|
537
613
|
topLevelAwait: type === "module" ? topLevelAwait : false,
|
|
538
614
|
babelHelpersInjectionAsImport: type === "module" ? undefined : false,
|
|
615
|
+
|
|
616
|
+
code,
|
|
539
617
|
})
|
|
540
618
|
} catch (e) {
|
|
541
619
|
// If there is a syntax error in inline script
|
|
@@ -553,10 +631,7 @@ const transformHtmlScript = async ({
|
|
|
553
631
|
|
|
554
632
|
code = transformResult.code
|
|
555
633
|
let map = transformResult.map
|
|
556
|
-
const sourcemapUrl =
|
|
557
|
-
`${urlToBasename(compiledUrl)}.map`,
|
|
558
|
-
compiledUrl,
|
|
559
|
-
)
|
|
634
|
+
const sourcemapUrl = generateSourcemapUrl(compiledUrl)
|
|
560
635
|
if (sourcemapMethod === "inline") {
|
|
561
636
|
code = setJavaScriptSourceMappingUrl(code, sourcemapToBase64Url(map))
|
|
562
637
|
return [
|
|
@@ -580,11 +655,12 @@ const transformHtmlScript = async ({
|
|
|
580
655
|
]
|
|
581
656
|
}
|
|
582
657
|
|
|
583
|
-
|
|
584
|
-
const mutateRessourceHints = async (htmlAst) => {
|
|
658
|
+
const collectRessourceHints = (htmlAst) => {
|
|
585
659
|
const ressourceHints = []
|
|
586
660
|
visitHtmlAst(htmlAst, (htmlNode) => {
|
|
587
|
-
if (htmlNode.nodeName !== "link")
|
|
661
|
+
if (htmlNode.nodeName !== "link") {
|
|
662
|
+
return
|
|
663
|
+
}
|
|
588
664
|
const relAttribute = getHtmlNodeAttributeByName(htmlNode, "rel")
|
|
589
665
|
const rel = relAttribute ? relAttribute.value : ""
|
|
590
666
|
const isRessourceHint = [
|
|
@@ -594,44 +670,10 @@ const mutateRessourceHints = async (htmlAst) => {
|
|
|
594
670
|
"preload",
|
|
595
671
|
"modulepreload",
|
|
596
672
|
].includes(rel)
|
|
597
|
-
if (!isRessourceHint)
|
|
598
|
-
|
|
599
|
-
|
|
673
|
+
if (!isRessourceHint) {
|
|
674
|
+
return
|
|
675
|
+
}
|
|
676
|
+
ressourceHints.push(htmlNode)
|
|
600
677
|
})
|
|
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())
|
|
678
|
+
return ressourceHints
|
|
637
679
|
}
|