@jsenv/core 25.0.0-alpha.0 → 25.0.0-alpha.1

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.
Files changed (57) hide show
  1. package/dist/browser_runtime/asset-manifest.json +2 -2
  2. package/dist/browser_runtime/{browser_runtime_a8097085.js → browser_runtime_91c5a3b8.js} +137 -26
  3. package/dist/browser_runtime/browser_runtime_91c5a3b8.js.map +1089 -0
  4. package/dist/build_manifest.js +5 -5
  5. package/dist/compile_proxy/asset-manifest.json +2 -2
  6. package/dist/compile_proxy/{compile_proxy_e16d7de8.html → compile_proxy_7ad5faa6.html} +119 -26
  7. package/dist/compile_proxy/{compile_proxy_e3b0c442_9e168143.js.map → compile_proxy_e3b0c442_809f35f7.js.map} +6 -6
  8. package/dist/redirector/asset-manifest.json +2 -2
  9. package/dist/redirector/{redirector_e3b0c442_3a34a156.js.map → redirector_e3b0c442_e391410e.js.map} +6 -6
  10. package/dist/redirector/{redirector_2e0c8abe.html → redirector_eb92e8a7.html} +119 -26
  11. package/dist/toolbar/asset-manifest.json +11 -11
  12. package/dist/toolbar/{toolbar.main_a5ef2c60.js.map → toolbar.main2_6c1b3d82.js.map} +8 -8
  13. package/dist/toolbar/{toolbar_412abb83.html → toolbar_04ba410c.html} +127 -32
  14. package/dist/toolbar_injector/asset-manifest.json +2 -2
  15. package/dist/toolbar_injector/{toolbar_injector_4f9c19e5.js → toolbar_injector_4a48bc53.js} +2 -2
  16. package/dist/toolbar_injector/{toolbar_injector_4f9c19e5.js.map → toolbar_injector_4a48bc53.js.map} +2 -2
  17. package/package.json +5 -4
  18. package/readme.md +22 -89
  19. package/src/buildProject.js +28 -15
  20. package/src/dev_server.js +8 -2
  21. package/src/execute.js +7 -1
  22. package/src/executeTestPlan.js +6 -0
  23. package/src/internal/browser_feature_detection/browser_feature_detection.js +18 -25
  24. package/src/internal/browser_runtime/browser_runtime.js +2 -2
  25. package/src/internal/browser_runtime/createBrowserRuntime.js +1 -1
  26. package/src/internal/browser_runtime/displayErrorInDocument.js +2 -0
  27. package/src/internal/browser_runtime/displayErrorNotification.js +1 -1
  28. package/src/internal/building/buildUsingRollup.js +3 -8
  29. package/src/internal/building/ressource_builder.js +35 -42
  30. package/src/internal/building/rollup_plugin_jsenv.js +195 -186
  31. package/src/internal/building/url_versioning.js +36 -42
  32. package/src/internal/compiling/createCompiledFileService.js +28 -40
  33. package/src/internal/compiling/html_source_file_service.js +66 -51
  34. package/src/internal/compiling/js-compilation-service/babel_plugin_systemjs_prepend.js +23 -0
  35. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +16 -12
  36. package/src/internal/compiling/js-compilation-service/transformJs.js +2 -0
  37. package/src/internal/compiling/jsenvCompilerForHtml.js +43 -44
  38. package/src/internal/compiling/jsenvCompilerForImportmap.js +15 -76
  39. package/src/internal/compiling/jsenvCompilerForJavaScript.js +9 -0
  40. package/src/internal/compiling/startCompileServer.js +29 -5
  41. package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +9 -9
  42. package/src/internal/executing/executePlan.js +6 -0
  43. package/src/internal/generateGroupMap/{jsenvBabelPluginCompatMap.js → babel_plugins_compatibility.js} +0 -0
  44. package/src/internal/generateGroupMap/{featuresCompatMap.js → features_compatibility.js} +9 -1
  45. package/src/internal/generateGroupMap/generateGroupMap.js +6 -35
  46. package/src/internal/generateGroupMap/one_runtime_compat.js +9 -12
  47. package/src/internal/generateGroupMap/runtime_compat.js +10 -15
  48. package/src/internal/generateGroupMap/runtime_compat_composition.js +2 -2
  49. package/src/internal/generateGroupMap/shake_babel_plugin_map.js +21 -0
  50. package/src/internal/import-resolution/importmap_default.js +52 -0
  51. package/src/internal/node_feature_detection/node_feature_detection.js +25 -19
  52. package/src/internal/runtime/s.js +101 -6
  53. package/src/internal/unevalException.js +1 -1
  54. package/src/jsenvServiceWorkerFinalizer.js +3 -1
  55. package/dist/browser_runtime/browser_runtime_a8097085.js.map +0 -1067
  56. package/src/internal/generateGroupMap/jsenvPluginCompatMap.js +0 -1
  57. package/src/internal/import-resolution/importmap-default.js +0 -34
