@jsenv/core 24.1.0-alpha.0 → 24.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/{license → LICENSE} +0 -0
  2. package/dist/browser_runtime/browser_runtime-fbd309a1.js +5137 -0
  3. package/dist/browser_runtime/browser_runtime-fbd309a1.js.map +1064 -0
  4. package/dist/{jsenv_browser_system.js → browser_system/browser_system-29eda202.js} +12 -12
  5. package/dist/{jsenv_browser_system.js.map → browser_system/browser_system-29eda202.js.map} +64 -64
  6. package/dist/build_manifest.js +12 -0
  7. package/dist/compile_proxy/assets/s.js-749702e8.map +242 -0
  8. package/dist/compile_proxy/compile_proxy-405777e6.html +2074 -0
  9. package/dist/compile_proxy/compile_proxy.html__inline__20-39c0801c.js.map +385 -0
  10. package/dist/event_source_client/event_source_client-9f14c8b9.js +356 -0
  11. package/dist/event_source_client/event_source_client-9f14c8b9.js.map +127 -0
  12. package/dist/redirector/assets/s.js-749702e8.map +242 -0
  13. package/dist/redirector/redirector-237cd168.html +2118 -0
  14. package/dist/redirector/redirector.html__inline__15-33acb0b9.js.map +390 -0
  15. package/dist/toolbar/assets/compilation.css-209d68b4.map +12 -0
  16. package/dist/toolbar/assets/eventsource.css-38cd0a36.map +12 -0
  17. package/dist/toolbar/assets/execution.css-0ebe522f.map +12 -0
  18. package/dist/toolbar/assets/focus.css-3f9c156d.map +12 -0
  19. package/dist/toolbar/assets/light-theme.css-78b19a80.map +12 -0
  20. package/dist/toolbar/assets/overflow-menu.css-d9688a1c.map +12 -0
  21. package/dist/toolbar/assets/s.js-749702e8.map +242 -0
  22. package/dist/toolbar/assets/settings.css-2b81b245.map +12 -0
  23. package/dist/toolbar/assets/toolbar.main.css-846920e9.map +28 -0
  24. package/dist/toolbar/assets/tooltip.css-03395ee6.map +12 -0
  25. package/dist/toolbar/toolbar-d3d98c2e.html +4778 -0
  26. package/dist/toolbar/toolbar.main-cab36c15.js.map +795 -0
  27. package/dist/toolbar_injector/assets/jsenv-logo-188b9ca6.svg +95 -0
  28. package/dist/{jsenv_toolbar_injector.js → toolbar_injector/toolbar_injector-01f71ce3.js} +62 -137
  29. package/dist/toolbar_injector/toolbar_injector-01f71ce3.js.map +294 -0
  30. package/main.js +0 -1
  31. package/package.json +4 -2
  32. package/readme.md +10 -7
  33. package/src/buildProject.js +8 -2
  34. package/src/dev_server.js +45 -102
  35. package/src/importUsingChildProcess.js +1 -1
  36. package/src/internal/{runtime/detectBrowser/detectBrowser.js → browser_detection/browser_detection.js} +0 -0
  37. package/src/internal/{runtime/detectBrowser → browser_detection}/detectAndroid.js +0 -0
  38. package/src/internal/{runtime/detectBrowser → browser_detection}/detectChrome.js +0 -0
  39. package/src/internal/{runtime/detectBrowser → browser_detection}/detectEdge.js +0 -0
  40. package/src/internal/{runtime/detectBrowser → browser_detection}/detectElectron.js +0 -0
  41. package/src/internal/{runtime/detectBrowser → browser_detection}/detectFirefox.js +0 -0
  42. package/src/internal/{runtime/detectBrowser → browser_detection}/detectIOS.js +0 -0
  43. package/src/internal/{runtime/detectBrowser → browser_detection}/detectInternetExplorer.js +0 -0
  44. package/src/internal/{runtime/detectBrowser → browser_detection}/detectOpera.js +0 -0
  45. package/src/internal/{runtime/detectBrowser → browser_detection}/detectSafari.js +0 -0
  46. package/src/internal/{runtime/detectBrowser → browser_detection}/util.js +0 -0
  47. package/src/internal/{runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js → browser_feature_detection/browser_feature_detection.js} +116 -81
  48. package/src/internal/browser_feature_detection/compile_proxy.html +27 -0
  49. package/src/internal/{browser-launcher → browser_launcher}/createSharing.js +0 -0
  50. package/src/internal/{browser-launcher → browser_launcher}/executeHtmlFile.js +7 -4
  51. package/src/internal/{browser-launcher → browser_launcher}/trackPageToNotify.js +0 -0
  52. package/src/internal/{browser-launcher/jsenv-browser-system.js → browser_runtime/browser_runtime.js} +4 -4
  53. package/src/internal/{runtime/createBrowserRuntime/createBrowserSystem.js → browser_runtime/browser_system.js} +3 -2
  54. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/createBrowserRuntime.js +7 -5
  55. package/src/internal/{browser-launcher → browser_runtime}/displayErrorInDocument.js +0 -0
  56. package/src/internal/{browser-launcher → browser_runtime}/displayErrorNotification.js +2 -4
  57. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/evalSource.js +2 -0
  58. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/makeNamespaceTransferable.js +0 -0
  59. package/src/internal/{browser-utils → browser_utils}/fetch-browser.js +2 -0
  60. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingFetch.js +3 -0
  61. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingScript.js +2 -0
  62. package/src/internal/{browser-utils → browser_utils}/fetchJson.js +0 -0
  63. package/src/internal/{browser-utils → browser_utils}/fetchUsingXHR.js +4 -4
  64. package/src/internal/building/buildUsingRollup.js +4 -0
  65. package/src/internal/building/createJsenvRollupPlugin.js +19 -9
  66. package/src/internal/building/css/applyPostCss.js +19 -8
  67. package/src/internal/building/css/moveCssUrls.js +44 -0
  68. package/src/internal/building/css/parseCssRessource.js +67 -17
  69. package/src/internal/building/css/parseCssUrls.js +29 -23
  70. package/src/internal/building/css/postcss_plugin_url_visitor.js +11 -20
  71. package/src/internal/building/css/replaceCssUrls.js +38 -19
  72. package/src/internal/building/css_module.js +6 -10
  73. package/src/internal/building/html/parseHtmlRessource.js +37 -11
  74. package/src/internal/building/parseRessource.js +3 -0
  75. package/src/internal/building/ressource_builder.js +12 -3
  76. package/src/internal/compiling/babel_plugin_import_assertions.js +1 -2
  77. package/src/internal/compiling/compile-directory/validateCache.js +0 -5
  78. package/src/internal/compiling/compileFile.js +17 -54
  79. package/src/internal/compiling/createCompiledFileService.js +2 -0
  80. package/src/internal/compiling/html_source_file_service.js +49 -13
  81. package/src/internal/compiling/jsenvCompilerForHtml.js +29 -12
  82. package/src/internal/compiling/startCompileServer.js +39 -33
  83. package/src/internal/dev_server/event_source_client/event_source_client.js +63 -0
  84. package/src/internal/{toolbar/eventsource/connectEventSource.js → dev_server/event_source_client/event_source_connection.js} +66 -88
  85. package/src/internal/dev_server/event_source_client/file_changes.js +82 -0
  86. package/src/internal/dev_server/event_source_client/livereload_preference.js +13 -0
  87. package/src/internal/{exploring → dev_server/exploring}/exploring.css +0 -0
  88. package/src/internal/{exploring → dev_server/exploring}/exploring.html +8 -3
  89. package/src/internal/{exploring → dev_server/exploring}/exploring.js +0 -0
  90. package/src/internal/{exploring → dev_server/exploring}/fetchExploringJson.js +4 -9
  91. package/src/internal/dev_server/redirector/redirector.html +48 -0
  92. package/src/internal/{toolbar → dev_server/toolbar}/animation/toolbar.animation.js +0 -0
  93. package/src/internal/{toolbar → dev_server/toolbar}/compilation/compilation.css +0 -0
  94. package/src/internal/{toolbar → dev_server/toolbar}/compilation/toolbar.compilation.js +4 -7
  95. package/src/internal/{toolbar → dev_server/toolbar}/eventsource/eventsource.css +0 -0
  96. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +83 -0
  97. package/src/internal/{toolbar → dev_server/toolbar}/execution/execution.css +0 -0
  98. package/src/internal/{toolbar → dev_server/toolbar}/execution/toolbar.execution.js +0 -0
  99. package/src/internal/{toolbar → dev_server/toolbar}/focus/focus.css +0 -0
  100. package/src/internal/{toolbar → dev_server/toolbar}/focus/toolbar.focus.js +0 -0
  101. package/src/internal/{toolbar → dev_server/toolbar}/jsenv-logo.svg +0 -0
  102. package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +152 -0
  103. package/src/internal/{toolbar → dev_server/toolbar}/responsive/overflow-menu.css +0 -0
  104. package/src/internal/{toolbar → dev_server/toolbar}/responsive/toolbar.responsive.js +0 -0
  105. package/src/internal/{toolbar → dev_server/toolbar}/settings/settings.css +0 -0
  106. package/src/internal/{toolbar → dev_server/toolbar}/settings/toolbar.settings.js +0 -0
  107. package/src/internal/{toolbar → dev_server/toolbar}/theme/jsenv-theme.css +0 -0
  108. package/src/internal/{toolbar → dev_server/toolbar}/theme/light-theme.css +0 -0
  109. package/src/internal/{toolbar → dev_server/toolbar}/theme/toolbar.theme.js +0 -0
  110. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.html +35 -42
  111. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.injector.js +53 -125
  112. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.css +0 -0
  113. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.js +44 -31
  114. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.css +0 -0
  115. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.js +0 -0
  116. package/src/internal/{toolbar → dev_server/toolbar}/util/animation.js +0 -0
  117. package/src/internal/{toolbar → dev_server/toolbar}/util/dom.js +0 -0
  118. package/src/internal/{toolbar → dev_server/toolbar}/util/fetching.js +2 -2
  119. package/src/internal/{toolbar → dev_server/toolbar}/util/jsenvLogger.js +0 -0
  120. package/src/internal/{toolbar → dev_server/toolbar}/util/preferences.js +0 -0
  121. package/src/internal/{toolbar → dev_server/toolbar}/util/responsive.js +0 -0
  122. package/src/internal/{toolbar → dev_server/toolbar}/util/util.js +0 -0
  123. package/src/internal/{toolbar → dev_server/toolbar}/variant/variant.js +0 -0
  124. package/src/internal/generateGroupMap/one_runtime_compat.js +1 -1
  125. package/src/internal/generateGroupMap/runtime_compat_composition.js +1 -1
  126. package/src/internal/generateGroupMap/runtime_support.js +1 -1
  127. package/src/internal/jsenvInternalFiles.js +0 -84
  128. package/src/internal/jsenv_builds.js +19 -0
  129. package/src/internal/{runtime/node-feature-detect/feature-detect-dynamic-import.mjs → node_feature_detection/feature_detect_dynamic_import.mjs} +0 -0
  130. package/src/internal/{runtime/node-feature-detect/feature-detect-top-level-await.mjs → node_feature_detection/feature_detect_top_level_await.mjs} +0 -0
  131. package/src/internal/{runtime/node-feature-detect → node_feature_detection}/nodeSupportsDynamicImport.js +0 -0
  132. package/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js +16 -0
  133. package/src/internal/{runtime/createNodeRuntime/scanNodeRuntimeFeatures.js → node_feature_detection/node_feature_detection.js} +12 -13
  134. package/src/internal/{node-launcher → node_launcher}/createChildProcessOptions.js +0 -0
  135. package/src/internal/{node-launcher → node_launcher}/createControllableNodeProcess.js +9 -14
  136. package/src/internal/{node-launcher → node_launcher}/kill_process_tree.js +0 -0
  137. package/src/internal/{node-launcher → node_launcher}/processOptions.js +0 -0
  138. package/src/internal/{runtime/detectNode → node_runtime}/detectNode.js +0 -0
  139. package/src/internal/{runtime/createNodeRuntime → node_runtime}/evalSource.js +1 -1
  140. package/src/internal/{runtime/createNodeRuntime → node_runtime}/fetchSource.js +1 -1
  141. package/src/internal/{node-launcher → node_runtime}/nodeControllableFile.mjs +14 -11
  142. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithDynamicImport.js → node_runtime/node_execution_dynamic_import.js} +34 -6
  143. package/src/internal/node_runtime/node_execution_performance.js +67 -0
  144. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithSystemJs.js → node_runtime/node_execution_systemjs.js} +38 -24
  145. package/src/internal/{runtime/createNodeRuntime/createNodeSystem.js → node_runtime/node_system.js} +4 -4
  146. package/src/internal/runtime/computeCompileIdFromGroupId.js +1 -0
  147. package/src/internal/runtime/resolveGroup.js +1 -1
  148. package/src/internal/runtime/resolveRuntimeGroup.js +2 -2
  149. package/src/internal/{semantic-versioning → semantic_versioning}/findHighestVersion.js +0 -0
  150. package/src/internal/{semantic-versioning → semantic_versioning}/findLowestVersion.js +0 -0
  151. package/src/internal/{semantic-versioning → semantic_versioning}/index.js +0 -0
  152. package/src/internal/{semantic-versioning → semantic_versioning}/valueToVersion.js +0 -0
  153. package/src/internal/{semantic-versioning → semantic_versioning}/versionCompare.js +0 -0
  154. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsAbove.js +0 -0
  155. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsBelow.js +0 -0
  156. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsEqual.js +0 -0
  157. package/src/launchBrowser.js +3 -3
  158. package/src/launchNode.js +33 -7
  159. package/src/requireUsingChildProcess.js +1 -1
  160. package/dist/jsenv_compile_proxy.js +0 -1339
  161. package/dist/jsenv_compile_proxy.js.map +0 -378
  162. package/dist/jsenv_exploring_index.js +0 -1092
  163. package/dist/jsenv_exploring_index.js.map +0 -353
  164. package/dist/jsenv_exploring_redirector.js +0 -1386
  165. package/dist/jsenv_exploring_redirector.js.map +0 -384
  166. package/dist/jsenv_toolbar.js +0 -3347
  167. package/dist/jsenv_toolbar.js.map +0 -846
  168. package/dist/jsenv_toolbar_injector.js.map +0 -320
  169. package/src/internal/browser-launcher/jsenv_compile_proxy.html +0 -13
  170. package/src/internal/browser-launcher/jsenv_compile_proxy.js +0 -5
  171. package/src/internal/exploring/exploring.redirector.html +0 -13
  172. package/src/internal/exploring/exploring.redirector.js +0 -28
  173. package/src/internal/node-launcher/node-js-file.js +0 -110
  174. package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +0 -32
  175. package/src/internal/runtime/node-feature-detect/nodeSupportsTopLevelAwait.js +0 -18
  176. package/src/internal/toolbar/backtolist/toolbar.backtolist.js +0 -33
  177. package/src/internal/toolbar/eventsource/connectCompileServerEventSource.js +0 -74
  178. package/src/internal/toolbar/eventsource/toolbar.eventsource.js +0 -239
  179. package/src/internal/toolbar/notification/toolbar.notification.js +0 -121
  180. package/src/nodeRuntime.js +0 -5
