@jsenv/core 25.1.0 → 25.3.0-alpha.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 +75 -76
- 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 +14 -0
- 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 +110 -91
- 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/compileHtml.js +15 -28
- package/src/internal/compiling/createCompiledFileService.js +22 -24
- package/src/internal/compiling/html_source_file_service.js +18 -19
- 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 +231 -195
- 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"
|
|
@@ -30,48 +30,46 @@ import {
|
|
|
30
30
|
stringifyHtmlAst,
|
|
31
31
|
getHtmlNodeAttributeByName,
|
|
32
32
|
getHtmlNodeTextNode,
|
|
33
|
-
|
|
33
|
+
getIdForInlineHtmlNode,
|
|
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,122 +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
|
-
const inlineScriptName =
|
|
369
|
-
script,
|
|
370
|
-
scripts,
|
|
371
|
-
`[id].js`,
|
|
372
|
-
)
|
|
430
|
+
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
431
|
+
const inlineScriptName = `${scriptId}.js`
|
|
373
432
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
374
|
-
const scriptCompiledUrl =
|
|
433
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
375
434
|
compiledUrl,
|
|
376
435
|
inlineScriptName,
|
|
377
436
|
)
|
|
378
437
|
addHtmlAssetGenerator(async () => {
|
|
379
438
|
return transformHtmlScript({
|
|
380
439
|
projectDirectoryUrl,
|
|
440
|
+
jsenvRemoteDirectory,
|
|
381
441
|
url: scriptOriginalUrl,
|
|
382
442
|
compiledUrl: scriptCompiledUrl,
|
|
383
|
-
code: textNode.value,
|
|
384
443
|
|
|
385
444
|
type: "module",
|
|
386
445
|
babelPluginMap,
|
|
387
446
|
moduleOutFormat,
|
|
388
447
|
importMetaFormat,
|
|
389
448
|
topLevelAwait,
|
|
449
|
+
|
|
390
450
|
sourcemapMethod,
|
|
451
|
+
code: textNode.value,
|
|
391
452
|
})
|
|
392
453
|
})
|
|
393
454
|
const specifier = `./${urlToRelativeUrl(scriptCompiledUrl, compiledUrl)}`
|
|
@@ -411,7 +472,6 @@ const visitScripts = async ({
|
|
|
411
472
|
})
|
|
412
473
|
return
|
|
413
474
|
}
|
|
414
|
-
|
|
415
475
|
if (type === "application/javascript" || type === "text/javascript") {
|
|
416
476
|
if (src) {
|
|
417
477
|
const htmlServerUrl = url.replace(
|
|
@@ -430,8 +490,11 @@ const visitScripts = async ({
|
|
|
430
490
|
if (fileIsInsideJsenvDistDirectory) {
|
|
431
491
|
return
|
|
432
492
|
}
|
|
433
|
-
|
|
434
|
-
|
|
493
|
+
const isRemoteUrl = jsenvRemoteDirectory.isRemoteUrl(src)
|
|
494
|
+
if (isRemoteUrl && jsenvRemoteDirectory.isPreservedUrl(src)) {
|
|
495
|
+
return
|
|
496
|
+
}
|
|
497
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
435
498
|
compiledUrl,
|
|
436
499
|
urlToFilename(scriptOriginalUrl),
|
|
437
500
|
)
|
|
@@ -440,6 +503,7 @@ const visitScripts = async ({
|
|
|
440
503
|
// the transformation here and not in compile server
|
|
441
504
|
// (because compile server would think it's a module script
|
|
442
505
|
// and add things like systemjs)
|
|
506
|
+
// we could take into account the integrity her
|
|
443
507
|
const scriptResponse = await fetchUrl(scriptOriginalUrl)
|
|
444
508
|
if (scriptResponse.status !== 200) {
|
|
445
509
|
logger.warn(
|
|
@@ -462,19 +526,24 @@ const visitScripts = async ({
|
|
|
462
526
|
})
|
|
463
527
|
return transformHtmlScript({
|
|
464
528
|
projectDirectoryUrl,
|
|
529
|
+
jsenvRemoteDirectory,
|
|
465
530
|
url: scriptOriginalUrl,
|
|
466
531
|
compiledUrl: scriptCompiledUrl,
|
|
467
|
-
code: scriptAsText,
|
|
468
532
|
|
|
469
533
|
type: "classic",
|
|
470
534
|
babelPluginMap,
|
|
471
535
|
moduleOutFormat,
|
|
472
536
|
importMetaFormat,
|
|
473
537
|
topLevelAwait,
|
|
538
|
+
|
|
474
539
|
sourcemapMethod,
|
|
540
|
+
code: scriptAsText,
|
|
475
541
|
})
|
|
476
542
|
})
|
|
477
543
|
addHtmlMutation(() => {
|
|
544
|
+
if (integrityAttribute) {
|
|
545
|
+
removeHtmlNodeAttribute(script, integrityAttribute)
|
|
546
|
+
}
|
|
478
547
|
srcAttribute.value = `./${urlToRelativeUrl(
|
|
479
548
|
scriptCompiledUrl,
|
|
480
549
|
compiledUrl,
|
|
@@ -482,28 +551,27 @@ const visitScripts = async ({
|
|
|
482
551
|
})
|
|
483
552
|
return
|
|
484
553
|
}
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
scripts,
|
|
488
|
-
`[id].js`,
|
|
489
|
-
)
|
|
554
|
+
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
555
|
+
const inlineScriptName = `${scriptId}.js`
|
|
490
556
|
const scriptOriginalUrl = resolveUrl(inlineScriptName, url)
|
|
491
|
-
const scriptCompiledUrl =
|
|
557
|
+
const scriptCompiledUrl = generateCompilationAssetUrl(
|
|
492
558
|
compiledUrl,
|
|
493
559
|
inlineScriptName,
|
|
494
560
|
)
|
|
495
561
|
addHtmlAssetGenerator(async () => {
|
|
496
562
|
const htmlAssets = await transformHtmlScript({
|
|
497
563
|
projectDirectoryUrl,
|
|
564
|
+
jsenvRemoteDirectory,
|
|
498
565
|
url: scriptOriginalUrl,
|
|
499
566
|
compiledUrl: scriptCompiledUrl,
|
|
500
|
-
code: textNode.value,
|
|
501
567
|
|
|
502
568
|
type: "classic",
|
|
503
569
|
babelPluginMap,
|
|
504
570
|
moduleOutFormat,
|
|
505
571
|
importMetaFormat,
|
|
506
572
|
topLevelAwait,
|
|
573
|
+
|
|
574
|
+
code: textNode.value,
|
|
507
575
|
sourcemapMethod,
|
|
508
576
|
})
|
|
509
577
|
addHtmlMutation(() => {
|
|
@@ -518,30 +586,34 @@ const visitScripts = async ({
|
|
|
518
586
|
|
|
519
587
|
const transformHtmlScript = async ({
|
|
520
588
|
projectDirectoryUrl,
|
|
589
|
+
jsenvRemoteDirectory,
|
|
521
590
|
url,
|
|
522
591
|
compiledUrl,
|
|
523
|
-
code,
|
|
524
|
-
type,
|
|
525
592
|
|
|
593
|
+
type,
|
|
526
594
|
babelPluginMap,
|
|
527
595
|
moduleOutFormat,
|
|
528
596
|
importMetaFormat,
|
|
529
597
|
topLevelAwait,
|
|
598
|
+
|
|
599
|
+
code,
|
|
530
600
|
sourcemapMethod,
|
|
531
601
|
}) => {
|
|
532
602
|
let transformResult
|
|
533
603
|
try {
|
|
534
604
|
transformResult = await transformJs({
|
|
535
|
-
|
|
605
|
+
projectDirectoryUrl,
|
|
606
|
+
jsenvRemoteDirectory,
|
|
536
607
|
url,
|
|
537
608
|
compiledUrl,
|
|
538
|
-
projectDirectoryUrl,
|
|
539
609
|
|
|
540
610
|
babelPluginMap,
|
|
541
611
|
moduleOutFormat: type === "module" ? moduleOutFormat : "global",
|
|
542
612
|
importMetaFormat,
|
|
543
613
|
topLevelAwait: type === "module" ? topLevelAwait : false,
|
|
544
614
|
babelHelpersInjectionAsImport: type === "module" ? undefined : false,
|
|
615
|
+
|
|
616
|
+
code,
|
|
545
617
|
})
|
|
546
618
|
} catch (e) {
|
|
547
619
|
// If there is a syntax error in inline script
|
|
@@ -559,10 +631,7 @@ const transformHtmlScript = async ({
|
|
|
559
631
|
|
|
560
632
|
code = transformResult.code
|
|
561
633
|
let map = transformResult.map
|
|
562
|
-
const sourcemapUrl =
|
|
563
|
-
`${urlToBasename(compiledUrl)}.map`,
|
|
564
|
-
compiledUrl,
|
|
565
|
-
)
|
|
634
|
+
const sourcemapUrl = generateSourcemapUrl(compiledUrl)
|
|
566
635
|
if (sourcemapMethod === "inline") {
|
|
567
636
|
code = setJavaScriptSourceMappingUrl(code, sourcemapToBase64Url(map))
|
|
568
637
|
return [
|
|
@@ -586,11 +655,12 @@ const transformHtmlScript = async ({
|
|
|
586
655
|
]
|
|
587
656
|
}
|
|
588
657
|
|
|
589
|
-
|
|
590
|
-
const mutateRessourceHints = async (htmlAst) => {
|
|
658
|
+
const collectRessourceHints = (htmlAst) => {
|
|
591
659
|
const ressourceHints = []
|
|
592
660
|
visitHtmlAst(htmlAst, (htmlNode) => {
|
|
593
|
-
if (htmlNode.nodeName !== "link")
|
|
661
|
+
if (htmlNode.nodeName !== "link") {
|
|
662
|
+
return
|
|
663
|
+
}
|
|
594
664
|
const relAttribute = getHtmlNodeAttributeByName(htmlNode, "rel")
|
|
595
665
|
const rel = relAttribute ? relAttribute.value : ""
|
|
596
666
|
const isRessourceHint = [
|
|
@@ -600,44 +670,10 @@ const mutateRessourceHints = async (htmlAst) => {
|
|
|
600
670
|
"preload",
|
|
601
671
|
"modulepreload",
|
|
602
672
|
].includes(rel)
|
|
603
|
-
if (!isRessourceHint)
|
|
604
|
-
|
|
605
|
-
|
|
673
|
+
if (!isRessourceHint) {
|
|
674
|
+
return
|
|
675
|
+
}
|
|
676
|
+
ressourceHints.push(htmlNode)
|
|
606
677
|
})
|
|
607
|
-
|
|
608
|
-
const mutations = []
|
|
609
|
-
await Promise.all(
|
|
610
|
-
ressourceHints.map(async (ressourceHint) => {
|
|
611
|
-
const hrefAttribute = getHtmlNodeAttributeByName(
|
|
612
|
-
ressourceHint.htmlNode,
|
|
613
|
-
"href",
|
|
614
|
-
)
|
|
615
|
-
const href = hrefAttribute ? hrefAttribute.value : ""
|
|
616
|
-
if (!href) return
|
|
617
|
-
|
|
618
|
-
// - "modulepreload" -> "preload" because it's now regular js script
|
|
619
|
-
const asAttribute = getHtmlNodeAttributeByName(
|
|
620
|
-
ressourceHint.htmlNode,
|
|
621
|
-
"as",
|
|
622
|
-
)
|
|
623
|
-
|
|
624
|
-
if (ressourceHint.rel === "modulepreload") {
|
|
625
|
-
mutations.push(() => {
|
|
626
|
-
replaceHtmlNode(
|
|
627
|
-
ressourceHint.htmlNode,
|
|
628
|
-
`<link rel="preload" as="script" />`,
|
|
629
|
-
)
|
|
630
|
-
})
|
|
631
|
-
return
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
if (asAttribute && asAttribute.value === "script") {
|
|
635
|
-
mutations.push(() => {
|
|
636
|
-
replaceHtmlNode(ressourceHint.htmlNode, `<link as="script" />`)
|
|
637
|
-
})
|
|
638
|
-
return
|
|
639
|
-
}
|
|
640
|
-
}),
|
|
641
|
-
)
|
|
642
|
-
mutations.forEach((mutation) => mutation())
|
|
678
|
+
return ressourceHints
|
|
643
679
|
}
|