@@ -7,29 +7,40 @@ import {
7
7
 
8
8
  export const createUrlVersioner = ({
9
9
  entryPointUrls,
10
- workerUrls,
11
- classicWorkerUrls,
12
- serviceWorkerUrls,
13
- classicServiceWorkerUrls,
14
10
  asOriginalUrl,
15
11
  lineBreakNormalization,
16
12
  }) => {
17
- const computeBuildRelativeUrl = (ressource) => {
13
+ const names = []
14
+ const getFreeName = (name) => {
15
+ let nameCandidate = name
16
+ let integer = 1
17
+ // eslint-disable-next-line no-constant-condition
18
+ while (true) {
19
+ if (!names.includes(nameCandidate)) {
20
+ names.push(nameCandidate)
21
+ return nameCandidate
22
+ }
23
+ integer++
24
+ nameCandidate = `${name}${integer}`
25
+ }
26
+ }
27
+
28
+ const computeBuildRelativeUrl = (ressource, precomputation) => {
18
29
  const pattern = getFilenamePattern({
19
30
  ressource,
20
31
  entryPointUrls,
21
- workerUrls,
22
- classicWorkerUrls,
23
- serviceWorkerUrls,
24
- classicServiceWorkerUrls,
25
32
  asOriginalUrl,
26
33
  precomputeBuildRelativeUrl,
27
34
  })
35
+
28
36
  const buildRelativeUrl = generateBuildRelativeUrl(
29
37
  ressource.url,
30
38
  ressource.bufferAfterBuild,
31
39
  {
32
40
  pattern,
41
+ getName: precomputation
42
+ ? () => urlToBasename(ressource.url)
43
+ : () => getFreeName(urlToBasename(ressource.url)),
33
44
  contentType: ressource.contentType,
34
45
  lineBreakNormalization,
35
46
  },
@@ -46,7 +57,7 @@ export const createUrlVersioner = ({
46
57
  }
47
58
 
48
59
  ressource.bufferAfterBuild = bufferAfterBuild
49
- const precomputedBuildRelativeUrl = computeBuildRelativeUrl(ressource)
60
+ const precomputedBuildRelativeUrl = computeBuildRelativeUrl(ressource, true)
50
61
  ressource.bufferAfterBuild = undefined
51
62
  ressource.precomputedBuildRelativeUrl = precomputedBuildRelativeUrl
52
63
  return precomputedBuildRelativeUrl
@@ -61,10 +72,6 @@ export const createUrlVersioner = ({
61
72
  const getFilenamePattern = ({
62
73
  ressource,
63
74
  entryPointUrls,
64
- workerUrls,
65
- classicWorkerUrls,
66
- serviceWorkerUrls,
67
- classicServiceWorkerUrls,
68
75
  asOriginalUrl,
69
76
  precomputeBuildRelativeUrl,
70
77
  }) => {
@@ -74,30 +81,6 @@ const getFilenamePattern = ({
74
81
  return entryPointBuildRelativeUrl
75
82
  }
76
83
 
77
- // service worker:
78
- // - MUST be at the root (same level than the HTML file)
79
- // otherwise it might be registered for the scope "/assets/" instead of "/"
80
- // - MUST not be versioned
81
- if (ressource.isServiceWorker) {
82
- const originalUrl = asOriginalUrl(ressource.url)
83
- const serviceWorkerBuildRelativeUrl = ressource.isJsModule
84
- ? serviceWorkerUrls[originalUrl]
85
- : classicServiceWorkerUrls[originalUrl]
86
- // we could/should log a warning when service worker is not at the root
87
- // we should also disable versioning for this file
88
- // of the build directory
89
- return serviceWorkerBuildRelativeUrl
90
- }
91
-
92
- // it's a module worker
93
- if (ressource.isWorker) {
94
- const originalUrl = asOriginalUrl(ressource.url)
95
- const workerBuildRelativeUrl = ressource.isJsModule
96
- ? workerUrls[originalUrl]
97
- : classicWorkerUrls[originalUrl]
98
- return workerBuildRelativeUrl
99
- }
100
-
101
84
  // inline ressource inherits location
102
85
  if (ressource.isInline) {
103
86
  // inherit parent directory location because it's an inline file
@@ -119,8 +102,19 @@ const getFilenamePattern = ({
119
102
  return `${name}_[hash][extname]`
120
103
  }
121
104
 
105
+ // service worker:
106
+ // - MUST be at the root (same level than the HTML file)
107
+ // otherwise it might be registered for the scope "/assets/" instead of "/"
108
+ // - MUST not be versioned
109
+ if (ressource.isServiceWorker) {
110
+ return "[name][extname]"
111
+ }
112
+
113
+ if (ressource.isWorker) {
114
+ return "[name]_[hash][extname]"
115
+ }
116
+
122
117
  if (ressource.isJsModule) {
123
- // it's a js module
124
118
  return "[name]_[hash][extname]"
125
119
  }
126
120
 
@@ -133,8 +127,8 @@ const generateBuildRelativeUrl = (
133
127
  fileUrl,
134
128
  fileContent,
135
129
  {
136
- name = urlToBasename(fileUrl),
137
- pattern = "[name]-[hash][extname]",
130
+ getName,
131
+ pattern,
138
132
  contentType = "application/octet-stream",
139
133
  lineBreakNormalization = false,
140
134
  } = {},
@@ -143,7 +137,7 @@ const generateBuildRelativeUrl = (
143
137
  if (pattern.startsWith("./")) pattern = pattern.slice(2)
144
138
  const buildRelativeUrl = renderFileNamePattern(pattern, {
145
139
  dirname: () => urlToParentUrl(fileUrl),
146
- name: () => name,
140
+ name: getName,
147
141
  hash: () =>
148
142
  generateContentHash(fileContent, {
149
143
  contentType,
@@ -6,10 +6,10 @@ import {
6
6
  urlToMeta,
7
7
  } from "@jsenv/filesystem"
8
8
 
9
- import { featuresCompatMap } from "@jsenv/core/src/internal/generateGroupMap/featuresCompatMap.js"
10
9
  import { createRuntimeCompat } from "@jsenv/core/src/internal/generateGroupMap/runtime_compat.js"
11
-
10
+ import { shakeBabelPluginMap } from "@jsenv/core/src/internal/generateGroupMap/shake_babel_plugin_map.js"
12
11
  import { serverUrlToCompileInfo } from "@jsenv/core/src/internal/url_conversion.js"
12
+
13
13
  import { setUrlExtension } from "../url_utils.js"
14
14
  import {
15
15
  COMPILE_ID_BUILD_GLOBAL,
@@ -45,8 +45,12 @@ export const createCompiledFileService = ({
45
45
  moduleOutFormat,
46
46
  importMetaFormat,
47
47
  topLevelAwait,
48
+ prependSystemJs,
48
49
  groupMap,
49
50
  customCompilers,
51
+ workerUrls,
52
+ serviceWorkerUrls,
53
+ importMapInWebWorkers,
50
54
 
51
55
  jsenvEventSourceClientInjection,
52
56
  jsenvToolbarInjection,
@@ -60,6 +64,8 @@ export const createCompiledFileService = ({
60
64
  Object.keys(groupMap).forEach((groupName) => {
61
65
  compileIdModuleFormats[groupName] = canAvoidSystemJs({
62
66
  runtimeSupport: groupMap[groupName].minRuntimeVersions,
67
+ workerUrls,
68
+ importMapInWebWorkers,
63
69
  })
64
70
  ? "esmodule"
65
71
  : "systemjs"
@@ -183,18 +189,20 @@ export const createCompiledFileService = ({
183
189
  outDirectoryRelativeUrl,
184
190
  compileId,
185
191
  request,
186
-
187
- runtimeSupport,
188
- babelPluginMap: babelPluginMapFromCompileId(compileId, {
192
+ babelPluginMap: shakeBabelPluginMap({
189
193
  babelPluginMap,
190
- groupMap,
194
+ missingFeatureNames: groupMap[compileId].missingFeatureNames,
191
195
  }),
196
+ runtimeSupport,
197
+ workerUrls,
198
+ serviceWorkerUrls,
192
199
  moduleOutFormat:
193
200
  moduleOutFormat === undefined
194
201
  ? compileIdModuleFormats[compileId]
195
202
  : moduleOutFormat,
196
203
  importMetaFormat,
197
204
  topLevelAwait,
205
+ prependSystemJs,
198
206
 
199
207
  sourcemapMethod,
200
208
  sourcemapExcludeSources,
@@ -210,18 +218,23 @@ export const createCompiledFileService = ({
210
218
  }
211
219
  }
212
220
 
213
- const canAvoidSystemJs = ({ runtimeSupport }) => {
221
+ const canAvoidSystemJs = ({
222
+ runtimeSupport,
223
+ workerUrls,
224
+ importMapInWebWorkers,
225
+ }) => {
214
226
  const runtimeCompatMap = createRuntimeCompat({
227
+ featureNames: [
228
+ "module",
229
+ "importmap",
230
+ "import_assertion_type_json",
231
+ "import_assertion_type_css",
232
+ ...(workerUrls.length > 0 ? ["worker_type_module"] : []),
233
+ ...(importMapInWebWorkers ? ["worker_importmap"] : []),
234
+ ],
215
235
  runtimeSupport,
216
- pluginMap: {
217
- module: true,
218
- importmap: true,
219
- import_assertion_type_json: true,
220
- import_assertion_type_css: true,
221
- },
222
- pluginCompatMap: featuresCompatMap,
223
236
  })
224
- return runtimeCompatMap.pluginRequiredNameArray.length === 0
237
+ return runtimeCompatMap.missingFeatureNames.length === 0
225
238
  }
226
239
 
227
240
  const getCompiler = ({ originalFileUrl, compileMeta }) => {
@@ -295,31 +308,6 @@ const contentTypeExtensions = {
295
308
  // "text/css": ".css",
296
309
  }
297
310
 
298
- const babelPluginMapFromCompileId = (
299
- compileId,
300
- { babelPluginMap, groupMap },
301
- ) => {
302
- const babelPluginMapForGroup = {}
303
-
304
- groupMap[compileId].pluginRequiredNameArray.forEach((requiredPluginName) => {
305
- const babelPlugin = babelPluginMap[requiredPluginName]
306
- if (babelPlugin) {
307
- babelPluginMapForGroup[requiredPluginName] = babelPlugin
308
- }
309
- })
310
-
311
- Object.keys(babelPluginMap).forEach((key) => {
312
- if (key.startsWith("syntax-")) {
313
- babelPluginMapForGroup[key] = babelPluginMap[key]
314
- }
315
- if (key === "transform-replace-expressions") {
316
- babelPluginMapForGroup[key] = babelPluginMap[key]
317
- }
318
- })
319
-
320
- return babelPluginMapForGroup
321
- }
322
-
323
311
  const ressourceToPathname = (ressource) => {
324
312
  const searchSeparatorIndex = ressource.indexOf("?")
325
313
  const pathname =
@@ -18,7 +18,7 @@ import {
18
18
  urlToFilename,
19
19
  urlIsInsideOf,
20
20
  } from "@jsenv/filesystem"
21
- import { moveImportMap } from "@jsenv/importmap"
21
+ import { composeTwoImportMaps, moveImportMap } from "@jsenv/importmap"
22
22
  import { createDetailedMessage } from "@jsenv/logger"
23
23
 
24
24
  import {
@@ -28,6 +28,8 @@ import {
28
28
  } from "@jsenv/core/dist/build_manifest.js"
29
29
  import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
30
30
  import { stringifyDataUrl } from "@jsenv/core/src/internal/dataUrl.utils.js"
31
+ import { getDefaultImportmap } from "@jsenv/core/src/internal/import-resolution/importmap_default.js"
32
+
31
33
  import {
32
34
  parseHtmlString,
33
35
  parseHtmlAstRessources,
@@ -155,14 +157,13 @@ const transformHTMLSourceFile = async ({
155
157
  fileUrl = urlWithoutSearch(fileUrl)
156
158
 
157
159
  const htmlAst = parseHtmlString(fileContent)
158
- if (inlineImportMapIntoHTML) {
159
- await inlineImportmapScripts({
160
- logger,
161
- htmlAst,
162
- htmlFileUrl: fileUrl,
163
- projectDirectoryUrl,
164
- })
165
- }
160
+ await visitImportmapScripts({
161
+ logger,
162
+ htmlAst,
163
+ inlineImportMapIntoHTML,
164
+ htmlFileUrl: fileUrl,
165
+ projectDirectoryUrl,
166
+ })
166
167
 
167
168
  const browserRuntimeBuildUrlRelativeToProject = urlToRelativeUrl(
168
169
  BROWSER_RUNTIME_BUILD_URL,
@@ -277,59 +278,73 @@ const transformHTMLSourceFile = async ({
277
278
  return stringifyHtmlAst(htmlAst)
278
279
  }
279
280
 
280
- const inlineImportmapScripts = async ({ logger, htmlAst, htmlFileUrl }) => {
281
+ const visitImportmapScripts = async ({
282
+ logger,
283
+ inlineImportMapIntoHTML,
284
+ htmlAst,
285
+ htmlFileUrl,
286
+ projectDirectoryUrl,
287
+ }) => {
281
288
  const { scripts } = parseHtmlAstRessources(htmlAst)
282
- const remoteImportmapScripts = scripts.filter((script) => {
289
+ const importmapScripts = scripts.filter((script) => {
283
290
  const typeAttribute = getHtmlNodeAttributeByName(script, "type")
284
- const srcAttribute = getHtmlNodeAttributeByName(script, "src")
285
- if (typeAttribute && typeAttribute.value === "importmap" && srcAttribute) {
291
+ if (typeAttribute && typeAttribute.value === "importmap") {
286
292
  return true
287
293
  }
288
294
  return false
289
295
  })
290
296
 
291
297
  await Promise.all(
292
- remoteImportmapScripts.map(async (remoteImportmapScript) => {
293
- const srcAttribute = getHtmlNodeAttributeByName(
294
- remoteImportmapScript,
295
- "src",
296
- )
297
- const importMapUrl = resolveUrl(srcAttribute.value, htmlFileUrl)
298
- const importMapResponse = await fetchUrl(importMapUrl)
299
- if (importMapResponse.status !== 200) {
300
- logger.warn(
301
- createDetailedMessage(
302
- importMapResponse.status === 404
303
- ? `Cannot inline importmap script because file cannot be found.`
304
- : `Cannot inline importmap script due to unexpected response status (${importMapResponse.status}).`,
305
- {
306
- "importmap script src": srcAttribute.value,
307
- "importmap url": importMapUrl,
308
- "html url": htmlFileUrl,
309
- },
310
- ),
298
+ importmapScripts.map(async (importmapScript) => {
299
+ const srcAttribute = getHtmlNodeAttributeByName(importmapScript, "src")
300
+ if (srcAttribute && inlineImportMapIntoHTML) {
301
+ const importMapUrl = resolveUrl(srcAttribute.value, htmlFileUrl)
302
+ const importMapResponse = await fetchUrl(importMapUrl)
303
+ if (importMapResponse.status !== 200) {
304
+ logger.warn(
305
+ createDetailedMessage(
306
+ importMapResponse.status === 404
307
+ ? `Cannot inline importmap script because file cannot be found.`
308
+ : `Cannot inline importmap script due to unexpected response status (${importMapResponse.status}).`,
309
+ {
310
+ "importmap script src": srcAttribute.value,
311
+ "importmap url": importMapUrl,
312
+ "html url": htmlFileUrl,
313
+ },
314
+ ),
315
+ )
316
+ return
317
+ }
318
+
319
+ const importMapContent = await importMapResponse.json()
320
+ const importMapInlined = moveImportMap(
321
+ importMapContent,
322
+ importMapUrl,
323
+ htmlFileUrl,
311
324
  )
312
- return
313
- }
314
325
 
315
- const importMapContent = await importMapResponse.json()
316
- const importMapInlined = moveImportMap(
317
- importMapContent,
318
- importMapUrl,
319
- htmlFileUrl,
320
- )
326
+ replaceHtmlNode(
327
+ importmapScript,
328
+ `<script type="importmap">${JSON.stringify(
329
+ importMapInlined,
330
+ null,
331
+ " ",
332
+ )}</script>`,
333
+ {
334
+ attributesToIgnore: ["src"],
335
+ },
336
+ )
337
+ }
321
338
 
322
- replaceHtmlNode(
323
- remoteImportmapScript,
324
- `<script type="importmap">${JSON.stringify(
325
- importMapInlined,
326
- null,
327
- " ",
328
- )}</script>`,
329
- {
330
- attributesToIgnore: ["src"],
331
- },
332
- )
339
+ const textNode = getHtmlNodeTextNode(importmapScript)
340
+ if (!srcAttribute && textNode) {
341
+ const jsenvImportmap = getDefaultImportmap(htmlFileUrl, {
342
+ projectDirectoryUrl,
343
+ })
344
+ const htmlImportmap = JSON.parse(textNode.value)
345
+ const importmap = composeTwoImportMaps(jsenvImportmap, htmlImportmap)
346
+ textNode.value = JSON.stringify(importmap, null, " ")
347
+ }
333
348
  }),
334
349
  )
335
350
  }
@@ -0,0 +1,23 @@
1
+ import { readFileSync } from "node:fs"
2
+
3
+ import { jsenvCoreDirectoryUrl } from "@jsenv/core/src/internal/jsenvCoreDirectoryUrl.js"
4
+
5
+ export const babelPluginSystemJsPrepend = (api) => {
6
+ api.assertVersion(7)
7
+ const systemJsUrl = new URL(
8
+ "src/internal/runtime/s.js",
9
+ jsenvCoreDirectoryUrl,
10
+ )
11
+ return {
12
+ name: "systemjs-prepend",
13
+ visitor: {
14
+ Program: {
15
+ exit(path) {
16
+ const code = String(readFileSync(systemJsUrl))
17
+ const ast = api.template.ast`${code}`
18
+ path.node.body.unshift(ast)
19
+ },
20
+ },
21
+ },
22
+ }
23
+ }
@@ -11,6 +11,7 @@ import { babelPluginImportMetadata } from "@jsenv/core/src/internal/compiling/ba
11
11
  import { ansiToHTML } from "./ansiToHTML.js"
12
12
  import { babelPluginRegeneratorRuntimeAsJsenvImport } from "./babel_plugin_regenerator_runtime_as_jsenv_import.js"
13
13
  import { babelPluginBabelHelpersAsJsenvImports } from "./babel_plugin_babel_helpers_as_jsenv_imports.js"
14
+ import { babelPluginSystemJsPrepend } from "./babel_plugin_systemjs_prepend.js"
14
15
  import { filePathToBabelHelperName } from "./babelHelper.js"
15
16
 
16
17
  export const jsenvTransform = async ({
@@ -26,6 +27,7 @@ export const jsenvTransform = async ({
26
27
  topLevelAwait,
27
28
 
28
29
  babelHelpersInjectionAsImport,
30
+ prependSystemJs,
29
31
  transformGenerator,
30
32
  regeneratorRuntimeImportPath,
31
33
  sourcemapEnabled,
@@ -77,7 +79,6 @@ export const jsenvTransform = async ({
77
79
  ],
78
80
  }
79
81
  }
80
-
81
82
  babelPluginMap = {
82
83
  ...getMinimalBabelPluginMap(),
83
84
  "transform-import-meta": [
@@ -147,6 +148,19 @@ export const jsenvTransform = async ({
147
148
  : {}),
148
149
  "import-metadata": [babelPluginImportMetadata],
149
150
  }
151
+ if (moduleOutFormat === "systemjs") {
152
+ babelPluginMap = {
153
+ ...babelPluginMap,
154
+ "proposal-dynamic-import": [proposalDynamicImport],
155
+ "transform-modules-systemjs": [transformModulesSystemJs],
156
+ }
157
+ }
158
+ if (prependSystemJs) {
159
+ babelPluginMap = {
160
+ ...babelPluginMap,
161
+ "systemjs-prepend": [babelPluginSystemJsPrepend],
162
+ }
163
+ }
150
164
 
151
165
  const asyncToPromise = babelPluginMap["transform-async-to-promises"]
152
166
  if (topLevelAwait && asyncToPromise) {
@@ -158,17 +172,7 @@ export const jsenvTransform = async ({
158
172
  code,
159
173
  options: {
160
174
  ...options,
161
- plugins: babelPluginsFromBabelPluginMap({
162
- ...babelPluginMap,
163
- ...(moduleOutFormat === "systemjs"
164
- ? {
165
- "proposal-dynamic-import": [proposalDynamicImport],
166
- ...(moduleOutFormat === "systemjs"
167
- ? { "transform-modules-systemjs": [transformModulesSystemJs] }
168
- : {}),
169
- }
170
- : {}),
171
- }),
175
+ plugins: babelPluginsFromBabelPluginMap(babelPluginMap),
172
176
  },
173
177
  })
174
178
  code = babelTransformReturnValue.code
@@ -12,6 +12,7 @@ export const transformJs = async ({
12
12
  moduleOutFormat = "esmodule",
13
13
  importMetaFormat = moduleOutFormat,
14
14
  babelHelpersInjectionAsImport = moduleOutFormat === "esmodule",
15
+ prependSystemJs,
15
16
  topLevelAwait,
16
17
  transformGenerator = true,
17
18
  sourcemapEnabled = true,
@@ -51,6 +52,7 @@ export const transformJs = async ({
51
52
  importMetaFormat,
52
53
 
53
54
  babelHelpersInjectionAsImport,
55
+ prependSystemJs,
54
56
  topLevelAwait,
55
57
  transformGenerator,
56
58
  sourcemapEnabled,
@@ -8,7 +8,7 @@ import {
8
8
  TOOLBAR_INJECTOR_BUILD_URL,
9
9
  } from "@jsenv/core/dist/build_manifest.js"
10
10
  import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
11
- import { getDefaultImportMap } from "@jsenv/core/src/internal/import-resolution/importmap-default.js"
11
+ import { getDefaultImportmap } from "@jsenv/core/src/internal/import-resolution/importmap_default.js"
12
12
 
13
13
  import {
14
14
  setJavaScriptSourceMappingUrl,
@@ -120,83 +120,82 @@ export const compileHtml = async ({
120
120
  importmapInfo = {
121
121
  script,
122
122
  url: resolveUrl(src, url),
123
- loadAsText: async () => {
123
+ load: async () => {
124
124
  const importMapResponse = await fetchUrl(importmapInfo.url)
125
- if (importMapResponse.status !== 200) {
126
- logger.warn(
127
- createDetailedMessage(
128
- importMapResponse.status === 404
129
- ? `importmap script file cannot be found.`
130
- : `importmap script file unexpected response status (${importMapResponse.status}).`,
131
- {
132
- "importmap url": importmapInfo.url,
133
- "html url": url,
134
- },
135
- ),
125
+ if (importMapResponse.status === 200) {
126
+ const importmapAsText = await importMapResponse.text()
127
+ let htmlImportmap = JSON.parse(importmapAsText)
128
+ htmlImportmap = moveImportMap(
129
+ htmlImportmap,
130
+ importmapInfo.url,
131
+ url,
136
132
  )
137
- return "{}"
133
+ sources.push(importmapInfo.url)
134
+ sourcesContent.push(importmapAsText)
135
+ return htmlImportmap
138
136
  }
139
- const importmapAsText = await importMapResponse.text()
140
- sources.push(importmapInfo.url)
141
- sourcesContent.push(importmapAsText)
142
-
143
- const importMapMoved = moveImportMap(
144
- JSON.parse(importmapAsText),
145
- importmapInfo.url,
146
- url,
147
- )
148
- const compiledImportmapAsText = JSON.stringify(
149
- importMapMoved,
150
- null,
151
- " ",
137
+ logger.warn(
138
+ createDetailedMessage(
139
+ importMapResponse.status === 404
140
+ ? `importmap script file cannot be found.`
141
+ : `importmap script file unexpected response status (${importMapResponse.status}).`,
142
+ {
143
+ "importmap url": importmapInfo.url,
144
+ "html url": url,
145
+ },
146
+ ),
152
147
  )
153
- return compiledImportmapAsText
148
+ return {}
154
149
  },
155
150
  }
156
151
  } else {
157
152
  importmapInfo = {
158
153
  script,
159
154
  url: compiledUrl,
160
- loadAsText: () => getHtmlNodeTextNode(script).value,
155
+ load: () => {
156
+ const jsenvImportmap = getDefaultImportmap(compiledUrl, {
157
+ projectDirectoryUrl,
158
+ compileDirectoryUrl: `${projectDirectoryUrl}${compileId}/${outDirectoryRelativeUrl}`,
159
+ })
160
+ const htmlImportmap = JSON.parse(
161
+ getHtmlNodeTextNode(script).value,
162
+ )
163
+ const importmap = composeTwoImportMaps(
164
+ jsenvImportmap,
165
+ htmlImportmap,
166
+ )
167
+ return importmap
168
+ },
161
169
  }
162
170
  }
163
171
  }
164
172
  }
165
173
  })
166
174
  if (importmapInfo) {
167
- const htmlImportMap = JSON.parse(await importmapInfo.loadAsText())
168
- const importMapFromJsenv = getDefaultImportMap({
169
- importMapFileUrl: compiledUrl,
170
- projectDirectoryUrl,
171
- compileDirectoryRelativeUrl: `${outDirectoryRelativeUrl}${compileId}/`,
172
- })
173
- const mappings = composeTwoImportMaps(importMapFromJsenv, htmlImportMap)
174
- const importmapAsText = JSON.stringify(mappings, null, " ")
175
+ const importmap = await importmapInfo.load()
176
+ const importmapAsText = JSON.stringify(importmap, null, " ")
175
177
  replaceHtmlNode(
176
178
  importmapInfo.script,
177
179
  `<script type="${
178
- moduleOutFormat === "systemjs" ? "jsenv-importmap" : "importmap"
180
+ moduleOutFormat === "systemjs" ? "systemjs-importmap" : "importmap"
179
181
  }">${importmapAsText}</script>`,
180
182
  {
181
183
  attributesToIgnore: ["src"],
182
184
  },
183
185
  )
184
186
  importmapInfo.inlinedFrom = importmapInfo.url
185
- importmapInfo.url = compiledUrl
186
187
  importmapInfo.text = importmapAsText
187
188
  } else {
188
- // inject a default importmap
189
- const defaultImportMap = getDefaultImportMap({
190
- importMapFileUrl: compiledUrl,
189
+ const defaultImportMap = getDefaultImportmap(compiledUrl, {
191
190
  projectDirectoryUrl,
192
- compileDirectoryRelativeUrl: `${outDirectoryRelativeUrl}${compileId}/`,
191
+ compileDirectoryUrl: `${projectDirectoryUrl}${outDirectoryRelativeUrl}${compileId}/`,
193
192
  })
194
193
  const importmapAsText = JSON.stringify(defaultImportMap, null, " ")
195
194
  manipulateHtmlAst(htmlAst, {
196
195
  scriptInjections: [
197
196
  {
198
197
  type:
199
- moduleOutFormat === "systemjs" ? "jsenv-importmap" : "importmap",
198
+ moduleOutFormat === "systemjs" ? "systemjs-importmap" : "importmap",
200
199
  // in case there is no importmap, force the presence
201
200
  // so that '@jsenv/core/' are still remapped
202
201
  text: importmapAsText,