@jsenv/core 24.6.5 → 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 (49) hide show
  1. package/dist/browser_runtime/asset-manifest.json +2 -1
  2. package/dist/browser_runtime/{browser_runtime-bb0e3aa4.js → browser_runtime_a8097085.js} +1 -1
  3. package/dist/browser_runtime/{browser_runtime-bb0e3aa4.js.map → browser_runtime_a8097085.js.map} +1 -1
  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-6eb67db4.html → compile_proxy_e16d7de8.html} +2 -2
  7. package/dist/compile_proxy/{compile_proxy.html__inline__20-9e168143.js.map → compile_proxy_e3b0c442_9e168143.js.map} +0 -0
  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-b6ad84bf.html → redirector_2e0c8abe.html} +2 -2
  13. package/dist/redirector/{redirector.html__inline__15-3a34a156.js.map → redirector_e3b0c442_3a34a156.js.map} +0 -0
  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-a5ef2c60.js.map → toolbar.main_a5ef2c60.js.map} +0 -0
  25. package/dist/toolbar/{toolbar-1fbf8dcb.html → toolbar_412abb83.html} +3 -5
  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-997dbaa0.js → toolbar_injector_4f9c19e5.js} +3 -3
  29. package/dist/toolbar_injector/{toolbar_injector-997dbaa0.js.map → toolbar_injector_4f9c19e5.js.map} +2 -2
  30. package/package.json +1 -1
  31. package/readme.md +2 -2
  32. package/src/buildProject.js +18 -16
  33. package/src/internal/building/buildUsingRollup.js +9 -7
  34. package/src/internal/building/build_logs.js +2 -2
  35. package/src/internal/building/build_stats.js +11 -1
  36. package/src/internal/building/html/parseHtmlRessource.js +2 -26
  37. package/src/internal/building/js/parseJsRessource.js +3 -2
  38. package/src/internal/building/json_module.js +11 -0
  39. package/src/internal/building/parseRessource.js +1 -1
  40. package/src/internal/building/ressource_builder.js +216 -215
  41. package/src/internal/building/rollup_plugin_jsenv.js +462 -306
  42. package/src/internal/building/url_loader.js +8 -145
  43. package/src/internal/building/url_versioning.js +226 -0
  44. package/src/internal/compiling/compileHtml.js +8 -1
  45. package/src/jsenvServiceWorkerFinalizer.js +7 -8
  46. package/src/internal/building/asset_url_versioning.js +0 -50
  47. package/src/internal/building/rollup_build_sourcemap.js +0 -54
  48. package/src/internal/building/url-versioning.js +0 -96
  49. 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,9 +13,12 @@ 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"
20
22
  import { transformJs } from "@jsenv/core/src/internal/compiling/js-compilation-service/transformJs.js"
21
23
  import { createUrlConverter } from "@jsenv/core/src/internal/url_conversion.js"
22
24
  import { createUrlFetcher } from "@jsenv/core/src/internal/building/url_fetcher.js"
@@ -24,7 +26,6 @@ import { createUrlLoader } from "@jsenv/core/src/internal/building/url_loader.js
24
26
  import { stringifyUrlTrace } from "@jsenv/core/src/internal/building/url_trace.js"
25
27
  import { sortObjectByPathnames } from "@jsenv/core/src/internal/building/sortObjectByPathnames.js"
26
28
  import { jsenvHelpersDirectoryInfo } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
27
- import { setUrlSearchParamsDescriptor } from "@jsenv/core/src/internal/url_utils.js"
28
29
 
