@jsenv/core 24.6.2 → 25.0.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.
Files changed (57) hide show
  1. package/dist/browser_runtime/asset-manifest.json +2 -1
  2. package/dist/browser_runtime/{browser_runtime-c7288751.js → browser_runtime_a8097085.js} +37 -27
  3. package/dist/browser_runtime/{browser_runtime-c7288751.js.map → browser_runtime_a8097085.js.map} +3 -3
  4. package/dist/build_manifest.js +6 -6
  5. package/dist/compile_proxy/asset-manifest.json +2 -1
  6. package/dist/compile_proxy/{compile_proxy-a3969633.html → compile_proxy_e16d7de8.html} +39 -34
  7. package/dist/compile_proxy/{compile_proxy.html__inline__20-9c92c170.js.map → compile_proxy_e3b0c442_9e168143.js.map} +3 -2
  8. package/dist/event_source_client/asset-manifest.json +2 -1
  9. package/dist/event_source_client/{event_source_client-9f14c8b9.js → event_source_client_620fbc2c.js} +1 -1
  10. package/dist/event_source_client/{event_source_client-9f14c8b9.js.map → event_source_client_620fbc2c.js.map} +1 -1
  11. package/dist/redirector/asset-manifest.json +2 -1
  12. package/dist/redirector/{redirector-a6b8d640.html → redirector_2e0c8abe.html} +39 -34
  13. package/dist/redirector/{redirector.html__inline__15-58430672.js.map → redirector_e3b0c442_3a34a156.js.map} +3 -2
  14. package/dist/toolbar/asset-manifest.json +11 -10
  15. package/dist/toolbar/assets/{compilation.css-209d68b4.map → compilation.css_e37c747b.map} +1 -1
  16. package/dist/toolbar/assets/{eventsource.css-38cd0a36.map → eventsource.css_c0c71e7b.map} +1 -1
  17. package/dist/toolbar/assets/{execution.css-0ebe522f.map → execution.css_f3377c10.map} +1 -1
  18. package/dist/toolbar/assets/{focus.css-3f9c156d.map → focus.css_896f3e45.map} +1 -1
  19. package/dist/toolbar/assets/{light-theme.css-78b19a80.map → light-theme.css_72a60fa3.map} +1 -1
  20. package/dist/toolbar/assets/{overflow-menu.css-d9688a1c.map → overflow-menu.css_2859d519.map} +1 -1
  21. package/dist/toolbar/assets/{settings.css-2b81b245.map → settings.css_61548139.map} +1 -1
  22. package/dist/toolbar/assets/{toolbar.main.css-846920e9.map → toolbar.main.css_269d7ce2.map} +9 -9
  23. package/dist/toolbar/assets/{tooltip.css-03395ee6.map → tooltip.css_a94a8bdd.map} +1 -1
  24. package/dist/toolbar/{toolbar.main-7aa01366.js.map → toolbar.main_a5ef2c60.js.map} +3 -2
  25. package/dist/toolbar/{toolbar-84985f43.html → toolbar_412abb83.html} +87 -64
  26. package/dist/toolbar_injector/asset-manifest.json +3 -2
  27. package/dist/toolbar_injector/assets/{jsenv-logo-188b9ca6.svg → jsenv-logo_188b9ca6.svg} +0 -0
  28. package/dist/toolbar_injector/{toolbar_injector-8edcae04.js → toolbar_injector_4f9c19e5.js} +17 -17
  29. package/dist/toolbar_injector/{toolbar_injector-8edcae04.js.map → toolbar_injector_4f9c19e5.js.map} +4 -4
  30. package/package.json +5 -4
  31. package/readme.md +12 -22
  32. package/src/buildProject.js +21 -21
  33. package/src/dev_server.js +6 -2
  34. package/src/internal/building/buildUsingRollup.js +24 -18
  35. package/src/internal/building/build_logs.js +2 -2
  36. package/src/internal/building/build_stats.js +11 -1
  37. package/src/internal/building/html/parseHtmlRessource.js +2 -26
  38. package/src/internal/building/js/parseJsRessource.js +3 -2
  39. package/src/internal/building/json_module.js +11 -0
  40. package/src/internal/building/parseRessource.js +1 -1
  41. package/src/internal/building/ressource_builder.js +216 -215
  42. package/src/internal/building/rollup_plugin_jsenv.js +522 -354
  43. package/src/internal/building/url_loader.js +8 -142
  44. package/src/internal/building/url_versioning.js +226 -0
  45. package/src/internal/compiling/compileHtml.js +8 -1
  46. package/src/internal/compiling/createCompiledFileService.js +7 -7
  47. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +9 -55
  48. package/src/internal/compiling/js-compilation-service/transformJs.js +8 -5
  49. package/src/internal/compiling/jsenvCompilerForHtml.js +4 -4
  50. package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -2
  51. package/src/internal/compiling/startCompileServer.js +2 -2
  52. package/src/jsenvServiceWorkerFinalizer.js +7 -8
  53. package/src/internal/building/asset_url_versioning.js +0 -50
  54. package/src/internal/building/rollup_build_sourcemap.js +0 -54
  55. package/src/internal/building/url-versioning.js +0 -96
  56. package/src/internal/compiling/js-compilation-service/findAsyncPluginNameInBabelPluginMap.js +0 -9
  57. package/src/internal/renderNamePattern.js +0 -6
@@ -4,7 +4,6 @@ import { normalizeImportMap } from "@jsenv/importmap"
4
4
  import { isSpecifierForNodeCoreModule } from "@jsenv/importmap/src/isSpecifierForNodeCoreModule.js"
5
5
  import { createDetailedMessage, loggerToLogLevel } from "@jsenv/logger"