@@ -1,12 +1,14 @@
1
+ /* eslint-env browser */
2
+
1
3
  import { normalizeImportMap } from "@jsenv/importmap/src/normalizeImportMap.js"
2
4
 
3
5
  // do not use memoize from @jsenv/filesystem to avoid pulling @jsenv/filesystem code into the browser build
4
- import { memoize } from "../../memoize.js"
5
- import { fetchUrl } from "../../browser-utils/fetch-browser.js"
6
- import { createImportResolverForImportmap } from "../../import-resolution/import-resolver-importmap.js"
7
- import { measureAsyncFnPerf } from "../../perf_browser.js"
6
+ import { fetchUrl } from "../browser_utils/fetch-browser.js"
7
+ import { createImportResolverForImportmap } from "../import-resolution/import-resolver-importmap.js"
8
+ import { memoize } from "../memoize.js"
9
+ import { measureAsyncFnPerf } from "../perf_browser.js"
8
10
 
9
- import { createBrowserSystem } from "./createBrowserSystem.js"
11
+ import { createBrowserSystem } from "./browser_system.js"
10
12
  import { makeNamespaceTransferable } from "./makeNamespaceTransferable.js"
11
13
 
12
14
  const memoizedCreateBrowserSystem = memoize(createBrowserSystem)