29
30
  import {
30
31
  formatBuildStartLog,
@@ -40,13 +41,12 @@ import {
40
41
  referenceToCodeForRollup,
41
42
  } from "./ressource_builder.js"
42
43
 
43
- import { computeBuildRelativeUrl } from "./url-versioning.js"
44
+ import { createUrlVersioner } from "./url_versioning.js"
44
45
  import { visitImportReferences } from "./import_references.js"
45
46
 
46
47
  import { createImportResolverForNode } from "../import-resolution/import-resolver-node.js"
47
48
  import { createImportResolverForImportmap } from "../import-resolution/import-resolver-importmap.js"
48
49
  import { getDefaultImportMap } from "../import-resolution/importmap-default.js"
49
- import { injectSourcemapInRollupBuild } from "./rollup_build_sourcemap.js"
50
50
  import { createBuildStats } from "./build_stats.js"
51
51
 
52
52
  export const createRollupPlugins = async ({
@@ -54,7 +54,7 @@ export const createRollupPlugins = async ({
54
54
  logger,
55
55
 
56
56
  projectDirectoryUrl,
57
- entryPointMap,
57
+ entryPoints,
58
58
  compileServerOrigin,
59
59
  compileDirectoryRelativeUrl,
60
60
  buildDirectoryUrl,
@@ -69,6 +69,8 @@ export const createRollupPlugins = async ({
69
69
  workers,
70
70
  serviceWorkers,
71
71
  serviceWorkerFinalizer,
72
+ classicWorkers,
73
+ classicServiceWorkers,
72
74
 
73
75
  format,
74
76
  systemJsUrl,
@@ -77,7 +79,6 @@ export const createRollupPlugins = async ({
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 createRollupPlugins = 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 createRollupPlugins = 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 createRollupPlugins = 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 createRollupPlugins = 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)
@@ -329,9 +350,9 @@ export const createRollupPlugins = async ({
329
350
  name: "jsenv",
330
351
 
331
352
  async buildStart() {
332
- logger.info(formatBuildStartLog({ entryPointMap }))
353
+ logger.info(formatBuildStartLog({ entryPoints }))
333
354
 
334
- const entryPointsPrepared = await prepareEntryPoints(entryPointMap, {
355
+ const entryPointsPrepared = await prepareEntryPoints(entryPoints, {
335
356
  logger,
336
357
  projectDirectoryUrl,
337
358
  buildDirectoryUrl,
@@ -360,7 +381,7 @@ export const createRollupPlugins = async ({
360
381
  if (typeof useImportMapToMaximizeCacheReuse === "undefined") {
361
382
  useImportMapToMaximizeCacheReuse =
362
383
  htmlEntryPointCount > 0 &&
363
- // 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
364
385
  !node
365
386
  }
366
387
 
@@ -459,7 +480,7 @@ export const createRollupPlugins = async ({
459
480
  )
460
481
  }
461
482
  } else {
462
- // 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
463
484
  fetchImportMap = () => {
464
485
  const firstEntryPoint = htmlEntryPoints[0] || entryPointsPrepared[0]
465
486
  const { entryProjectRelativeUrl } = firstEntryPoint
@@ -603,13 +624,32 @@ export const createRollupPlugins = async ({
603
624
  }
604
625
 
605
626
  const originalUrl = asOriginalUrl(projectUrl)
606
- 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) {
607
645
  return {
608
646
  isWorker: true,
609
647
  url: ressourceUrl,
610
648
  }
611
649
  }
612
- if (isServiceWorkerUrl(originalUrl)) {
650
+ const classicServiceWorkerBuildRelativeUrl =
651
+ classicServiceWorkerUrls[originalUrl]
652
+ if (classicServiceWorkerBuildRelativeUrl) {
613
653
  return {
614
654
  isServiceWorker: true,
615
655
  url: ressourceUrl,
@@ -618,34 +658,79 @@ export const createRollupPlugins = async ({
618
658
 
619
659
  return ressourceUrl
620
660
  },
621
- emitChunk,
622
- emitAsset,
623
- setAssetSource,
624
661
  onJsModule: ({ ressource, jsModuleUrl, jsModuleIsInline }) => {
625
- if (jsModuleIsInline) {
626
- 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
627
668
  }
628
669
 
629
- urlImporterMap[jsModuleUrl] = {
630
- url: resolveUrl(
670
+ if (ressource.isEntryPoint) {
671
+ } else {
672
+ const importerUrl = resolveUrl(
631
673
  entryPointsPrepared[0].entryProjectRelativeUrl,
632
674
  compileDirectoryServerUrl,
633
- ),
634
- line: undefined,
635
- 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
+ }
636
705
  }
637
- jsModulesFromEntry[asRollupUrl(jsModuleUrl)] = true
638
- const name = urlToBasename(jsModuleUrl)
706
+
707
+ const fileName = ressource.relativeUrl
639
708
  const rollupReferenceId = emitChunk({
640
- id: asRollupUrl(jsModuleUrl),
641
- name,
709
+ id: jsModuleUrl,
710
+ name: urlToBasename(jsModuleUrl),
642
711
  })
643
712
  return {
644
- name,
645
713
  rollupReferenceId,
714
+ fileName,
646
715
  }
647
716
  },
648
- 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,
649
734
  },
650
735
  )
651
736
 
@@ -654,16 +739,15 @@ export const createRollupPlugins = async ({
654
739
  async ({
655
740
  entryContentType,
656
741
  entryProjectRelativeUrl,
657
- entryBuildRelativeUrl,
658
742
  entryBuffer,
659
743
  }) => {
660
744
  if (entryContentType === "application/javascript") {
661
- emitChunk({
662
- id: ensureRelativeUrlNotation(entryProjectRelativeUrl),
663
- name: urlToBasename(`file:///${entryBuildRelativeUrl}`),
664
- ...(urlVersionningForEntryPoints
665
- ? {}
666
- : { fileName: entryBuildRelativeUrl }),
745
+ await ressourceBuilder.createReferenceForEntryPoint({
746
+ entryContentType,
747
+ entryUrl: resolveUrl(
748
+ entryProjectRelativeUrl,
749
+ compileDirectoryServerUrl,
750
+ ),
667
751
  })
668
752
  return
669
753
  }
@@ -684,8 +768,6 @@ export const createRollupPlugins = async ({
684
768
  entryContentType,
685
769
  entryUrl,
686
770
  entryBuffer,
687
- entryBuildRelativeUrl,
688
- urlVersionningForEntryPoints,
689
771
  })
690
772
  },
691
773
  ),
@@ -700,14 +782,19 @@ export const createRollupPlugins = async ({
700
782
  },
701
783
 
702
784
  async resolveId(specifier, importer, { custom }) {
785
+ if (specifier === EMPTY_CHUNK_URL) {
786
+ return specifier
787
+ }
788
+
789
+ let importerUrl
703
790
  if (importer === undefined) {
704
791
  if (specifier.endsWith(".html")) {
705
- importer = compileServerOrigin
792
+ importerUrl = compileServerOrigin
706
793
  } else {
707
- importer = compileDirectoryServerUrl
794
+ importerUrl = compileDirectoryServerUrl
708
795
  }
709
796
  } else {
710
- importer = asServerUrl(importer)
797
+ importerUrl = asServerUrl(importer)
711
798
  }
712
799
 
713
800
  const { importAssertionInfo } = custom
@@ -735,22 +822,20 @@ export const createRollupPlugins = async ({
735
822
  return specifier
736
823
  }
737
824
 
738
- if (isFileSystemPath(importer)) {
739
- importer = fileSystemPathToUrl(importer)
740
- }
741
-
742
- const importUrl = await importResolver.resolveImport(specifier, importer)
743
-
825
+ const importUrl = await importResolver.resolveImport(
826
+ specifier,
827
+ importerUrl,
828
+ )
744
829
  const existingImporter = urlImporterMap[importUrl]
745
830
  if (!existingImporter) {
746
831
  urlImporterMap[importUrl] = importAssertionInfo
747
832
  ? {
748
- url: importer,
833
+ url: importerUrl,
749
834
  column: importAssertionInfo.column,
750
835
  line: importAssertionInfo.line,
751
836
  }
752
837
  : {
753
- url: importer,
838
+ url: importerUrl,
754
839
  // rollup do not expose a way to know line and column for the static or dynamic import
755
840
  // referencing that file
756
841
  column: undefined,
@@ -782,33 +867,31 @@ export const createRollupPlugins = async ({
782
867
  },
783
868
 
784
869
  resolveFileUrl: ({ referenceId, fileName }) => {
785
- const ressourceFound = ressourceBuilder.findRessource((ressource) => {
786
- return ressource.rollupReferenceId === referenceId
787
- })
788
- const buildRelativeUrl = ressourceFound
789
- ? ressourceFound.buildRelativeUrl
790
- : fileName
870
+ ressourcesReferencedByJs.push(fileName)
791
871
 
792
872
  if (format === "esmodule") {
793
873
  if (!node && useImportMapToMaximizeCacheReuse && urlVersioning) {
794
- const buildRelativeUrlWithoutVersion =
795
- buildRelativeUrlToFileName(buildRelativeUrl)
796
- return `window.__resolveImportUrl__("./${buildRelativeUrlWithoutVersion}", import.meta.url)`
874
+ return `window.__resolveImportUrl__("./${fileName}", import.meta.url)`
797
875
  }
798
- return `new URL("${buildRelativeUrl}", import.meta.url)`
876
+ return `new URL("${fileName}", import.meta.url)`
799
877
  }
800
878
  if (format === "systemjs") {
801
- if (useImportMapToMaximizeCacheReuse && urlVersioning) {
802
- const buildRelativeUrlWithoutVersion =
803
- buildRelativeUrlToFileName(buildRelativeUrl)
804
- return `new URL(System.resolve("./${buildRelativeUrlWithoutVersion}", module.meta.url))`
805
- }
806
- return `new URL(System.resolve("./${buildRelativeUrl}", module.meta.url))`
879
+ return `new URL(System.resolve("./${fileName}", module.meta.url))`
807
880
  }
808
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
809
887
  return `new URL("${buildRelativeUrl}", document.currentScript && document.currentScript.src || document.baseURI)`
810
888
  }
811
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
812
895
  return `new URL("${buildRelativeUrl}", "file:///" + __filename.replace(/\\/g, "/"))`
813
896
  }
814
897
  return null
@@ -830,11 +913,10 @@ export const createRollupPlugins = async ({
830
913
  return urlLoader.loadUrl(rollupUrl, {
831
914
  signal,
832
915
  logger,
833
- ressourceBuilder,
834
916
  })
835
917
  })
836
918
 
837
- url = loadResult.url
919
+ if (loadResult.url) url = loadResult.url
838
920
  const code = loadResult.code
839
921
  const map = loadResult.map
840
922
 
@@ -846,6 +928,7 @@ export const createRollupPlugins = async ({
846
928
  originalUrl,
847
929
  jsenvHelpersDirectoryInfo.url,
848
930
  )
931
+ // const isEntryPoint = entryPointUrls[originalUrl]
849
932
 
850
933
  const importer = urlImporterMap[url]
851
934
  // Inform ressource builder that this js module exists
@@ -855,18 +938,12 @@ export const createRollupPlugins = async ({
855
938
  // For import assertions, the imported ressource (css,json,...)
856
939
  // is arelady converted to a js module
857
940
  ressourceBuilder.createReferenceFoundByRollup({
858
- // we don't want to emit a js chunk for every js file found
859
- // (However we want if the file is preload/prefetch by something else)
860
- // so we tell asset builder not to emit a chunk for this js reference
861
- // otherwise rollup would never concat module together
862
- referenceShouldNotEmitChunk: jsConcatenation,
863
941
  contentTypeExpected: "application/javascript",
864
942
  referenceLabel: "static or dynamic import",
865
943
  referenceUrl: importer.url,
866
944
  referenceColumn: importer.column,
867
945
  referenceLine: importer.line,
868
946
  ressourceSpecifier: url,
869
-
870
947
  isJsenvHelperFile,
871
948
  contentType: "application/javascript",
872
949
  bufferBeforeBuild: Buffer.from(code),
@@ -896,18 +973,20 @@ export const createRollupPlugins = async ({
896
973
  onReferenceWithImportMetaUrlPattern: async ({ importNode }) => {
897
974
  const specifier = importNode.arguments[0].value
898
975
  const { line, column } = importNode.loc.start
899
- const reference =
900
- await ressourceBuilder.createReferenceFoundInJsModule({
901
- referenceLabel: "URL + import.meta.url",
902
- jsUrl: url,
903
- jsLine: line,
904
- jsColumn: column,
905
- ressourceSpecifier: specifier,
906
- })
976
+ const reference = ressourceBuilder.createReferenceFoundInJsModule({
977
+ referenceLabel: "URL + import.meta.url",
978
+ jsUrl: url,
979
+ jsLine: line,
980
+ jsColumn: column,
981
+ ressourceSpecifier: specifier,
982
+ })
907
983
  if (!reference) {
908
984
  return
909
985
  }
910
- 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
+ }
911
990
  mutations.push((magicString) => {
912
991
  magicString.overwrite(
913
992
  importNode.start,
@@ -924,7 +1003,6 @@ export const createRollupPlugins = async ({
924
1003
  const { source } = importNode
925
1004
  const importSpecifier = source.value
926
1005
  const { line, column } = importNode.loc.start
927
-
928
1006
  // "type" is dynamic on dynamic import such as
929
1007
  // import("./data.json", {
930
1008
  // assert: {
@@ -952,9 +1030,7 @@ export const createRollupPlugins = async ({
952
1030
  type: typePropertyValue.value,
953
1031
  }
954
1032
  }
955
-
956
1033
  const { type } = assertions
957
-
958
1034
  // "specifier" is dynamic on dynamic import such as
959
1035
  // import(true ? "./a.json" : "b.json", {
960
1036
  // assert: {
@@ -978,9 +1054,7 @@ export const createRollupPlugins = async ({
978
1054
  ),
979
1055
  )
980
1056
  }
981
-
982
1057
  // There is no strategy for css import assertion on Node.js
983
- // and that's normal
984
1058
  if (type === "css" && node) {
985
1059
  throw new Error(
986
1060
  createDetailedMessage(
@@ -1006,29 +1080,31 @@ export const createRollupPlugins = async ({
1006
1080
  },
1007
1081
  }),
1008
1082
  )
1009
-
1010
- const ressourceUrl = asServerUrl(id)
1011
- if (external) {
1012
- if (importAssertionSupportedByRuntime) {
1013
- const reference =
1014
- await ressourceBuilder.createReferenceFoundInJsModule({
1015
- referenceLabel: "import assertion",
1016
- isImportAssertion: true,
1017
- jsUrl: url,
1018
- jsLine: line,
1019
- jsColumn: column,
1020
- ressourceSpecifier: ressourceUrl,
1021
- })
1022
- // reference can be null for cross origin urls
1023
- if (!reference) {
1024
- return
1025
- }
1026
- markBuildRelativeUrlAsUsedByJs(
1027
- reference.ressource.buildRelativeUrl,
1028
- )
1029
- return
1030
- }
1031
-
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) {
1032
1108
  throw new Error(
1033
1109
  createDetailedMessage(
1034
1110
  `import assertion ressource cannot be external when runtime do not support import assertions`,
@@ -1041,16 +1117,64 @@ export const createRollupPlugins = async ({
1041
1117
  )
1042
1118
  }
1043
1119
 
1044
- // we want to convert the import assertions into a js module
1045
- // to do that we append ?import_type to the url
1046
- // In theory this is not needed anymore:
1047
- // This is already done by the compile server
1048
- 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}`,
1049
1128
  ressourceUrl,
1050
- {
1051
- import_type: type,
1052
- },
1053
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
+ }
1054
1178
 
1055
1179
  mutations.push((magicString) => {
1056
1180
  magicString.overwrite(
@@ -1078,9 +1202,6 @@ export const createRollupPlugins = async ({
1078
1202
 
1079
1203
  // resolveImportMeta: () => {}
1080
1204
  outputOptions: (outputOptions) => {
1081
- const extension = extname(entryPointMap[Object.keys(entryPointMap)[0]])
1082
- const outputExtension = extension === ".html" ? ".js" : extension
1083
-
1084
1205
  outputOptions.paths = (id) => {
1085
1206
  const mapping = importPaths[id]
1086
1207
  if (mapping) {
@@ -1093,19 +1214,31 @@ export const createRollupPlugins = async ({
1093
1214
  }
1094
1215
  return id
1095
1216
  }
1217
+ // outputOptions.assetFileNames = () => {
1218
+ // return `assets/[name]_[hash][extname]`
1219
+ // }
1096
1220
  outputOptions.entryFileNames = () => {
1097
- if (urlVersionningForEntryPoints) {
1098
- return `[name]-[hash]${outputExtension}`
1221
+ if (useImportMapToMaximizeCacheReuse) {
1222
+ return `[name]${outputExtension}`
1099
1223
  }
1100
- return `[name]${outputExtension}`
1224
+ return entryPoints
1101
1225
  }
1102
- outputOptions.chunkFileNames = () => {
1226
+ outputOptions.chunkFileNames = (chunkInfo) => {
1103
1227
  // const originalUrl = asOriginalUrl(chunkInfo.facadeModuleId)
1104
1228
  // const basename = urlToBasename(originalUrl)
1105
1229
  if (useImportMapToMaximizeCacheReuse) {
1106
1230
  return `[name]${outputExtension}`
1107
1231
  }
1108
- 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}`
1109
1242
  }
1110
1243
 
1111
1244
  // rollup does not expects to have http dependency in the mix: fix them
@@ -1138,29 +1271,35 @@ export const createRollupPlugins = async ({
1138
1271
  },
1139
1272
 
1140
1273
  async generateBundle(outputOptions, rollupResult) {
1141
- const jsChunks = {}
1274
+ const rollupJsFileInfos = {}
1275
+ const rollupAssetFileInfos = {}
1142
1276
  // To keep in mind: rollupResult object can be mutated by late asset emission
1143
1277
  // however late chunk (js module) emission is not possible
1144
1278
  // as rollup rightfully prevent late js emission
1145
1279
  Object.keys(rollupResult).forEach((fileName) => {
1146
- const file = rollupResult[fileName]
1280
+ const rollupFileInfo = rollupResult[fileName]
1147
1281
 
1148
1282
  // there is 3 types of file: "placeholder", "asset", "chunk"
1149
- if (file.type === "asset") {
1283
+ if (rollupFileInfo.type === "asset") {
1284
+ rollupAssetFileInfos[fileName] = rollupFileInfo
1150
1285
  return
1151
1286
  }
1152
1287
 
1153
- if (file.type === "chunk") {
1154
- const { facadeModuleId } = file
1288
+ if (rollupFileInfo.type === "chunk") {
1289
+ const { facadeModuleId } = rollupFileInfo
1155
1290
  if (facadeModuleId === EMPTY_CHUNK_URL) {
1156
1291
  return
1157
1292
  }
1158
- const fileCopy = { ...file }
1293
+ const fileCopy = { ...rollupFileInfo }
1159
1294
  if (facadeModuleId) {
1160
1295
  fileCopy.url = asServerUrl(facadeModuleId)
1161
1296
  } else {
1162
- const sourcePath = file.map.sources[file.map.sources.length - 1]
1163
- 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
+ )
1164
1303
  const originalProjectUrl = resolveUrl(sourcePath, fileBuildUrl)
1165
1304
  fileCopy.url = asCompiledServerUrl(originalProjectUrl, {
1166
1305
  projectDirectoryUrl,
@@ -1168,69 +1307,31 @@ export const createRollupPlugins = async ({
1168
1307
  compileDirectoryRelativeUrl,
1169
1308
  })
1170
1309
  }
1171
- jsChunks[fileName] = fileCopy
1172
- }
1173
- })
1174
-
1175
- const jsModuleBuild = {}
1176
- Object.keys(jsChunks).forEach((fileName) => {
1177
- const file = jsChunks[fileName]
1178
- let buildRelativeUrl
1179
- const canBeVersioned =
1180
- asRollupUrl(file.url) in jsModulesFromEntry ||
1181
- urlVersionningForEntryPoints ||
1182
- !file.isEntry
1183
-
1184
- if (file.url in inlineModuleScripts && format === "systemjs") {
1185
- const code = file.code
1186
- const systemRegisterIndex = code.indexOf("System.register([")
1187
- const magicString = new MagicString(code)
1188
- magicString.overwrite(
1189
- systemRegisterIndex,
1190
- systemRegisterIndex + "System.register([".length,
1191
- `System.register("${fileName}", [`,
1192
- )
1193
- file.code = magicString.toString()
1194
- }
1195
1310
 
1196
- if (urlVersioning) {
1197
- if (canBeVersioned && useImportMapToMaximizeCacheReuse) {
1198
- buildRelativeUrl = computeBuildRelativeUrl(
1199
- resolveUrl(fileName, buildDirectoryUrl),
1200
- file.code,
1201
- {
1202
- pattern: `[name]-[hash][extname]`,
1203
- lineBreakNormalization,
1204
- contentType: "application/javascript",
1205
- },
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}", [`,
1206
1319
  )
1207
- } else {
1208
- buildRelativeUrl = fileName
1320
+ fileCopy.code = magicString.toString()
1209
1321
  }
1210
- } else {
1211
- buildRelativeUrl = fileName
1212
- fileName = rollupFileNameWithoutHash(fileName)
1213
- }
1214
1322
 
1215
- const originalProjectUrl = asOriginalUrl(file.url)
1216
- const originalProjectRelativeUrl = urlToRelativeUrl(
1217
- originalProjectUrl,
1218
- projectDirectoryUrl,
1219
- )
1220
- const jsRessource = ressourceBuilder.findRessource(
1221
- (ressource) => ressource.url === file.url,
1222
- )
1223
- if (jsRessource && jsRessource.isInline) {
1224
- if (format === "systemjs") {
1225
- markBuildRelativeUrlAsUsedByJs(buildRelativeUrl)
1323
+ if (
1324
+ isReferencedByJs({
1325
+ rollupFileInfo: fileCopy,
1326
+ jsConcatenation,
1327
+ ressourceBuilder,
1328
+ })
1329
+ ) {
1330
+ ressourcesReferencedByJs.push(fileCopy.fileName)
1226
1331
  }
1227
- buildInlineFileContents[buildRelativeUrl] = file.code
1228
- } else {
1229
- markBuildRelativeUrlAsUsedByJs(buildRelativeUrl)
1230
- buildMappings[originalProjectRelativeUrl] = buildRelativeUrl
1231
- }
1232
1332
 
1233
- jsModuleBuild[buildRelativeUrl] = file
1333
+ rollupJsFileInfos[fileName] = fileCopy
1334
+ }
1234
1335
  })
1235
1336
 
1236
1337
  // it's important to do this to emit late asset
@@ -1243,35 +1344,67 @@ export const createRollupPlugins = async ({
1243
1344
  // aux assets faisant référence a ces chunk js qu'ils sont terminés
1244
1345
  // et donc les assets peuvent connaitre le nom du chunk
1245
1346
  // et mettre a jour leur dépendance vers ce fichier js
1246
- 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
+
1247
1388
  // wait html files to be emitted
1248
1389
  await ressourceBuilder.getAllEntryPointsEmittedPromise()
1249
1390
  onBundleEnd()
1250
-
1391
+ const jsModuleBuild = {
1392
+ ...rollupJsFileInfos,
1393
+ }
1251
1394
  const assetBuild = {}
1252
- Object.keys(rollupResult).forEach((rollupFileId) => {
1253
- const file = rollupResult[rollupFileId]
1395
+ Object.keys(rollupResult).forEach((fileName) => {
1396
+ const file = rollupResult[fileName]
1254
1397
  if (file.type !== "asset") {
1255
1398
  return
1256
1399
  }
1257
1400
 
1258
- const { facadeModuleId } = file
1259
- if (facadeModuleId === EMPTY_CHUNK_URL) {
1260
- return
1261
- }
1262
-
1263
1401
  const assetRessource = ressourceBuilder.findRessource(
1264
- (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,
1265
1407
  )
1266
- if (!assetRessource) {
1267
- const buildRelativeUrl = rollupFileId
1268
- const fileName = rollupFileNameWithoutHash(buildRelativeUrl)
1269
- assetBuild[buildRelativeUrl] = file
1270
- buildManifest[fileName] = buildRelativeUrl
1271
- // the asset does not exists in the project it was generated during building
1272
- // happens for sourcemap
1273
- return
1274
- }
1275
1408
 
1276
1409
  // ignore potential useless assets which happens when:
1277
1410
  // - sourcemap re-emitted
@@ -1293,38 +1426,36 @@ export const createRollupPlugins = async ({
1293
1426
  }
1294
1427
 
1295
1428
  const buildRelativeUrl = assetRessource.buildRelativeUrl
1296
- const fileName = rollupFileNameWithoutHash(buildRelativeUrl)
1297
1429
  if (assetRessource.isInline) {
1298
1430
  buildInlineFileContents[buildRelativeUrl] = file.source
1299
- } 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) {
1300
1439
  const originalProjectUrl = asOriginalUrl(assetRessource.url)
1301
1440
  const originalProjectRelativeUrl = urlToRelativeUrl(
1302
1441
  originalProjectUrl,
1303
1442
  projectDirectoryUrl,
1304
1443
  )
1305
- // in case sourcemap is mutated, we must not trust rollup but the asset builder source instead
1306
- file.source = assetRessource.bufferAfterBuild
1307
-
1308
- assetBuild[buildRelativeUrl] = file
1309
1444
  buildMappings[originalProjectRelativeUrl] = buildRelativeUrl
1310
- buildManifest[fileName] = buildRelativeUrl
1311
1445
  }
1312
1446
  })
1313
-
1314
1447
  rollupBuild = {
1315
1448
  ...jsModuleBuild,
1316
1449
  ...assetBuild,
1317
1450
  }
1318
- rollupBuild = injectSourcemapInRollupBuild(rollupBuild, {
1319
- buildDirectoryUrl,
1320
- })
1321
-
1322
- // update rollupBuild, buildInlineFilesContents, buildManifest and buildMappings
1323
- // in case some ressources where inlined by ressourceBuilder.rollupBuildEnd
1324
- Object.keys(rollupBuild).forEach((buildRelativeUrl) => {
1325
- 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]
1326
1457
  const ressource = ressourceBuilder.findRessource((ressource) => {
1327
- if (ressource.buildRelativeUrl === buildRelativeUrl) {
1458
+ if (ressource.buildRelativeUrl === fileName) {
1328
1459
  return true
1329
1460
  }
1330
1461
  if (ressource.url === rollupFileInfo.url) {
@@ -1332,46 +1463,44 @@ export const createRollupPlugins = async ({
1332
1463
  }
1333
1464
  return false
1334
1465
  })
1335
- if (ressource && ressource.isInline) {
1336
- const fileName = buildRelativeUrlToFileName(buildRelativeUrl)
1337
- if (fileName) {
1338
- delete buildManifest[fileName]
1339
- }
1466
+ if (ressource.isInline) {
1467
+ delete buildManifest[fileName]
1340
1468
  const originalProjectUrl = asOriginalUrl(ressource.url)
1341
- delete buildMappings[
1342
- urlToRelativeUrl(originalProjectUrl, projectDirectoryUrl)
1343
- ]
1344
- buildInlineFileContents[buildRelativeUrl] = rollupFileInfo.code
1345
- 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
1346
1479
  }
1347
1480
  })
1348
1481
 
1349
1482
  await finalizeServiceWorkers({
1350
1483
  serviceWorkers,
1484
+ classicServiceWorkers,
1351
1485
  serviceWorkerFinalizer,
1352
1486
  projectDirectoryUrl,
1353
1487
  buildDirectoryUrl,
1354
1488
  rollupBuild,
1355
1489
  buildMappings,
1356
1490
  buildManifest,
1491
+ buildFileContents,
1357
1492
  lineBreakNormalization,
1358
1493
  minify,
1359
1494
  })
1360
1495
 
1361
- rollupBuild = sortObjectByPathnames(rollupBuild)
1362
1496
  buildManifest = sortObjectByPathnames(buildManifest)
1363
1497
  buildMappings = sortObjectByPathnames(buildMappings)
1364
- Object.keys(rollupBuild).forEach((buildRelativeUrl) => {
1365
- const { type, source, code } = rollupBuild[buildRelativeUrl]
1366
- buildFileContents[buildRelativeUrl] = type === "asset" ? source : code
1367
- })
1368
1498
  const buildDuration = Date.now() - buildStartMs
1369
1499
  buildStats = createBuildStats({
1370
1500
  buildFileContents,
1371
1501
  ressourceBuilder,
1372
1502
  buildDuration,
1373
1503
  })
1374
-
1375
1504
  logger.info(
1376
1505
  formatBuildDoneInfo({
1377
1506
  buildStats,
@@ -1400,7 +1529,7 @@ export const createRollupPlugins = async ({
1400
1529
  return {
1401
1530
  rollupPlugins,
1402
1531
  getLastErrorMessage: () => lastErrorMessage,
1403
- getResult: () => {
1532
+ getResult: async () => {
1404
1533
  return {
1405
1534
  rollupBuild,
1406
1535
  urlResponseBodyMap: urlLoader.getUrlResponseBodyMap(),
@@ -1419,7 +1548,7 @@ export const createRollupPlugins = async ({
1419
1548
  }
1420
1549
 
1421
1550
  const prepareEntryPoints = async (
1422
- entryPointMap,
1551
+ entryPoints,
1423
1552
  {
1424
1553
  logger,
1425
1554
  projectDirectoryUrl,
@@ -1428,7 +1557,7 @@ const prepareEntryPoints = async (
1428
1557
  urlFetcher,
1429
1558
  },
1430
1559
  ) => {
1431
- const entryFileRelativeUrls = Object.keys(entryPointMap)
1560
+ const entryFileRelativeUrls = Object.keys(entryPoints)
1432
1561
  const entryPointsPrepared = []
1433
1562
  await entryFileRelativeUrls.reduce(async (previous, entryFileRelativeUrl) => {
1434
1563
  await previous
@@ -1438,10 +1567,9 @@ const prepareEntryPoints = async (
1438
1567
  projectDirectoryUrl,
1439
1568
  )
1440
1569
  const entryBuildUrl = resolveUrl(
1441
- entryPointMap[entryFileRelativeUrl],
1570
+ entryPoints[entryFileRelativeUrl],
1442
1571
  buildDirectoryUrl,
1443
1572
  )
1444
-
1445
1573
  const entryProjectRelativeUrl = urlToRelativeUrl(
1446
1574
  entryProjectUrl,
1447
1575
  projectDirectoryUrl,
@@ -1450,20 +1578,16 @@ const prepareEntryPoints = async (
1450
1578
  entryBuildUrl,
1451
1579
  buildDirectoryUrl,
1452
1580
  )
1453
-
1454
1581
  logger.debug(`${UNICODE.INFO} load entry point ${entryProjectRelativeUrl}`)
1455
-
1456
1582
  const entryServerUrl = resolveUrl(
1457
1583
  entryProjectRelativeUrl,
1458
1584
  compileServerOrigin,
1459
1585
  )
1460
-
1461
1586
  const entryResponse = await urlFetcher.fetchUrl(entryServerUrl, {
1462
- urlTrace: `entryPointMap`,
1587
+ urlTrace: `entryPoints`,
1463
1588
  })
1464
1589
  const entryContentType = entryResponse.headers["content-type"]
1465
1590
  const isHtml = entryContentType === "text/html"
1466
-
1467
1591
  entryPointsPrepared.push({
1468
1592
  entryContentType:
1469
1593
  entryContentType === "text/javascript"
@@ -1511,20 +1635,6 @@ const normalizeRollupResolveReturnValue = (resolveReturnValue) => {
1511
1635
  return resolveReturnValue
1512
1636
  }
1513
1637
 
1514
- const rollupFileNameWithoutHash = (fileName) => {
1515
- return fileName.replace(/-[a-z0-9]{8,}(\..*?)?$/, (_, afterHash = "") => {
1516
- return afterHash
1517
- })
1518
- }
1519
-
1520
- // otherwise importmap handle it as a bare import
1521
- const ensureRelativeUrlNotation = (relativeUrl) => {
1522
- if (relativeUrl.startsWith("../")) {
1523
- return relativeUrl
1524
- }
1525
- return `./${relativeUrl}`
1526
- }
1527
-
1528
1638
  const externalImportUrlPatternsToExternalUrlPredicate = (
1529
1639
  externalImportUrlPatterns,
1530
1640
  projectDirectoryUrl,
@@ -1560,16 +1670,47 @@ const acceptsJsonContentType = ({ node, format }) => {
1560
1670
  return false
1561
1671
  }
1562
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
+
1563
1696
  const finalizeServiceWorkers = async ({
1564
1697
  serviceWorkers,
1698
+ classicServiceWorkers,
1565
1699
  serviceWorkerFinalizer,
1566
1700
  buildMappings,
1567
1701
  buildManifest,
1568
- rollupBuild,
1702
+ buildFileContents,
1569
1703
  lineBreakNormalization,
1570
1704
  }) => {
1705
+ const serviceWorkerKeys = Object.keys(serviceWorkers)
1706
+ const classicServiceWorkerKeys = Object.keys(classicServiceWorkers)
1707
+ const projectRelativeUrls = [
1708
+ ...serviceWorkerKeys,
1709
+ ...classicServiceWorkerKeys,
1710
+ ]
1711
+
1571
1712
  await Promise.all(
1572
- Object.keys(serviceWorkers).map(async (projectRelativeUrl) => {
1713
+ projectRelativeUrls.map(async (projectRelativeUrl) => {
1573
1714
  const projectUrl = resolveUrl(projectRelativeUrl, "file://")
1574
1715
  projectRelativeUrl = urlToRelativeUrl(projectUrl, "file://")
1575
1716
  const serviceWorkerBuildRelativeUrl = buildMappings[projectRelativeUrl]
@@ -1578,14 +1719,29 @@ const finalizeServiceWorkers = async ({
1578
1719
  `"${projectRelativeUrl}" service worker file missing in the build`,
1579
1720
  )
1580
1721
  }
1581
- const buildFileContent = rollupBuild[serviceWorkerBuildRelativeUrl].source
1582
- rollupBuild[serviceWorkerBuildRelativeUrl].source =
1583
- serviceWorkerFinalizer(buildFileContent, {
1722
+
1723
+ // module service worker
1724
+ if (serviceWorkerKeys.includes(projectRelativeUrl)) {
1725
+ let code = buildFileContents[serviceWorkerBuildRelativeUrl]
1726
+ code = await serviceWorkerFinalizer(code, {
1727
+ serviceWorkerBuildRelativeUrl,
1728
+ buildManifest,
1729
+ buildFileContents,
1730
+ lineBreakNormalization,
1731
+ })
1732
+ buildFileContents[serviceWorkerBuildRelativeUrl] = code
1733
+ }
1734
+ // "classic" service worker
1735
+ else {
1736
+ let code = buildFileContents[serviceWorkerBuildRelativeUrl]
1737
+ code = await serviceWorkerFinalizer(code, {
1584
1738
  serviceWorkerBuildRelativeUrl,
1585
1739
  buildManifest,
1586
- rollupBuild,
1740
+ buildFileContents,
1587
1741
  lineBreakNormalization,
1588
1742
  })
1743
+ buildFileContents[serviceWorkerBuildRelativeUrl] = code
1744
+ }
1589
1745
  }),
1590
1746
  )
1591
1747
  }