6
6
  import {
7
- isFileSystemPath,
8
7
  fileSystemPathToUrl,
9
8
  resolveUrl,
10
9
  urlToRelativeUrl,
@@ -14,16 +13,19 @@ import {
14
13
  normalizeStructuredMetaMap,
15
14
  urlToMeta,
16
15
  urlToBasename,
16
+ urlToFilename,
17
17
  } from "@jsenv/filesystem"
18
18
  import { UNICODE } from "@jsenv/log"
19
19
 
20
+ import { convertJsonTextToJavascriptModule } from "@jsenv/core/src/internal/building/json_module.js"
21
+ import { convertCssTextToJavascriptModule } from "@jsenv/core/src/internal/building/css_module.js"
22
+ import { transformJs } from "@jsenv/core/src/internal/compiling/js-compilation-service/transformJs.js"
20
23
  import { createUrlConverter } from "@jsenv/core/src/internal/url_conversion.js"
21
24
  import { createUrlFetcher } from "@jsenv/core/src/internal/building/url_fetcher.js"
22
25
  import { createUrlLoader } from "@jsenv/core/src/internal/building/url_loader.js"
23
26
  import { stringifyUrlTrace } from "@jsenv/core/src/internal/building/url_trace.js"
24
27
  import { sortObjectByPathnames } from "@jsenv/core/src/internal/building/sortObjectByPathnames.js"
25
28
  import { jsenvHelpersDirectoryInfo } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
26
- import { setUrlSearchParamsDescriptor } from "@jsenv/core/src/internal/url_utils.js"
27
29
 
28
30
  import {
29
31
  formatBuildStartLog,
@@ -39,21 +41,20 @@ import {
39
41
  referenceToCodeForRollup,
40
42
  } from "./ressource_builder.js"
41
43
 
42
- import { computeBuildRelativeUrl } from "./url-versioning.js"
44
+ import { createUrlVersioner } from "./url_versioning.js"
43
45
  import { visitImportReferences } from "./import_references.js"
44
46
 
45
47
  import { createImportResolverForNode } from "../import-resolution/import-resolver-node.js"
46
48
  import { createImportResolverForImportmap } from "../import-resolution/import-resolver-importmap.js"
47
49
  import { getDefaultImportMap } from "../import-resolution/importmap-default.js"
48
- import { injectSourcemapInRollupBuild } from "./rollup_build_sourcemap.js"
49
50
  import { createBuildStats } from "./build_stats.js"
50
51
 
51
- export const createJsenvRollupPlugin = async ({
52
+ export const createRollupPlugins = async ({
52
53
  buildOperation,
53
54
  logger,
54
55
 
55
56
  projectDirectoryUrl,
56
- entryPointMap,
57
+ entryPoints,
57
58
  compileServerOrigin,
58
59
  compileDirectoryRelativeUrl,
59
60
  buildDirectoryUrl,
@@ -68,16 +69,16 @@ export const createJsenvRollupPlugin = async ({
68
69
  workers,
69
70
  serviceWorkers,
70
71
  serviceWorkerFinalizer,
72
+ classicWorkers,
73
+ classicServiceWorkers,
71
74
 
72
75
  format,
73
76
  systemJsUrl,
74
77
  babelPluginMap,
75
- transformTopLevelAwait,
76
78
  node,
77
79
  importAssertionsSupport,
78
80
 
79
81
  urlVersioning,
80
- urlVersionningForEntryPoints,
81
82
  lineBreakNormalization,
82
83
  jsConcatenation,
83
84
  cssConcatenation,
@@ -101,14 +102,34 @@ export const createJsenvRollupPlugin = async ({
101
102
  lastErrorMessage = error.message
102
103
  }
103
104
 
104
- const workerUrls = Object.keys(workers).map((key) =>
105
- resolveUrl(key, projectDirectoryUrl),
106
- )
107
- const serviceWorkerUrls = Object.keys(serviceWorkers).map((key) =>
108
- resolveUrl(key, projectDirectoryUrl),
109
- )
110
- const isWorkerUrl = (url) => workerUrls.includes(url)
111
- const isServiceWorkerUrl = (url) => serviceWorkerUrls.includes(url)
105
+ const extension = extname(entryPoints[Object.keys(entryPoints)[0]])
106
+ const outputExtension = extension === ".html" ? ".js" : extension
107
+
108
+ const entryPointUrls = {}
109
+ Object.keys(entryPoints).forEach((key) => {
110
+ const url = resolveUrl(key, projectDirectoryUrl)
111
+ entryPointUrls[url] = entryPoints[key]
112
+ })
113
+ const workerUrls = {}
114
+ Object.keys(workers).forEach((key) => {
115
+ const url = resolveUrl(key, projectDirectoryUrl)
116
+ workerUrls[url] = workers[key]
117
+ })
118
+ const serviceWorkerUrls = {}
119
+ Object.keys(serviceWorkers).forEach((key) => {
120
+ const url = resolveUrl(key, projectDirectoryUrl)
121
+ serviceWorkerUrls[url] = serviceWorkers[key]
122
+ })
123
+ const classicWorkerUrls = {}
124
+ Object.keys(classicWorkers).forEach((key) => {
125
+ const url = resolveUrl(key, projectDirectoryUrl)
126
+ classicWorkerUrls[url] = classicWorkers[key]
127
+ })
128
+ const classicServiceWorkerUrls = {}
129
+ Object.keys(classicServiceWorkers).forEach((key) => {
130
+ const url = resolveUrl(key, projectDirectoryUrl)
131
+ classicServiceWorkerUrls[url] = classicServiceWorkers[key]
132
+ })
112
133
 
113
134
  let ressourceBuilder
114
135
  let importResolver
@@ -132,6 +153,16 @@ export const createJsenvRollupPlugin = async ({
132
153
  urlMappings,
133
154
  })
134
155
 
156
+ const urlVersioner = createUrlVersioner({
157
+ entryPointUrls,
158
+ workerUrls,
159
+ classicWorkerUrls,
160
+ serviceWorkerUrls,
161
+ classicServiceWorkerUrls,
162
+ asOriginalUrl,
163
+ lineBreakNormalization,
164
+ })
165
+
135
166
  const urlFetcher = createUrlFetcher({
136
167
  asOriginalUrl,
137
168
  asProjectUrl,
@@ -142,13 +173,11 @@ export const createJsenvRollupPlugin = async ({
142
173
  },
143
174
  })
144
175
 
176
+ const urlCustomLoaders = {}
145
177
  const urlLoader = createUrlLoader({
146
- projectDirectoryUrl,
147
- buildDirectoryUrl,
148
- babelPluginMap,
178
+ urlCustomLoaders,
149
179
  allowJson: acceptsJsonContentType({ node, format }),
150
180
  urlImporterMap,
151
- inlineModuleScripts,
152
181
  jsConcatenation,
153
182
 
154
183
  asServerUrl,
@@ -163,41 +192,33 @@ export const createJsenvRollupPlugin = async ({
163
192
  projectDirectoryUrl,
164
193
  )
165
194
 
166
- // map fileName (build relative urls without hash) to build relative url
195
+ // map build relative urls without hash (called "ressourceName") to real build relative urls
167
196
  let buildManifest = {}
168
- const buildRelativeUrlToFileName = (buildRelativeUrl) => {
169
- const fileName = Object.keys(buildManifest).find(
170
- (key) => buildManifest[key] === buildRelativeUrl,
171
- )
172
- return fileName
173
- }
174
- const buildRelativeUrlsUsedInJs = []
175
- const markBuildRelativeUrlAsUsedByJs = (buildRelativeUrl) => {
176
- buildRelativeUrlsUsedInJs.push(buildRelativeUrl)
177
- buildManifest[rollupFileNameWithoutHash(buildRelativeUrl)] =
178
- buildRelativeUrl
179
- }
197
+
198
+ const ressourcesReferencedByJs = []
180
199
  const createImportMapForFilesUsedInJs = () => {
181
200
  const topLevelMappings = {}
182
- buildRelativeUrlsUsedInJs
183
- .sort(comparePathnames)
184
- .forEach((buildRelativeUrl) => {
185
- const fileName = buildRelativeUrlToFileName(buildRelativeUrl)
186
- if (fileName !== buildRelativeUrl) {
187
- topLevelMappings[`./${fileName}`] = `./${buildRelativeUrl}`
188
- }
189
- })
201
+ ressourcesReferencedByJs.sort(comparePathnames).forEach((ressourceName) => {
202
+ const buildRelativeUrl = buildManifest[ressourceName]
203
+ if (
204
+ ressourceName &&
205
+ buildRelativeUrl &&
206
+ ressourceName !== buildRelativeUrl
207
+ ) {
208
+ topLevelMappings[`./${ressourceName}`] = `./${buildRelativeUrl}`
209
+ }
210
+ })
190
211
  return {
191
212
  imports: topLevelMappings,
192
213
  }
193
214
  }
194
215
 
195
- let buildMappings = {}
196
216
  // an object where keys are build relative urls
197
217
  // and values rollup chunk or asset
198
218
  // we need this because we sometimes tell rollup
199
219
  // that a file.fileName is something while it's not really this
200
220
  // because of remapping
221
+ let buildMappings = {}
201
222
  let rollupBuild
202
223
 
203
224
  const EMPTY_CHUNK_URL = resolveUrl("__empty__", projectDirectoryUrl)
@@ -239,8 +260,40 @@ export const createJsenvRollupPlugin = async ({
239
260
  let minifyJs
240
261
  let minifyHtml
241
262
 
242
- const jsenvRollupPlugin = {}
243
-
263
+ const rollupPlugins = []
264
+ // When format is systemjs, rollup add async/await
265
+ // that might be unsupported by the runtime.
266
+ // in that case we have to transform the rollup output
267
+ if (babelPluginMap["transform-async-to-promises"] && format === "systemjs") {
268
+ rollupPlugins.push({
269
+ name: "jsenv_fix_async_await",
270
+ async renderChunk(code, chunk) {
271
+ let map = chunk.map
272
+ const result = await transformJs({
273
+ code,
274
+ url: chunk.facadeModuleId
275
+ ? asOriginalUrl(chunk.facadeModuleId)
276
+ : resolveUrl(chunk.fileName, buildDirectoryUrl),
277
+ projectDirectoryUrl,
278
+ babelPluginMap: {
279
+ "transform-async-to-promises":
280
+ babelPluginMap["transform-async-to-promises"],
281
+ },
282
+ // pass undefined when format is "systemjs" to avoid
283
+ // re-wrapping the code in systemjs format
284
+ moduleOutFormat: undefined,
285
+ babelHelpersInjectionAsImport: false,
286
+ transformGenerator: false,
287
+ })
288
+ code = result.code
289
+ map = result.map
290
+ return {
291
+ code,
292
+ map,
293
+ }
294
+ },
295
+ })
296
+ }
244
297
  if (minify) {
245
298
  const methodHooks = {
246
299
  minifyJs: async (...args) => {
@@ -271,33 +324,35 @@ export const createJsenvRollupPlugin = async ({
271
324
  return methodHooks.minifyHtml(html, minifyHtmlOptions)
272
325
  }
273
326
 
274
- jsenvRollupPlugin.renderChunk = async (code, chunk) => {
275
- let map = chunk.map
276
- const result = await minifyJs({
277
- url: chunk.facadeModuleId
278
- ? asOriginalUrl(chunk.facadeModuleId)
279
- : resolveUrl(chunk.fileName, buildDirectoryUrl),
280
- code,
281
- map,
282
- ...(format === "global" ? { toplevel: false } : { toplevel: true }),
283
- })
327
+ rollupPlugins.push({
328
+ name: "jsenv_minifier",
329
+ async renderChunk(code, chunk) {
330
+ let map = chunk.map
331
+ const result = await minifyJs({
332
+ url: chunk.facadeModuleId
333
+ ? asOriginalUrl(chunk.facadeModuleId)
334
+ : resolveUrl(chunk.fileName, buildDirectoryUrl),
335
+ code,
336
+ map,
337
+ ...(format === "global" ? { toplevel: false } : { toplevel: true }),
338
+ })
284
339
 
285
- code = result.code
286
- map = result.map
287
- return {
288
- code,
289
- map,
290
- }
291
- }
340
+ code = result.code
341
+ map = result.map
342
+ return {
343
+ code,
344
+ map,
345
+ }
346
+ },
347
+ })
292
348
  }
293
-
294
- Object.assign(jsenvRollupPlugin, {
349
+ rollupPlugins.unshift({
295
350
  name: "jsenv",
296
351
 
297
352
  async buildStart() {
298
- logger.info(formatBuildStartLog({ entryPointMap }))
353
+ logger.info(formatBuildStartLog({ entryPoints }))
299
354
 
300
- const entryPointsPrepared = await prepareEntryPoints(entryPointMap, {
355
+ const entryPointsPrepared = await prepareEntryPoints(entryPoints, {
301
356
  logger,
302
357
  projectDirectoryUrl,
303
358
  buildDirectoryUrl,
@@ -326,7 +381,7 @@ export const createJsenvRollupPlugin = async ({
326
381
  if (typeof useImportMapToMaximizeCacheReuse === "undefined") {
327
382
  useImportMapToMaximizeCacheReuse =
328
383
  htmlEntryPointCount > 0 &&
329
- // node has no importmap concept, le'ts use the versionned url in that case
384
+ // node has no importmap concept, let's use the versionned url in that case
330
385
  !node
331
386
  }
332
387
 
@@ -425,7 +480,7 @@ export const createJsenvRollupPlugin = async ({
425
480
  )
426
481
  }
427
482
  } else {
428
- // there is no importmap, its' fine it's not mandatory to use one
483
+ // there is no importmap, it's fine, it's not mandatory
429
484
  fetchImportMap = () => {
430
485
  const firstEntryPoint = htmlEntryPoints[0] || entryPointsPrepared[0]
431
486
  const { entryProjectRelativeUrl } = firstEntryPoint
@@ -569,13 +624,32 @@ export const createJsenvRollupPlugin = async ({
569
624
  }
570
625
 
571
626
  const originalUrl = asOriginalUrl(projectUrl)
572
- if (isWorkerUrl(originalUrl)) {
627
+ const workerBuildRelativeUrl = workerUrls[originalUrl]
628
+ if (workerBuildRelativeUrl) {
629
+ return {
630
+ isWorker: true,
631
+ isJsModule: true,
632
+ url: ressourceUrl,
633
+ }
634
+ }
635
+ const serviceWorkerBuildRelativeUrl = serviceWorkerUrls[originalUrl]
636
+ if (serviceWorkerBuildRelativeUrl) {
637
+ return {
638
+ isServiceWorker: true,
639
+ isJsModule: true,
640
+ url: ressourceUrl,
641
+ }
642
+ }
643
+ const classicWorkerBuildRelativeUrl = classicWorkerUrls[originalUrl]
644
+ if (classicWorkerBuildRelativeUrl) {
573
645
  return {
574
646
  isWorker: true,
575
647
  url: ressourceUrl,
576
648
  }
577
649
  }
578
- if (isServiceWorkerUrl(originalUrl)) {
650
+ const classicServiceWorkerBuildRelativeUrl =
651
+ classicServiceWorkerUrls[originalUrl]
652
+ if (classicServiceWorkerBuildRelativeUrl) {
579
653
  return {
580
654
  isServiceWorker: true,
581
655
  url: ressourceUrl,
@@ -584,34 +658,79 @@ export const createJsenvRollupPlugin = async ({
584
658
 
585
659
  return ressourceUrl
586
660
  },
587
- emitChunk,
588
- emitAsset,
589
- setAssetSource,
590
661
  onJsModule: ({ ressource, jsModuleUrl, jsModuleIsInline }) => {
591
- if (jsModuleIsInline) {
592
- inlineModuleScripts[jsModuleUrl] = ressource
662
+ // we want to emit chunk only when ressource is referenced by something else than rollup
663
+ if (
664
+ jsConcatenation &&
665
+ ressource.references.every((ref) => ref.fromRollup)
666
+ ) {
667
+ return null
593
668
  }
594
669
 
595
- urlImporterMap[jsModuleUrl] = {
596
- url: resolveUrl(
670
+ if (ressource.isEntryPoint) {
671
+ } else {
672
+ const importerUrl = resolveUrl(
597
673
  entryPointsPrepared[0].entryProjectRelativeUrl,
598
674
  compileDirectoryServerUrl,
599
- ),
600
- line: undefined,
601
- column: undefined,
675
+ )
676
+ urlImporterMap[jsModuleUrl] = {
677
+ url: importerUrl,
678
+ line: undefined,
679
+ column: undefined,
680
+ }
681
+ jsModulesFromEntry[asRollupUrl(jsModuleUrl)] = true
682
+ if (jsModuleIsInline) {
683
+ inlineModuleScripts[jsModuleUrl] = ressource
684
+ urlCustomLoaders[jsModuleUrl] = async () => {
685
+ const transformResult = await transformJs({
686
+ code: String(
687
+ inlineModuleScripts[jsModuleUrl].bufferBeforeBuild,
688
+ ),
689
+ url: asOriginalUrl(jsModuleUrl), // transformJs expect a file:// url
690
+ projectDirectoryUrl,
691
+ babelPluginMap,
692
+ // moduleOutFormat: format // we are compiling for rollup output must be "esmodule"
693
+ // we compile for rollup, let top level await untouched
694
+ // it will be converted, if needed, during "renderChunk" hook
695
+ topLevelAwait: "ignore",
696
+ })
697
+ let code = transformResult.code
698
+ let map = transformResult.map
699
+ return {
700
+ code,
701
+ map,
702
+ }
703
+ }
704
+ }
602
705
  }
603
- jsModulesFromEntry[asRollupUrl(jsModuleUrl)] = true
604
- const name = urlToBasename(jsModuleUrl)
706
+
707
+ const fileName = ressource.relativeUrl
605
708
  const rollupReferenceId = emitChunk({
606
- id: asRollupUrl(jsModuleUrl),
607
- name,
709
+ id: jsModuleUrl,
710
+ name: urlToBasename(jsModuleUrl),
608
711
  })
609
712
  return {
610
- name,
611
713
  rollupReferenceId,
714
+ fileName,
612
715
  }
613
716
  },
614
- lineBreakNormalization,
717
+ onAsset: ({ ressource }) => {
718
+ const fileName = ressource.relativeUrl
719
+ const rollupReferenceId = emitAsset({
720
+ fileName,
721
+ })
722
+ return {
723
+ rollupReferenceId,
724
+ fileName,
725
+ }
726
+ },
727
+ onAssetSourceUpdated: ({ ressource }) => {
728
+ setAssetSource(
729
+ ressource.rollupReferenceId,
730
+ ressource.bufferAfterBuild,
731
+ )
732
+ },
733
+ urlVersioner,
615
734
  },
616
735
  )
617
736
 
@@ -620,16 +739,15 @@ export const createJsenvRollupPlugin = async ({
620
739
  async ({
621
740
  entryContentType,
622
741
  entryProjectRelativeUrl,
623
- entryBuildRelativeUrl,
624
742
  entryBuffer,
625
743
  }) => {
626
744
  if (entryContentType === "application/javascript") {
627
- emitChunk({
628
- id: ensureRelativeUrlNotation(entryProjectRelativeUrl),
629
- name: urlToBasename(`file:///${entryBuildRelativeUrl}`),
630
- ...(urlVersionningForEntryPoints
631
- ? {}
632
- : { fileName: entryBuildRelativeUrl }),
745
+ await ressourceBuilder.createReferenceForEntryPoint({
746
+ entryContentType,
747
+ entryUrl: resolveUrl(
748
+ entryProjectRelativeUrl,
749
+ compileDirectoryServerUrl,
750
+ ),
633
751
  })
634
752
  return
635
753
  }
@@ -650,8 +768,6 @@ export const createJsenvRollupPlugin = async ({
650
768
  entryContentType,
651
769
  entryUrl,
652
770
  entryBuffer,
653
- entryBuildRelativeUrl,
654
- urlVersionningForEntryPoints,
655
771
  })
656
772
  },
657
773
  ),
@@ -666,14 +782,19 @@ export const createJsenvRollupPlugin = async ({
666
782
  },
667
783
 
668
784
  async resolveId(specifier, importer, { custom }) {
785
+ if (specifier === EMPTY_CHUNK_URL) {
786
+ return specifier
787
+ }
788
+
789
+ let importerUrl
669
790
  if (importer === undefined) {
670
791
  if (specifier.endsWith(".html")) {
671
- importer = compileServerOrigin
792
+ importerUrl = compileServerOrigin
672
793
  } else {
673
- importer = compileDirectoryServerUrl
794
+ importerUrl = compileDirectoryServerUrl
674
795
  }
675
796
  } else {
676
- importer = asServerUrl(importer)
797
+ importerUrl = asServerUrl(importer)
677
798
  }
678
799
 
679
800
  const { importAssertionInfo } = custom
@@ -701,22 +822,20 @@ export const createJsenvRollupPlugin = async ({
701
822
  return specifier
702
823
  }
703
824
 
704
- if (isFileSystemPath(importer)) {
705
- importer = fileSystemPathToUrl(importer)
706
- }
707
-
708
- const importUrl = await importResolver.resolveImport(specifier, importer)
709
-
825
+ const importUrl = await importResolver.resolveImport(
826
+ specifier,
827
+ importerUrl,
828
+ )
710
829
  const existingImporter = urlImporterMap[importUrl]
711
830
  if (!existingImporter) {
712
831
  urlImporterMap[importUrl] = importAssertionInfo
713
832
  ? {
714
- url: importer,
833
+ url: importerUrl,
715
834
  column: importAssertionInfo.column,
716
835
  line: importAssertionInfo.line,
717
836
  }
718
837
  : {
719
- url: importer,
838
+ url: importerUrl,
720
839
  // rollup do not expose a way to know line and column for the static or dynamic import
721
840
  // referencing that file
722
841
  column: undefined,
@@ -748,33 +867,31 @@ export const createJsenvRollupPlugin = async ({
748
867
  },
749
868
 
750
869
  resolveFileUrl: ({ referenceId, fileName }) => {
751
- const ressourceFound = ressourceBuilder.findRessource((ressource) => {
752
- return ressource.rollupReferenceId === referenceId
753
- })
754
- const buildRelativeUrl = ressourceFound
755
- ? ressourceFound.buildRelativeUrl
756
- : fileName
870
+ ressourcesReferencedByJs.push(fileName)
757
871
 
758
872
  if (format === "esmodule") {
759
873
  if (!node && useImportMapToMaximizeCacheReuse && urlVersioning) {
760
- const buildRelativeUrlWithoutVersion =
761
- buildRelativeUrlToFileName(buildRelativeUrl)
762
- return `window.__resolveImportUrl__("./${buildRelativeUrlWithoutVersion}", import.meta.url)`
874
+ return `window.__resolveImportUrl__("./${fileName}", import.meta.url)`
763
875
  }
764
- return `new URL("${buildRelativeUrl}", import.meta.url)`
876
+ return `new URL("${fileName}", import.meta.url)`
765
877
  }
766
878
  if (format === "systemjs") {
767
- if (useImportMapToMaximizeCacheReuse && urlVersioning) {
768
- const buildRelativeUrlWithoutVersion =
769
- buildRelativeUrlToFileName(buildRelativeUrl)
770
- return `new URL(System.resolve("./${buildRelativeUrlWithoutVersion}", module.meta.url))`
771
- }
772
- return `new URL(System.resolve("./${buildRelativeUrl}", module.meta.url))`
879
+ return `new URL(System.resolve("./${fileName}", module.meta.url))`
773
880
  }
774
881
  if (format === "global") {
882
+ const ressource = ressourceBuilder.findRessource((ressource) => {
883
+ return ressource.rollupReferenceId === referenceId
884
+ })
885
+ ressource.fileName = fileName
886
+ const buildRelativeUrl = ressource.buildRelativeUrl
775
887
  return `new URL("${buildRelativeUrl}", document.currentScript && document.currentScript.src || document.baseURI)`
776
888
  }
777
889
  if (format === "commonjs") {
890
+ const ressource = ressourceBuilder.findRessource((ressource) => {
891
+ return ressource.rollupReferenceId === referenceId
892
+ })
893
+ ressource.fileName = fileName
894
+ const buildRelativeUrl = ressource.buildRelativeUrl
778
895
  return `new URL("${buildRelativeUrl}", "file:///" + __filename.replace(/\\/g, "/"))`
779
896
  }
780
897
  return null
@@ -796,11 +913,10 @@ export const createJsenvRollupPlugin = async ({
796
913
  return urlLoader.loadUrl(rollupUrl, {
797
914
  signal,
798
915
  logger,
799
- ressourceBuilder,
800
916
  })
801
917
  })
802
918
 
803
- url = loadResult.url
919
+ if (loadResult.url) url = loadResult.url
804
920
  const code = loadResult.code
805
921
  const map = loadResult.map
806
922
 
@@ -812,6 +928,7 @@ export const createJsenvRollupPlugin = async ({
812
928
  originalUrl,
813
929
  jsenvHelpersDirectoryInfo.url,
814
930
  )
931
+ // const isEntryPoint = entryPointUrls[originalUrl]
815
932
 
816
933
  const importer = urlImporterMap[url]
817
934
  // Inform ressource builder that this js module exists
@@ -821,18 +938,12 @@ export const createJsenvRollupPlugin = async ({
821
938
  // For import assertions, the imported ressource (css,json,...)
822
939
  // is arelady converted to a js module
823
940
  ressourceBuilder.createReferenceFoundByRollup({
824
- // we don't want to emit a js chunk for every js file found
825
- // (However we want if the file is preload/prefetch by something else)
826
- // so we tell asset builder not to emit a chunk for this js reference
827
- // otherwise rollup would never concat module together
828
- referenceShouldNotEmitChunk: jsConcatenation,
829
941
  contentTypeExpected: "application/javascript",
830
942
  referenceLabel: "static or dynamic import",
831
943
  referenceUrl: importer.url,
832
944
  referenceColumn: importer.column,
833
945
  referenceLine: importer.line,
834
946
  ressourceSpecifier: url,
835
-
836
947
  isJsenvHelperFile,
837
948
  contentType: "application/javascript",
838
949
  bufferBeforeBuild: Buffer.from(code),
@@ -862,18 +973,20 @@ export const createJsenvRollupPlugin = async ({
862
973
  onReferenceWithImportMetaUrlPattern: async ({ importNode }) => {
863
974
  const specifier = importNode.arguments[0].value
864
975
  const { line, column } = importNode.loc.start
865
- const reference =
866
- await ressourceBuilder.createReferenceFoundInJsModule({
867
- referenceLabel: "URL + import.meta.url",
868
- jsUrl: url,
869
- jsLine: line,
870
- jsColumn: column,
871
- ressourceSpecifier: specifier,
872
- })
976
+ const reference = ressourceBuilder.createReferenceFoundInJsModule({
977
+ referenceLabel: "URL + import.meta.url",
978
+ jsUrl: url,
979
+ jsLine: line,
980
+ jsColumn: column,
981
+ ressourceSpecifier: specifier,
982
+ })
873
983
  if (!reference) {
874
984
  return
875
985
  }
876
- markBuildRelativeUrlAsUsedByJs(reference.ressource.buildRelativeUrl)
986
+ if (!reference.ressource.isJsModule) {
987
+ // so that ressource.buildRelativeUrl is known during "resolveFileUrl" hook`
988
+ await reference.ressource.getReadyPromise()
989
+ }
877
990
  mutations.push((magicString) => {
878
991
  magicString.overwrite(
879
992
  importNode.start,
@@ -890,7 +1003,6 @@ export const createJsenvRollupPlugin = async ({
890
1003
  const { source } = importNode
891
1004
  const importSpecifier = source.value
892
1005
  const { line, column } = importNode.loc.start
893
-
894
1006
  // "type" is dynamic on dynamic import such as
895
1007
  // import("./data.json", {
896
1008
  // assert: {
@@ -918,9 +1030,7 @@ export const createJsenvRollupPlugin = async ({
918
1030
  type: typePropertyValue.value,
919
1031
  }
920
1032
  }
921
-
922
1033
  const { type } = assertions
923
-
924
1034
  // "specifier" is dynamic on dynamic import such as
925
1035
  // import(true ? "./a.json" : "b.json", {
926
1036
  // assert: {
@@ -944,9 +1054,7 @@ export const createJsenvRollupPlugin = async ({
944
1054
  ),
945
1055
  )
946
1056
  }
947
-
948
1057
  // There is no strategy for css import assertion on Node.js
949
- // and that's normal
950
1058
  if (type === "css" && node) {
951
1059
  throw new Error(
952
1060
  createDetailedMessage(
@@ -972,29 +1080,31 @@ export const createJsenvRollupPlugin = async ({
972
1080
  },
973
1081
  }),
974
1082
  )
975
-
976
- const ressourceUrl = asServerUrl(id)
977
- if (external) {
978
- if (importAssertionSupportedByRuntime) {
979
- const reference =
980
- await ressourceBuilder.createReferenceFoundInJsModule({
981
- referenceLabel: "import assertion",
982
- isImportAssertion: true,
983
- jsUrl: url,
984
- jsLine: line,
985
- jsColumn: column,
986
- ressourceSpecifier: ressourceUrl,
987
- })
988
- // reference can be null for cross origin urls
989
- if (!reference) {
990
- return
991
- }
992
- markBuildRelativeUrlAsUsedByJs(
993
- reference.ressource.buildRelativeUrl,
994
- )
995
- return
996
- }
997
-
1083
+ // remove import
1084
+ let ressourceUrl = asServerUrl(id)
1085
+ // lod the asset without ?import_type in it
1086
+ ressourceUrl = ressourceUrl.replace(`?import_type=${type}`, "")
1087
+ const fileReference = ressourceBuilder.createReferenceFoundInJsModule(
1088
+ {
1089
+ referenceLabel: `${type} import assertion`,
1090
+ // If all references to a ressource are only import assertions
1091
+ // the file referenced do not need to be written on filesystem
1092
+ // as it was converted to a js file
1093
+ // We pass "isImportAssertion: true" for this purpose
1094
+ isImportAssertion: true,
1095
+ jsUrl: url,
1096
+ jsLine: line,
1097
+ jsColumn: column,
1098
+ ressourceSpecifier: ressourceUrl,
1099
+ contentTypeExpected:
1100
+ type === "css" ? "text/css" : "application/json",
1101
+ },
1102
+ )
1103
+ // reference can be null for cross origin urls
1104
+ if (!fileReference) {
1105
+ return
1106
+ }
1107
+ if (external && !importAssertionSupportedByRuntime) {
998
1108
  throw new Error(
999
1109
  createDetailedMessage(
1000
1110
  `import assertion ressource cannot be external when runtime do not support import assertions`,
@@ -1007,16 +1117,64 @@ export const createJsenvRollupPlugin = async ({
1007
1117
  )
1008
1118
  }
1009
1119
 
1010
- // we want to convert the import assertions into a js module
1011
- // to do that we append ?import_type to the url
1012
- // In theory this is not needed anymore:
1013
- // This is already done by the compile server
1014
- const ressourceUrlAsJsModule = setUrlSearchParamsDescriptor(
1120
+ // await fileReference.ressource.getReadyPromise()
1121
+ // once the file is ready, we know its buildRelativeUrl
1122
+ // we can update either to the fileName or buildRelativeUrl
1123
+ // should be use the rollup reference id?
1124
+ const ressourceUrlAsJsModule = resolveUrl(
1125
+ `${urlToBasename(
1126
+ ressourceUrl,
1127
+ )}${outputExtension}?import_type=${type}`,
1015
1128
  ressourceUrl,
1016
- {
1017
- import_type: type,
1018
- },
1019
1129
  )
1130
+ const jsUrl = url
1131
+ urlCustomLoaders[ressourceUrlAsJsModule] = async () => {
1132
+ let code
1133
+ let map
1134
+
1135
+ if (type === "json") {
1136
+ await fileReference.ressource.getReadyPromise()
1137
+ code = String(fileReference.ressource.bufferAfterBuild)
1138
+ const jsModuleConversionResult =
1139
+ await convertJsonTextToJavascriptModule({
1140
+ code,
1141
+ map,
1142
+ })
1143
+ code = jsModuleConversionResult.code
1144
+ map = jsModuleConversionResult.map
1145
+ } else if (type === "css") {
1146
+ await fileReference.ressource.getReadyPromise()
1147
+ const cssBuildUrl = resolveUrl(
1148
+ fileReference.ressource.buildRelativeUrl,
1149
+ buildDirectoryUrl,
1150
+ )
1151
+ const jsBuildUrl = resolveUrl(
1152
+ urlToFilename(jsUrl),
1153
+ buildDirectoryUrl,
1154
+ )
1155
+ code = String(fileReference.ressource.bufferAfterBuild)
1156
+ const sourcemapReference =
1157
+ fileReference.ressource.dependencies.find((dependency) => {
1158
+ return dependency.ressource.isSourcemap
1159
+ })
1160
+ if (sourcemapReference) {
1161
+ // because css is ready, it's sourcemap is also ready
1162
+ // we can read directly sourcemapReference.ressource.bufferAfterBuild
1163
+ map = JSON.parse(sourcemapReference.ressource.bufferAfterBuild)
1164
+ }
1165
+ const jsModuleConversionResult =
1166
+ await convertCssTextToJavascriptModule({
1167
+ cssUrl: cssBuildUrl,
1168
+ jsUrl: jsBuildUrl,
1169
+ code,
1170
+ map,
1171
+ })
1172
+ code = jsModuleConversionResult.code
1173
+ map = jsModuleConversionResult.map
1174
+ }
1175
+
1176
+ return { code, map }
1177
+ }
1020
1178
 
1021
1179
  mutations.push((magicString) => {
1022
1180
  magicString.overwrite(
@@ -1044,9 +1202,6 @@ export const createJsenvRollupPlugin = async ({
1044
1202
 
1045
1203
  // resolveImportMeta: () => {}
1046
1204
  outputOptions: (outputOptions) => {
1047
- const extension = extname(entryPointMap[Object.keys(entryPointMap)[0]])
1048
- const outputExtension = extension === ".html" ? ".js" : extension
1049
-
1050
1205
  outputOptions.paths = (id) => {
1051
1206
  const mapping = importPaths[id]
1052
1207
  if (mapping) {
@@ -1059,19 +1214,31 @@ export const createJsenvRollupPlugin = async ({
1059
1214
  }
1060
1215
  return id
1061
1216
  }
1217
+ // outputOptions.assetFileNames = () => {
1218
+ // return `assets/[name]_[hash][extname]`
1219
+ // }
1062
1220
  outputOptions.entryFileNames = () => {
1063
- if (urlVersionningForEntryPoints) {
1064
- return `[name]-[hash]${outputExtension}`
1221
+ if (useImportMapToMaximizeCacheReuse) {
1222
+ return `[name]${outputExtension}`
1065
1223
  }
1066
- return `[name]${outputExtension}`
1224
+ return entryPoints
1067
1225
  }
1068
- outputOptions.chunkFileNames = () => {
1226
+ outputOptions.chunkFileNames = (chunkInfo) => {
1069
1227
  // const originalUrl = asOriginalUrl(chunkInfo.facadeModuleId)
1070
1228
  // const basename = urlToBasename(originalUrl)
1071
1229
  if (useImportMapToMaximizeCacheReuse) {
1072
1230
  return `[name]${outputExtension}`
1073
1231
  }
1074
- return `[name]-[hash]${outputExtension}`
1232
+ if (chunkInfo.isEntry) {
1233
+ const originalUrl = asOriginalUrl(chunkInfo.facadeModuleId)
1234
+ const entryPointPattern = entryPointUrls[originalUrl]
1235
+ if (entryPointPattern) {
1236
+ return entryPointPattern
1237
+ }
1238
+ }
1239
+ return urlVersioning
1240
+ ? `[name]_[hash]${outputExtension}`
1241
+ : `[name]${outputExtension}`
1075
1242
  }
1076
1243
 
1077
1244
  // rollup does not expects to have http dependency in the mix: fix them
@@ -1104,29 +1271,35 @@ export const createJsenvRollupPlugin = async ({
1104
1271
  },
1105
1272
 
1106
1273
  async generateBundle(outputOptions, rollupResult) {
1107
- const jsChunks = {}
1108
- // rollupResult can be mutated by late asset emission
1109
- // howeverl late chunk (js module) emission is not possible
1274
+ const rollupJsFileInfos = {}
1275
+ const rollupAssetFileInfos = {}
1276
+ // To keep in mind: rollupResult object can be mutated by late asset emission
1277
+ // however late chunk (js module) emission is not possible
1110
1278
  // as rollup rightfully prevent late js emission
1111
1279
  Object.keys(rollupResult).forEach((fileName) => {
1112
- const file = rollupResult[fileName]
1280
+ const rollupFileInfo = rollupResult[fileName]
1113
1281
 
1114
1282
  // there is 3 types of file: "placeholder", "asset", "chunk"
1115
- if (file.type === "asset") {
1283
+ if (rollupFileInfo.type === "asset") {
1284
+ rollupAssetFileInfos[fileName] = rollupFileInfo
1116
1285
  return
1117
1286
  }
1118
1287
 
1119
- if (file.type === "chunk") {
1120
- const { facadeModuleId } = file
1288
+ if (rollupFileInfo.type === "chunk") {
1289
+ const { facadeModuleId } = rollupFileInfo
1121
1290
  if (facadeModuleId === EMPTY_CHUNK_URL) {
1122
1291
  return
1123
1292
  }
1124
- const fileCopy = { ...file }
1293
+ const fileCopy = { ...rollupFileInfo }
1125
1294
  if (facadeModuleId) {
1126
1295
  fileCopy.url = asServerUrl(facadeModuleId)
1127
1296
  } else {
1128
- const sourcePath = file.map.sources[file.map.sources.length - 1]
1129
- const fileBuildUrl = resolveUrl(file.fileName, buildDirectoryUrl)
1297
+ const sourcePath =
1298
+ rollupFileInfo.map.sources[rollupFileInfo.map.sources.length - 1]
1299
+ const fileBuildUrl = resolveUrl(
1300
+ rollupFileInfo.fileName,
1301
+ buildDirectoryUrl,
1302
+ )
1130
1303
  const originalProjectUrl = resolveUrl(sourcePath, fileBuildUrl)
1131
1304
  fileCopy.url = asCompiledServerUrl(originalProjectUrl, {
1132
1305
  projectDirectoryUrl,
@@ -1134,71 +1307,31 @@ export const createJsenvRollupPlugin = async ({
1134
1307
  compileDirectoryRelativeUrl,
1135
1308
  })
1136
1309
  }
1137
- jsChunks[fileName] = fileCopy
1138
- }
1139
- })
1140
- await ensureTopLevelAwaitTranspilationIfNeeded({
1141
- format,
1142
- transformTopLevelAwait,
1143
- })
1144
-
1145
- const jsModuleBuild = {}
1146
- Object.keys(jsChunks).forEach((fileName) => {
1147
- const file = jsChunks[fileName]
1148
- let buildRelativeUrl
1149
- const canBeVersioned =
1150
- asRollupUrl(file.url) in jsModulesFromEntry ||
1151
- urlVersionningForEntryPoints ||
1152
- !file.isEntry
1153
-
1154
- if (file.url in inlineModuleScripts && format === "systemjs") {
1155
- const magicString = new MagicString(file.code)
1156
- magicString.overwrite(
1157
- 0,
1158
- "System.register([".length,
1159
- `System.register("${fileName}", [`,
1160
- )
1161
- file.code = magicString.toString()
1162
- }
1163
1310
 
1164
- if (urlVersioning) {
1165
- if (canBeVersioned && useImportMapToMaximizeCacheReuse) {
1166
- buildRelativeUrl = computeBuildRelativeUrl(
1167
- resolveUrl(fileName, buildDirectoryUrl),
1168
- file.code,
1169
- {
1170
- pattern: `[name]-[hash][extname]`,
1171
- lineBreakNormalization,
1172
- contentType: "application/javascript",
1173
- },
1311
+ if (fileCopy.url in inlineModuleScripts && format === "systemjs") {
1312
+ const code = rollupFileInfo.code
1313
+ const systemRegisterIndex = code.indexOf("System.register([")
1314
+ const magicString = new MagicString(code)
1315
+ magicString.overwrite(
1316
+ systemRegisterIndex,
1317
+ systemRegisterIndex + "System.register([".length,
1318
+ `System.register("${fileName}", [`,
1174
1319
  )
1175
- } else {
1176
- buildRelativeUrl = fileName
1320
+ fileCopy.code = magicString.toString()
1177
1321
  }
1178
- } else {
1179
- buildRelativeUrl = fileName
1180
- fileName = rollupFileNameWithoutHash(fileName)
1181
- }
1182
1322
 
1183
- const originalProjectUrl = asOriginalUrl(file.url)
1184
- const originalProjectRelativeUrl = urlToRelativeUrl(
1185
- originalProjectUrl,
1186
- projectDirectoryUrl,
1187
- )
1188
- const jsRessource = ressourceBuilder.findRessource(
1189
- (ressource) => ressource.url === file.url,
1190
- )
1191
- if (jsRessource && jsRessource.isInline) {
1192
- if (format === "systemjs") {
1193
- markBuildRelativeUrlAsUsedByJs(buildRelativeUrl)
1323
+ if (
1324
+ isReferencedByJs({
1325
+ rollupFileInfo: fileCopy,
1326
+ jsConcatenation,
1327
+ ressourceBuilder,
1328
+ })
1329
+ ) {
1330
+ ressourcesReferencedByJs.push(fileCopy.fileName)
1194
1331
  }
1195
- buildInlineFileContents[buildRelativeUrl] = file.code
1196
- } else {
1197
- markBuildRelativeUrlAsUsedByJs(buildRelativeUrl)
1198
- buildMappings[originalProjectRelativeUrl] = buildRelativeUrl
1199
- }
1200
1332
 
1201
- jsModuleBuild[buildRelativeUrl] = file
1333
+ rollupJsFileInfos[fileName] = fileCopy
1334
+ }
1202
1335
  })
1203
1336
 
1204
1337
  // it's important to do this to emit late asset
@@ -1211,35 +1344,67 @@ export const createJsenvRollupPlugin = async ({
1211
1344
  // aux assets faisant référence a ces chunk js qu'ils sont terminés
1212
1345
  // et donc les assets peuvent connaitre le nom du chunk
1213
1346
  // et mettre a jour leur dépendance vers ce fichier js
1214
- ressourceBuilder.rollupBuildEnd({ jsModuleBuild, buildManifest })
1347
+ const { jsRessources } = ressourceBuilder.rollupBuildEnd({
1348
+ rollupJsFileInfos,
1349
+ rollupAssetFileInfos,
1350
+ useImportMapToMaximizeCacheReuse,
1351
+ })
1352
+ Object.keys(jsRessources).forEach((ressourceUrl) => {
1353
+ const jsRessource = jsRessources[ressourceUrl]
1354
+ if (jsRessource.isInline) {
1355
+ buildInlineFileContents[jsRessource.buildRelativeUrl] =
1356
+ jsRessource.bufferAfterBuild
1357
+ if (format === "systemjs") {
1358
+ ressourcesReferencedByJs.push(jsRessource.fileName)
1359
+ }
1360
+ } else {
1361
+ const originalProjectUrl = asOriginalUrl(ressourceUrl)
1362
+ const originalProjectRelativeUrl = urlToRelativeUrl(
1363
+ originalProjectUrl,
1364
+ projectDirectoryUrl,
1365
+ )
1366
+ buildMappings[originalProjectRelativeUrl] =
1367
+ jsRessource.buildRelativeUrl
1368
+ }
1369
+
1370
+ buildManifest[jsRessource.fileName] = jsRessource.buildRelativeUrl
1371
+ })
1372
+
1373
+ // wait for asset build relative urls
1374
+ // to ensure the importmap will contain remappings for them
1375
+ // (not sure this is required anymore)
1376
+ await Promise.all(
1377
+ ressourcesReferencedByJs.map(async (ressourceName) => {
1378
+ const ressource = ressourceBuilder.findRessource((ressource) => {
1379
+ return ressource.relativeUrl === ressourceName
1380
+ })
1381
+ if (ressource && !ressource.isJsModule) {
1382
+ await ressource.getReadyPromise()
1383
+ buildManifest[ressourceName] = ressource.buildRelativeUrl
1384
+ }
1385
+ }),
1386
+ )
1387
+
1215
1388
  // wait html files to be emitted
1216
1389
  await ressourceBuilder.getAllEntryPointsEmittedPromise()
1217
1390
  onBundleEnd()
1218
-
1391
+ const jsModuleBuild = {
1392
+ ...rollupJsFileInfos,
1393
+ }
1219
1394
  const assetBuild = {}
1220
- Object.keys(rollupResult).forEach((rollupFileId) => {
1221
- const file = rollupResult[rollupFileId]
1395
+ Object.keys(rollupResult).forEach((fileName) => {
1396
+ const file = rollupResult[fileName]
1222
1397
  if (file.type !== "asset") {
1223
1398
  return
1224
1399
  }
1225
1400
 
1226
- const { facadeModuleId } = file
1227
- if (facadeModuleId === EMPTY_CHUNK_URL) {
1228
- return
1229
- }
1230
-
1231
1401
  const assetRessource = ressourceBuilder.findRessource(
1232
- (ressource) => ressource.relativeUrl === rollupFileId,
1402
+ (ressource) =>
1403
+ // happens for import.meta.url pattern
1404
+ ressource.fileName === fileName ||
1405
+ // happens for sourcemap
1406
+ ressource.relativeUrl === fileName,
1233
1407
  )
1234
- if (!assetRessource) {
1235
- const buildRelativeUrl = rollupFileId
1236
- const fileName = rollupFileNameWithoutHash(buildRelativeUrl)
1237
- assetBuild[buildRelativeUrl] = file
1238
- buildManifest[fileName] = buildRelativeUrl
1239
- // the asset does not exists in the project it was generated during building
1240
- // happens for sourcemap
1241
- return
1242
- }
1243
1408
 
1244
1409
  // ignore potential useless assets which happens when:
1245
1410
  // - sourcemap re-emitted
@@ -1261,38 +1426,36 @@ export const createJsenvRollupPlugin = async ({
1261
1426
  }
1262
1427
 
1263
1428
  const buildRelativeUrl = assetRessource.buildRelativeUrl
1264
- const fileName = rollupFileNameWithoutHash(buildRelativeUrl)
1265
1429
  if (assetRessource.isInline) {
1266
1430
  buildInlineFileContents[buildRelativeUrl] = file.source
1267
- } else {
1431
+ return
1432
+ }
1433
+
1434
+ // in case sourcemap is mutated, we must not trust rollup but the asset builder source instead
1435
+ file.source = assetRessource.bufferAfterBuild
1436
+ assetBuild[buildRelativeUrl] = file
1437
+ buildManifest[assetRessource.fileName] = buildRelativeUrl
1438
+ if (assetRessource.bufferBeforeBuild) {
1268
1439
  const originalProjectUrl = asOriginalUrl(assetRessource.url)
1269
1440
  const originalProjectRelativeUrl = urlToRelativeUrl(
1270
1441
  originalProjectUrl,
1271
1442
  projectDirectoryUrl,
1272
1443
  )
1273
- // in case sourcemap is mutated, we must not trust rollup but the asset builder source instead
1274
- file.source = assetRessource.bufferAfterBuild
1275
-
1276
- assetBuild[buildRelativeUrl] = file
1277
1444
  buildMappings[originalProjectRelativeUrl] = buildRelativeUrl
1278
- buildManifest[fileName] = buildRelativeUrl
1279
1445
  }
1280
1446
  })
1281
-
1282
1447
  rollupBuild = {
1283
1448
  ...jsModuleBuild,
1284
1449
  ...assetBuild,
1285
1450
  }
1286
- rollupBuild = injectSourcemapInRollupBuild(rollupBuild, {
1287
- buildDirectoryUrl,
1288
- })
1289
-
1290
- // update rollupBuild, buildInlineFilesContents, buildManifest and buildMappings
1291
- // in case some ressources where inlined by ressourceBuilder.rollupBuildEnd
1292
- Object.keys(rollupBuild).forEach((buildRelativeUrl) => {
1293
- const rollupFileInfo = rollupBuild[buildRelativeUrl]
1451
+ rollupBuild = sortObjectByPathnames(rollupBuild)
1452
+ // fill "buildFileContents", "buildInlineFilesContents"
1453
+ // and update "buildManifest" and "buildMappings" in case some ressource where inlined
1454
+ // by ressourceBuilder.rollupBuildEnd
1455
+ Object.keys(rollupBuild).forEach((fileName) => {
1456
+ const rollupFileInfo = rollupBuild[fileName]
1294
1457
  const ressource = ressourceBuilder.findRessource((ressource) => {
1295
- if (ressource.buildRelativeUrl === buildRelativeUrl) {
1458
+ if (ressource.buildRelativeUrl === fileName) {
1296
1459
  return true
1297
1460
  }
1298
1461
  if (ressource.url === rollupFileInfo.url) {
@@ -1300,46 +1463,44 @@ export const createJsenvRollupPlugin = async ({
1300
1463
  }
1301
1464
  return false
1302
1465
  })
1303
- if (ressource && ressource.isInline) {
1304
- const fileName = buildRelativeUrlToFileName(buildRelativeUrl)
1305
- if (fileName) {
1306
- delete buildManifest[fileName]
1307
- }
1466
+ if (ressource.isInline) {
1467
+ delete buildManifest[fileName]
1308
1468
  const originalProjectUrl = asOriginalUrl(ressource.url)
1309
- delete buildMappings[
1310
- urlToRelativeUrl(originalProjectUrl, projectDirectoryUrl)
1311
- ]
1312
- buildInlineFileContents[buildRelativeUrl] = rollupFileInfo.code
1313
- delete rollupBuild[buildRelativeUrl]
1469
+ const originalRelativeUrl = urlToRelativeUrl(
1470
+ originalProjectUrl,
1471
+ projectDirectoryUrl,
1472
+ )
1473
+ delete buildMappings[originalRelativeUrl]
1474
+ buildInlineFileContents[ressource.buildRelativeUrl] =
1475
+ ressource.bufferAfterBuild
1476
+ } else {
1477
+ buildFileContents[ressource.buildRelativeUrl] =
1478
+ ressource.bufferAfterBuild
1314
1479
  }
1315
1480
  })
1316
1481
 
1317
1482
  await finalizeServiceWorkers({
1318
1483
  serviceWorkers,
1484
+ classicServiceWorkers,
1319
1485
  serviceWorkerFinalizer,
1320
1486
  projectDirectoryUrl,
1321
1487
  buildDirectoryUrl,
1322
1488
  rollupBuild,
1323
1489
  buildMappings,
1324
1490
  buildManifest,
1491
+ buildFileContents,
1325
1492
  lineBreakNormalization,
1326
1493
  minify,
1327
1494
  })
1328
1495
 
1329
- rollupBuild = sortObjectByPathnames(rollupBuild)
1330
1496
  buildManifest = sortObjectByPathnames(buildManifest)
1331
1497
  buildMappings = sortObjectByPathnames(buildMappings)
1332
- Object.keys(rollupBuild).forEach((buildRelativeUrl) => {
1333
- const { type, source, code } = rollupBuild[buildRelativeUrl]
1334
- buildFileContents[buildRelativeUrl] = type === "asset" ? source : code
1335
- })
1336
1498
  const buildDuration = Date.now() - buildStartMs
1337
1499
  buildStats = createBuildStats({
1338
1500
  buildFileContents,
1339
1501
  ressourceBuilder,
1340
1502
  buildDuration,
1341
1503
  })
1342
-
1343
1504
  logger.info(
1344
1505
  formatBuildDoneInfo({
1345
1506
  buildStats,
@@ -1366,9 +1527,9 @@ export const createJsenvRollupPlugin = async ({
1366
1527
  }
1367
1528
 
1368
1529
  return {
1369
- jsenvRollupPlugin,
1530
+ rollupPlugins,
1370
1531
  getLastErrorMessage: () => lastErrorMessage,
1371
- getResult: () => {
1532
+ getResult: async () => {
1372
1533
  return {
1373
1534
  rollupBuild,
1374
1535
  urlResponseBodyMap: urlLoader.getUrlResponseBodyMap(),
@@ -1386,28 +1547,8 @@ export const createJsenvRollupPlugin = async ({
1386
1547
  }
1387
1548
  }
1388
1549
 
1389
- const ensureTopLevelAwaitTranspilationIfNeeded = async ({
1390
- format,
1391
- transformTopLevelAwait,
1392
- }) => {
1393
- if (!transformTopLevelAwait) {
1394
- return
1395
- }
1396
-
1397
- if (format === "esmodule") {
1398
- // transform-async-to-promises won't be able to transform top level await
1399
- // for "esmodule", so it would be useless
1400
- return
1401
- }
1402
-
1403
- if (format === "systemjs") {
1404
- // top level await is an async function for systemjs
1405
- return
1406
- }
1407
- }
1408
-
1409
1550
  const prepareEntryPoints = async (
1410
- entryPointMap,
1551
+ entryPoints,
1411
1552
  {
1412
1553
  logger,
1413
1554
  projectDirectoryUrl,
@@ -1416,7 +1557,7 @@ const prepareEntryPoints = async (
1416
1557
  urlFetcher,
1417
1558
  },
1418
1559
  ) => {
1419
- const entryFileRelativeUrls = Object.keys(entryPointMap)
1560
+ const entryFileRelativeUrls = Object.keys(entryPoints)
1420
1561
  const entryPointsPrepared = []
1421
1562
  await entryFileRelativeUrls.reduce(async (previous, entryFileRelativeUrl) => {
1422
1563
  await previous
@@ -1426,10 +1567,9 @@ const prepareEntryPoints = async (
1426
1567
  projectDirectoryUrl,
1427
1568
  )
1428
1569
  const entryBuildUrl = resolveUrl(
1429
- entryPointMap[entryFileRelativeUrl],
1570
+ entryPoints[entryFileRelativeUrl],
1430
1571
  buildDirectoryUrl,
1431
1572
  )
1432
-
1433
1573
  const entryProjectRelativeUrl = urlToRelativeUrl(
1434
1574
  entryProjectUrl,
1435
1575
  projectDirectoryUrl,
@@ -1438,20 +1578,16 @@ const prepareEntryPoints = async (
1438
1578
  entryBuildUrl,
1439
1579
  buildDirectoryUrl,
1440
1580
  )
1441
-
1442
1581
  logger.debug(`${UNICODE.INFO} load entry point ${entryProjectRelativeUrl}`)
1443
-
1444
1582
  const entryServerUrl = resolveUrl(
1445
1583
  entryProjectRelativeUrl,
1446
1584
  compileServerOrigin,
1447
1585
  )
1448
-
1449
1586
  const entryResponse = await urlFetcher.fetchUrl(entryServerUrl, {
1450
- urlTrace: `entryPointMap`,
1587
+ urlTrace: `entryPoints`,
1451
1588
  })
1452
1589
  const entryContentType = entryResponse.headers["content-type"]
1453
1590
  const isHtml = entryContentType === "text/html"
1454
-
1455
1591
  entryPointsPrepared.push({
1456
1592
  entryContentType:
1457
1593
  entryContentType === "text/javascript"
@@ -1499,20 +1635,6 @@ const normalizeRollupResolveReturnValue = (resolveReturnValue) => {
1499
1635
  return resolveReturnValue
1500
1636
  }
1501
1637
 
1502
- const rollupFileNameWithoutHash = (fileName) => {
1503
- return fileName.replace(/-[a-z0-9]{8,}(\..*?)?$/, (_, afterHash = "") => {
1504
- return afterHash
1505
- })
1506
- }
1507
-
1508
- // otherwise importmap handle it as a bare import
1509
- const ensureRelativeUrlNotation = (relativeUrl) => {
1510
- if (relativeUrl.startsWith("../")) {
1511
- return relativeUrl
1512
- }
1513
- return `./${relativeUrl}`
1514
- }
1515
-
1516
1638
  const externalImportUrlPatternsToExternalUrlPredicate = (
1517
1639
  externalImportUrlPatterns,
1518
1640
  projectDirectoryUrl,
@@ -1548,16 +1670,47 @@ const acceptsJsonContentType = ({ node, format }) => {
1548
1670
  return false
1549
1671
  }
1550
1672
 
1673
+ const isReferencedByJs = ({
1674
+ rollupFileInfo,
1675
+ jsConcatenation,
1676
+ ressourceBuilder,
1677
+ }) => {
1678
+ if (rollupFileInfo.isDynamicEntry) {
1679
+ return true
1680
+ }
1681
+ const jsRessource = ressourceBuilder.findRessource((ressource) => {
1682
+ return ressource.url === rollupFileInfo.url
1683
+ })
1684
+ if (!jsConcatenation && rollupFileInfo.isEntry) {
1685
+ return true
1686
+ }
1687
+ if (
1688
+ jsRessource &&
1689
+ jsRessource.references.some((ref) => ref.isRessourceHint)
1690
+ ) {
1691
+ return true
1692
+ }
1693
+ return false
1694
+ }
1695
+
1551
1696
  const finalizeServiceWorkers = async ({
1552
1697
  serviceWorkers,
1698
+ classicServiceWorkers,
1553
1699
  serviceWorkerFinalizer,
1554
1700
  buildMappings,
1555
1701
  buildManifest,
1556
- rollupBuild,
1702
+ buildFileContents,
1557
1703
  lineBreakNormalization,
1558
1704
  }) => {
1705
+ const serviceWorkerKeys = Object.keys(serviceWorkers)
1706
+ const classicServiceWorkerKeys = Object.keys(classicServiceWorkers)
1707
+ const projectRelativeUrls = [
1708
+ ...serviceWorkerKeys,
1709
+ ...classicServiceWorkerKeys,
1710
+ ]
1711
+
1559
1712
  await Promise.all(
1560
- Object.keys(serviceWorkers).map(async (projectRelativeUrl) => {
1713
+ projectRelativeUrls.map(async (projectRelativeUrl) => {
1561
1714
  const projectUrl = resolveUrl(projectRelativeUrl, "file://")
1562
1715
  projectRelativeUrl = urlToRelativeUrl(projectUrl, "file://")
1563
1716
  const serviceWorkerBuildRelativeUrl = buildMappings[projectRelativeUrl]
@@ -1566,14 +1719,29 @@ const finalizeServiceWorkers = async ({
1566
1719
  `"${projectRelativeUrl}" service worker file missing in the build`,
1567
1720
  )
1568
1721
  }
1569
- const buildFileContent = rollupBuild[serviceWorkerBuildRelativeUrl].source
1570
- rollupBuild[serviceWorkerBuildRelativeUrl].source =
1571
- serviceWorkerFinalizer(buildFileContent, {
1722
+
1723
+ // module service worker
1724
+ if (serviceWorkerKeys.includes(projectRelativeUrl)) {
1725
+ let code = buildFileContents[serviceWorkerBuildRelativeUrl]
1726
+ code = await serviceWorkerFinalizer(code, {
1572
1727
  serviceWorkerBuildRelativeUrl,
1573
1728
  buildManifest,
1574
- rollupBuild,
1729
+ buildFileContents,
1575
1730
  lineBreakNormalization,
1576
1731
  })
1732
+ buildFileContents[serviceWorkerBuildRelativeUrl] = code
1733
+ }
1734
+ // "classic" service worker
1735
+ else {
1736
+ let code = buildFileContents[serviceWorkerBuildRelativeUrl]
1737
+ code = await serviceWorkerFinalizer(code, {
1738
+ serviceWorkerBuildRelativeUrl,
1739
+ buildManifest,
1740
+ buildFileContents,
1741
+ lineBreakNormalization,
1742
+ })
1743
+ buildFileContents[serviceWorkerBuildRelativeUrl] = code
1744
+ }
1577
1745
  }),
1578
1746
  )
1579
1747
  }