@@ -3,10 +3,8 @@ const { Notification } = window
3
3
 
4
4
  const displayErrorNotificationNotAvailable = () => {}
5
5
 
6
- const displayErrorNotificationImplementation = async (error, { icon } = {}) => {
7
- const permission = await Notification.requestPermission()
8
-
9
- if (permission === "granted") {
6
+ const displayErrorNotificationImplementation = (error, { icon } = {}) => {
7
+ if (Notification.permission === "granted") {
10
8
  const notification = new Notification("An error occured", {
11
9
  lang: "en",
12
10
  body: error.stack,
@@ -1,3 +1,5 @@
1
+ /* eslint-env browser */
2
+
1
3
  export const evalSource = (code, href) => {
2
4
  // eslint-disable-next-line no-eval
3
5
  return window.eval(appendSourceURL(code, href))
@@ -1,3 +1,5 @@
1
+ /* eslint-env browser */
2
+
1
3
  import { fetchUsingXHR } from "./fetchUsingXHR.js"
2
4
 
3
5
  const fetchNative = async (url, { mode = "cors", ...options } = {}) => {
@@ -1,4 +1,7 @@
1
+ /* eslint-env browser */
2
+
1
3
  import { createDetailedMessage } from "@jsenv/logger"
4
+
2
5
  import { fetchUrl } from "./fetch-browser.js"
3
6
 
4
7
  export const fetchAndEvalUsingFetch = async (url) => {
@@ -1,3 +1,5 @@
1
+ /* eslint-env browser */
2
+
1
3
  export const fetchAndEvalUsingScript = async (src) => {
2
4
  return new Promise((resolve, reject) => {
3
5
  const script = document.createElement("script")
@@ -1,4 +1,4 @@
1
- import { createDetailedMessage } from "@jsenv/logger"
1
+ /* eslint-env browser */
2
2
 
3
3
  export const fetchUsingXHR = async (
4
4
  url,
@@ -206,9 +206,9 @@ const hasSearchParams = typeof window.URLSearchParams === "function"
206
206
 
207
207
  const createRequestError = (error, { url }) => {
208
208
  return new Error(
209
- createDetailedMessage(`error during xhr request on ${url}.`, {
210
- ["error stack"]: error.stack,
211
- }),
209
+ `error during xhr request on ${url}.
210
+ --- error stack ---
211
+ ${error.stack}`,
212
212
  )
213
213
  }
214
214
 
@@ -50,8 +50,10 @@ export const buildUsingRollup = async ({
50
50
  importPaths,
51
51
 
52
52
  urlVersioning,
53
+ urlVersionningForEntryPoints,
53
54
  lineBreakNormalization,
54
55
  jsConcatenation,
56
+ cssConcatenation,
55
57
  useImportMapToMaximizeCacheReuse,
56
58
  preserveEntrySignatures,
57
59
  treeshake,
@@ -121,8 +123,10 @@ export const buildUsingRollup = async ({
121
123
  importPaths,
122
124
 
123
125
  urlVersioning,
126
+ urlVersionningForEntryPoints,
124
127
  lineBreakNormalization,
125
128
  jsConcatenation,
129
+ cssConcatenation,
126
130
  useImportMapToMaximizeCacheReuse,
127
131
 
128
132
  minify,
@@ -12,6 +12,7 @@ import {
12
12
  urlIsInsideOf,
13
13
  normalizeStructuredMetaMap,
14
14
  urlToMeta,
15
+ urlToBasename,
15
16
  } from "@jsenv/filesystem"
16
17
  import { UNICODE } from "@jsenv/log"
17
18
 
@@ -72,8 +73,10 @@ export const createJsenvRollupPlugin = async ({
72
73
  importAssertionsSupport,
73
74
 
74
75
  urlVersioning,
76
+ urlVersionningForEntryPoints,
75
77
  lineBreakNormalization,
76
78
  jsConcatenation,
79
+ cssConcatenation,
77
80
  useImportMapToMaximizeCacheReuse,
78
81
 
79
82
  minify,
@@ -468,6 +471,7 @@ export const createJsenvRollupPlugin = async ({
468
471
  minifyJs,
469
472
  minifyHtml,
470
473
  minifyCssOptions,
474
+ cssConcatenation,
471
475
  })
472
476
  },
473
477
  },
@@ -586,9 +590,10 @@ export const createJsenvRollupPlugin = async ({
586
590
  atleastOneChunkEmitted = true
587
591
  emitChunk({
588
592
  id: ensureRelativeUrlNotation(entryProjectRelativeUrl),
589
- name: entryBuildRelativeUrl,
590
- // don't hash js entry points
591
- fileName: entryBuildRelativeUrl,
593
+ name: urlToBasename(`file:///${entryBuildRelativeUrl}`),
594
+ ...(urlVersionningForEntryPoints
595
+ ? {}
596
+ : { fileName: entryBuildRelativeUrl }),
592
597
  })
593
598
  return
594
599
  }
@@ -601,15 +606,16 @@ export const createJsenvRollupPlugin = async ({
601
606
  `Unusual content type for entry point, got "${entryContentType}" for ${entryProjectRelativeUrl}`,
602
607
  )
603
608
  }
604
- const entryUrl = resolveUrl(
605
- entryProjectRelativeUrl,
606
- compileServerOrigin,
607
- )
609
+ const entryUrl =
610
+ entryContentType === "text/html"
611
+ ? resolveUrl(entryProjectRelativeUrl, compileServerOrigin)
612
+ : resolveUrl(entryProjectRelativeUrl, compileDirectoryRemoteUrl)
608
613
  await ressourceBuilder.createReferenceForEntryPoint({
609
614
  entryContentType,
610
615
  entryUrl,
611
616
  entryBuffer,
612
617
  entryBuildRelativeUrl,
618
+ urlVersionningForEntryPoints,
613
619
  })
614
620
  },
615
621
  ),
@@ -1015,6 +1021,9 @@ export const createJsenvRollupPlugin = async ({
1015
1021
  return id
1016
1022
  }
1017
1023
  outputOptions.entryFileNames = () => {
1024
+ if (urlVersionningForEntryPoints) {
1025
+ return `[name]-[hash]${outputExtension}`
1026
+ }
1018
1027
  return `[name]${outputExtension}`
1019
1028
  }
1020
1029
  outputOptions.chunkFileNames = () => {
@@ -1097,7 +1106,9 @@ export const createJsenvRollupPlugin = async ({
1097
1106
  const file = jsChunks[fileName]
1098
1107
  let buildRelativeUrl
1099
1108
  const canBeVersioned =
1100
- asRollupUrl(file.url) in jsModulesFromEntry || !file.isEntry
1109
+ asRollupUrl(file.url) in jsModulesFromEntry ||
1110
+ urlVersionningForEntryPoints ||
1111
+ !file.isEntry
1101
1112
 
1102
1113
  if (urlVersioning) {
1103
1114
  if (canBeVersioned && useImportMapToMaximizeCacheReuse) {
@@ -1133,7 +1144,6 @@ export const createJsenvRollupPlugin = async ({
1133
1144
  buildInlineFileContents[buildRelativeUrl] = file.code
1134
1145
  } else {
1135
1146
  markBuildRelativeUrlAsUsedByJs(buildRelativeUrl)
1136
- buildManifest[fileName] = buildRelativeUrl
1137
1147
  buildMappings[originalProjectRelativeUrl] = buildRelativeUrl
1138
1148
  }
1139
1149
  })
@@ -1,23 +1,35 @@
1
1
  import { urlToFileSystemPath } from "@jsenv/filesystem"
2
2
 
3
- export const applyPostCss = async (
4
- cssString,
5
- cssUrl,
3
+ export const applyPostCss = async ({
4
+ code,
5
+ url,
6
+ map,
7
+ sourcemapMethod = "comment",
6
8
  plugins,
7
9
  // https://github.com/postcss/postcss#options
8
10
  options = {},
9
- ) => {
11
+ }) => {
10
12
  const { default: postcss } = await import("postcss")
11
13
 
12
- let result
13
14
  try {
14
- const cssFileUrl = urlToFileUrl(cssUrl)
15
- result = await postcss(plugins).process(cssString, {
15
+ const cssFileUrl = urlToFileUrl(url)
16
+ const result = await postcss(plugins).process(code, {
16
17
  collectUrls: true,
17
18
  from: urlToFileSystemPath(cssFileUrl),
18
19
  to: urlToFileSystemPath(cssFileUrl),
20
+ map: {
21
+ annotation: sourcemapMethod === "comment",
22
+ inline: sourcemapMethod === "inline",
23
+ // https://postcss.org/api/#sourcemapoptions
24
+ ...(map ? { prev: JSON.stringify(map) } : {}),
25
+ },
19
26
  ...options,
20
27
  })
28
+ return {
29
+ code: result.css,
30
+ map: result.map.toJSON(),
31
+ postCssMessages: result.messages,
32
+ }
21
33
  } catch (error) {
22
34
  if (error.name === "CssSyntaxError") {
23
35
  console.error(String(error))
@@ -25,7 +37,6 @@ export const applyPostCss = async (
25
37
  }
26
38
  throw error
27
39
  }
28
- return result
29
40
  }
30
41
 
31
42
  // the goal of this function is to take an url that is likely an http url
@@ -0,0 +1,44 @@
1
+ import { urlToRelativeUrl } from "@jsenv/filesystem"
2
+
3
+ import { applyPostCss } from "./applyPostCss.js"
4
+ import { postCssPluginUrlVisitor } from "./postcss_plugin_url_visitor.js"
5
+
6
+ export const moveCssUrls = async ({
7
+ code,
8
+ from,
9
+ to,
10
+ map,
11
+ sourcemapMethod,
12
+ } = {}) => {
13
+ const fromDirectoryUrl = new URL("./", from).href
14
+ const toDirectoryUrl = new URL("./", to).href
15
+ // same directory, nothing to do
16
+ if (fromDirectoryUrl === toDirectoryUrl) {
17
+ return { code, map }
18
+ }
19
+
20
+ const result = await applyPostCss({
21
+ code,
22
+ url: from,
23
+ map,
24
+ sourcemapMethod,
25
+ plugins: [
26
+ postCssPluginUrlVisitor({
27
+ urlVisitor: ({ specifier }) => {
28
+ if (specifier[0] === "#") {
29
+ return null
30
+ }
31
+ const url = new URL(specifier, fromDirectoryUrl).href
32
+ const relativeUrl = urlToRelativeUrl(url, toDirectoryUrl)
33
+ return relativeUrl
34
+ },
35
+ }),
36
+ ],
37
+ })
38
+ code = result.code
39
+ map = result.map
40
+ return {
41
+ code,
42
+ map,
43
+ }
44
+ }
@@ -1,4 +1,9 @@
1
- import { urlToFilename, urlToRelativeUrl, resolveUrl } from "@jsenv/filesystem"
1
+ import {
2
+ urlToFilename,
3
+ urlToRelativeUrl,
4
+ resolveUrl,
5
+ fileSystemPathToUrl,
6
+ } from "@jsenv/filesystem"
2
7
 
3
8
  import {
4
9
  getCssSourceMappingUrl,
@@ -7,14 +12,18 @@ import {
7
12
  import { getRessourceAsBase64Url } from "../ressource_builder_util.js"
8
13
  import { parseCssUrls } from "./parseCssUrls.js"
9
14
  import { replaceCssUrls } from "./replaceCssUrls.js"
15
+ import { moveCssUrls } from "./moveCssUrls.js"
10
16
 
11
17
  export const parseCssRessource = async (
12
18
  cssRessource,
13
19
  { notifyReferenceFound },
14
- { asProjectUrl, asOriginalUrl, minify, minifyCssOptions },
20
+ { asProjectUrl, asOriginalUrl, minify, minifyCssOptions, cssConcatenation },
15
21
  ) => {
16
22
  const cssString = String(cssRessource.bufferBeforeBuild)
17
23
  const cssSourcemapUrl = getCssSourceMappingUrl(cssString)
24
+ const url = cssRessource.url
25
+ let code = cssString
26
+ let map
18
27
  let sourcemapReference
19
28
  if (cssSourcemapUrl) {
20
29
  sourcemapReference = notifyReferenceFound({
@@ -26,6 +35,8 @@ export const parseCssRessource = async (
26
35
  referenceColumn: 0,
27
36
  isSourcemap: true,
28
37
  })
38
+ await sourcemapReference.ressource.getBufferAvailablePromise()
39
+ map = JSON.parse(String(sourcemapReference.ressource.bufferBeforeBuild))
29
40
  } else {
30
41
  sourcemapReference = notifyReferenceFound({
31
42
  contentType: "application/octet-stream",
@@ -35,20 +46,25 @@ export const parseCssRessource = async (
35
46
  })
36
47
  }
37
48
 
38
- const { atImports, urlDeclarations } = await parseCssUrls(
39
- cssString,
40
- cssRessource.url,
41
- )
42
-
49
+ const { atImports, urlDeclarations } = await parseCssUrls({
50
+ code,
51
+ url,
52
+ })
43
53
  const urlNodeReferenceMapping = new Map()
54
+ const atImportReferences = []
44
55
  atImports.forEach((atImport) => {
45
56
  const importReference = notifyReferenceFound({
46
57
  ressourceSpecifier: atImport.specifier,
47
58
  ...cssNodeToReferenceLocation(atImport.urlDeclarationNode),
48
59
  })
49
60
  urlNodeReferenceMapping.set(atImport.urlNode, importReference)
61
+ atImportReferences.push(importReference)
50
62
  })
51
63
  urlDeclarations.forEach((urlDeclaration) => {
64
+ if (urlDeclaration.specifier[0] === "#") {
65
+ return
66
+ }
67
+
52
68
  const urlReference = notifyReferenceFound({
53
69
  ressourceSpecifier: urlDeclaration.specifier,
54
70
  ...cssNodeToReferenceLocation(urlDeclaration.urlDeclarationNode),
@@ -56,22 +72,20 @@ export const parseCssRessource = async (
56
72
  urlNodeReferenceMapping.set(urlDeclaration.urlNode, urlReference)
57
73
  })
58
74
 
59
- return async ({ getUrlRelativeToImporter, buildDirectoryUrl }) => {
75
+ return async ({
76
+ getUrlRelativeToImporter,
77
+ precomputeBuildRelativeUrl,
78
+ buildDirectoryUrl,
79
+ }) => {
60
80
  const sourcemapRessource = sourcemapReference.ressource
61
-
62
- let code = cssString
63
- let map = sourcemapRessource.isPlaceholder
64
- ? undefined
65
- : JSON.parse(String(sourcemapRessource.bufferBeforeBuild))
66
-
67
81
  const cssCompiledUrl = cssRessource.url
68
82
  const cssOriginalUrl = asOriginalUrl(cssCompiledUrl)
69
83
 
70
84
  const replaceCssResult = await replaceCssUrls({
71
- url: map ? asProjectUrl(cssCompiledUrl) : cssOriginalUrl,
72
- code: cssString,
85
+ url: asProjectUrl(cssCompiledUrl),
86
+ code,
73
87
  map,
74
- getUrlReplacementValue: ({ urlNode }) => {
88
+ urlVisitor: ({ urlNode }) => {
75
89
  const nodeCandidates = Array.from(urlNodeReferenceMapping.keys())
76
90
  const urlNodeFound = nodeCandidates.find((urlNodeCandidate) =>
77
91
  isSameCssDocumentUrlNode(urlNodeCandidate, urlNode),
@@ -95,6 +109,42 @@ export const parseCssRessource = async (
95
109
  }
96
110
  return getUrlRelativeToImporter(cssUrlRessource)
97
111
  },
112
+ cssConcatenation,
113
+ loadCssImport: async (path) => {
114
+ // const cssFileUrl = asProjectUrl(url)
115
+ const importedCssFileUrl = fileSystemPathToUrl(path)
116
+ const atImportReference = atImportReferences.find(
117
+ (atImportReference) => {
118
+ return (
119
+ asProjectUrl(atImportReference.ressource.url) ===
120
+ importedCssFileUrl
121
+ )
122
+ },
123
+ )
124
+ atImportReference.inlinedCallback()
125
+ let code = String(atImportReference.ressource.bufferAfterBuild)
126
+ const moveResult = await moveCssUrls({
127
+ code,
128
+ from: resolveUrl(
129
+ atImportReference.ressource.buildRelativeUrl,
130
+ buildDirectoryUrl,
131
+ ),
132
+ to: resolveUrl(
133
+ precomputeBuildRelativeUrl(cssRessource),
134
+ buildDirectoryUrl,
135
+ ),
136
+ // moveCssUrls will change the css source code
137
+ // Ideally we should update the sourcemap referenced by css
138
+ // to target the one after css urls are moved.
139
+ // It means we should force sourcemap ressource to the new one
140
+ // until it's supported we prevent postcss from updating the
141
+ // sourcemap comment, othwise css would reference a sourcemap
142
+ // that won't by in the build directory
143
+ sourcemapMethod: null,
144
+ })
145
+ code = moveResult.code
146
+ return code
147
+ },
98
148
  cssMinification: minify,
99
149
  cssMinificationOptions: minifyCssOptions,
100
150
  })
@@ -1,32 +1,38 @@
1
1
  import { applyPostCss } from "./applyPostCss.js"
2
2
  import { postCssPluginUrlVisitor } from "./postcss_plugin_url_visitor.js"
3
3
 
4
- export const parseCssUrls = async (css, cssUrl = "file:///file.css") => {
4
+ export const parseCssUrls = async ({ code, url = "file:///file.css" }) => {
5
5
  const atImports = []
6
6
  const urlDeclarations = []
7
-
8
- const postCssPlugins = [postCssPluginUrlVisitor]
9
- const postCssOptions = { collectUrls: true }
10
- const result = await applyPostCss(css, cssUrl, postCssPlugins, postCssOptions)
11
-
12
- result.messages.forEach(
13
- ({ type, specifier, atImportNode, declarationNode, urlNode }) => {
14
- if (type === "import") {
15
- atImports.push({
7
+ await applyPostCss({
8
+ code,
9
+ url,
10
+ plugins: [
11
+ postCssPluginUrlVisitor({
12
+ urlVisitor: ({
13
+ type,
16
14
  specifier,
15
+ atImportNode,
16
+ declarationNode,
17
17
  urlNode,
18
- urlDeclarationNode: atImportNode,
19
- })
20
- }
21
- if (type === "asset") {
22
- urlDeclarations.push({
23
- specifier,
24
- urlNode,
25
- urlDeclarationNode: declarationNode,
26
- })
27
- }
28
- },
29
- )
30
-
18
+ }) => {
19
+ if (type === "import") {
20
+ atImports.push({
21
+ specifier,
22
+ urlNode,
23
+ urlDeclarationNode: atImportNode,
24
+ })
25
+ }
26
+ if (type === "asset") {
27
+ urlDeclarations.push({
28
+ specifier,
29
+ urlNode,
30
+ urlDeclarationNode: declarationNode,
31
+ })
32
+ }
33
+ },
34
+ }),
35
+ ],
36
+ })
31
37
  return { atImports, urlDeclarations }
32
38
  }
@@ -14,18 +14,14 @@ hence sourcemap cannot point the original source location
14
14
  import { fileSystemPathToUrl, resolveUrl } from "@jsenv/filesystem"
15
15
  import { require } from "@jsenv/core/src/internal/require.js"
16
16
 
17
- export const postCssPluginUrlVisitor = () => {
17
+ export const postCssPluginUrlVisitor = ({ urlVisitor = () => null }) => {
18
18
  const parseCssValue = require("postcss-value-parser")
19
19
  const stringifyCssNodes = parseCssValue.stringify
20
20
 
21
21
  return {
22
22
  postcssPlugin: "url_visitor",
23
23
  prepare: (result) => {
24
- const {
25
- from,
26
- collectUrls = false,
27
- getUrlReplacementValue = () => undefined,
28
- } = result.opts
24
+ const { from } = result.opts
29
25
  const fromUrl = fileSystemPathToUrl(from)
30
26
  const mutations = []
31
27
  return {
@@ -109,9 +105,12 @@ export const postCssPluginUrlVisitor = () => {
109
105
  atImportNode,
110
106
  urlNode,
111
107
  }
112
- const urlNewValue = getUrlReplacementValue(urlReference)
113
- if (urlNewValue && urlNewValue !== urlNode.value) {
114
- urlNode.value = urlNewValue
108
+ const urlVisitorReturnValue = urlVisitor(urlReference)
109
+ if (
110
+ urlVisitorReturnValue &&
111
+ urlVisitorReturnValue !== urlNode.value
112
+ ) {
113
+ urlNode.value = urlVisitorReturnValue
115
114
  const newParams = parsed.toString()
116
115
  const newAtImportRule = new AtRule({
117
116
  name: "import",
@@ -120,10 +119,6 @@ export const postCssPluginUrlVisitor = () => {
120
119
  })
121
120
  atImportNode.replaceWith(newAtImportRule)
122
121
  }
123
-
124
- if (collectUrls) {
125
- result.messages.push(urlReference)
126
- }
127
122
  },
128
123
  },
129
124
  Declaration: (declarationNode) => {
@@ -158,14 +153,10 @@ export const postCssPluginUrlVisitor = () => {
158
153
  urlNode,
159
154
  }
160
155
 
161
- if (collectUrls) {
162
- result.messages.push(urlReference)
163
- }
164
-
165
- const urlNewValue = getUrlReplacementValue(urlReference)
166
- if (urlNewValue) {
156
+ const urlVisitorReturnValue = urlVisitor(urlReference)
157
+ if (urlVisitorReturnValue) {
167
158
  urlMutations.push(() => {
168
- urlNode.value = urlNewValue
159
+ urlNode.value = urlVisitorReturnValue
169
160
  })
170
161
  }
171
162
  },
@@ -1,3 +1,8 @@
1
+ import {
2
+ assertAndNormalizeDirectoryUrl,
3
+ urlToFileSystemPath,
4
+ } from "@jsenv/filesystem"
5
+
1
6
  import { require } from "@jsenv/core/src/internal/require.js"
2
7
  import { applyPostCss } from "./applyPostCss.js"
3
8
  import { postCssPluginUrlVisitor } from "./postcss_plugin_url_visitor.js"
@@ -6,32 +11,46 @@ export const replaceCssUrls = async ({
6
11
  url,
7
12
  code,
8
13
  map,
9
- getUrlReplacementValue,
14
+ urlVisitor,
15
+ cssConcatenation = false,
16
+ loadCssImport,
10
17
  cssMinification = false,
11
18
  cssMinificationOptions,
12
19
  } = {}) => {
13
- const postcssPlugins = [
14
- postCssPluginUrlVisitor,
15
- ...(cssMinification
16
- ? [await getCssMinificationPlugin(cssMinificationOptions)]
17
- : []),
18
- ]
19
- const postcssOptions = {
20
- getUrlReplacementValue,
21
- map: {
22
- inline: false,
23
- // https://postcss.org/api/#sourcemapoptions
24
- ...(map ? { prev: JSON.stringify(map) } : {}),
25
- },
26
- }
27
- const result = await applyPostCss(code, url, postcssPlugins, postcssOptions)
28
-
20
+ const result = await applyPostCss({
21
+ code,
22
+ url,
23
+ plugins: [
24
+ postCssPluginUrlVisitor({ urlVisitor }),
25
+ ...(cssConcatenation
26
+ ? [await getCssConcatenationPlugin({ url, loadCssImport })]
27
+ : []),
28
+ ...(cssMinification
29
+ ? [await getCssMinificationPlugin(cssMinificationOptions)]
30
+ : []),
31
+ ],
32
+ })
33
+ code = result.code
34
+ map = result.map
29
35
  return {
30
- code: result.css,
31
- map: result.map.toJSON(),
36
+ code,
37
+ map,
32
38
  }
33
39
  }
34
40
 
41
+ const getCssConcatenationPlugin = async ({ loadCssImport }) => {
42
+ const postcssImport = require("postcss-import")
43
+ return postcssImport({
44
+ resolve: (id, basedir) => {
45
+ const url = new URL(id, assertAndNormalizeDirectoryUrl(basedir)).href
46
+ return urlToFileSystemPath(url)
47
+ },
48
+ load: (id) => {
49
+ return loadCssImport(id)
50
+ },
51
+ })
52
+ }
53
+
35
54
  const getCssMinificationPlugin = async (cssMinificationOptions = {}) => {
36
55
  const cssnano = require("cssnano")
37
56
  const cssnanoDefaultPreset = require("cssnano-preset-default")