@jsenv/core 27.0.0-alpha.3 → 27.0.0-alpha.30

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 (222) hide show
  1. package/main.js +4 -0
  2. package/package.json +17 -14
  3. package/readme.md +4 -12
  4. package/src/build/build.js +527 -307
  5. package/src/build/build_urls_generator.js +33 -21
  6. package/src/build/graph_utils.js +31 -0
  7. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  8. package/src/build/inject_service_worker_urls.js +79 -0
  9. package/src/build/resync_ressource_hints.js +68 -0
  10. package/src/build/start_build_server.js +201 -0
  11. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  12. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  13. package/src/dev/start_dev_server.js +58 -26
  14. package/src/execute/execute.js +30 -4
  15. package/src/execute/run.js +19 -56
  16. package/src/execute/runtimes/browsers/from_playwright.js +201 -147
  17. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  18. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  19. package/src/execute/runtimes/node/node_process.js +280 -39
  20. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  21. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  22. package/src/omega/compat/runtime_compat.js +50 -0
  23. package/src/omega/errors.js +51 -58
  24. package/src/omega/fetched_content_compliance.js +24 -0
  25. package/src/omega/file_url_converter.js +8 -50
  26. package/src/omega/kitchen.js +409 -286
  27. package/src/omega/server/file_service.js +9 -11
  28. package/src/omega/url_graph/url_graph_load.js +14 -7
  29. package/src/omega/url_graph/url_graph_report.js +17 -15
  30. package/src/omega/url_graph.js +32 -10
  31. package/src/omega/web_workers.js +42 -0
  32. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  33. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  34. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  35. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  36. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  37. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +27 -168
  38. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  39. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  40. package/src/plugins/bundling/css/bundle_css.js +21 -0
  41. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  42. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +108 -78
  43. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  44. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
  45. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  46. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
  47. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  48. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  49. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  50. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  51. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  52. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  53. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
  54. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  55. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  56. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  57. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  58. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +98 -0
  59. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -8
  60. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  61. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  62. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  63. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +25 -0
  64. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  65. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  66. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  67. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  68. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  69. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
  70. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  71. package/src/plugins/minification/css/minify_css.js +9 -0
  72. package/src/plugins/minification/html/minify_html.js +15 -0
  73. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  74. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  75. package/src/plugins/minification/json/minify_json.js +8 -0
  76. package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
  77. package/src/{omega → plugins}/plugin_controller.js +18 -10
  78. package/src/plugins/plugins.js +73 -0
  79. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  80. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  81. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  82. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  83. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +183 -0
  84. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +256 -0
  85. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +139 -0
  86. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  87. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  88. package/src/{omega/core_plugins/babel/babel_helper → plugins/transpilation/babel/helpers}/babel_plugin_babel_helpers_as_jsenv_imports.js +1 -2
  89. package/src/plugins/transpilation/babel/helpers/babel_plugin_structure.js +161 -0
  90. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  91. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +38 -22
  92. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +31 -6
  93. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  95. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  96. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  97. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  98. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
  100. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +225 -0
  101. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +37 -0
  102. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  103. package/src/plugins/url_references/css/css_urls.js +49 -0
  104. package/src/plugins/url_references/html/html_urls.js +273 -0
  105. package/src/plugins/url_references/js/js_urls.js +163 -0
  106. package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
  107. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  108. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  109. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
  110. package/src/test/execute_plan.js +25 -11
  111. package/src/test/execute_test_plan.js +14 -1
  112. package/src/test/logs_file_execution.js +8 -7
  113. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  114. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  115. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  116. package/src/execute/runtimes/node/controlled_process.js +0 -316
  117. package/src/omega/core_plugins/babel/babel_helper/babel_helper_directory.js +0 -29
  118. package/src/omega/core_plugins/babel/babel_helper/client/.eslintrc.cjs +0 -24
  119. package/src/omega/core_plugins/babel/babel_helper/client/AsyncGenerator/AsyncGenerator.js +0 -81
  120. package/src/omega/core_plugins/babel/babel_helper/client/AwaitValue/AwaitValue.js +0 -3
  121. package/src/omega/core_plugins/babel/babel_helper/client/applyDecoratorDescriptor/applyDecoratorDescriptor.js +0 -33
  122. package/src/omega/core_plugins/babel/babel_helper/client/arrayLikeToArray/arrayLikeToArray.js +0 -7
  123. package/src/omega/core_plugins/babel/babel_helper/client/arrayWithHoles/arrayWithHoles.js +0 -4
  124. package/src/omega/core_plugins/babel/babel_helper/client/arrayWithoutHoles/arrayWithoutHoles.js +0 -6
  125. package/src/omega/core_plugins/babel/babel_helper/client/assertThisInitialized/assertThisInitialized.js +0 -7
  126. package/src/omega/core_plugins/babel/babel_helper/client/asyncGeneratorDelegate/asyncGeneratorDelegate.js +0 -40
  127. package/src/omega/core_plugins/babel/babel_helper/client/asyncIterator/asyncIterator.js +0 -65
  128. package/src/omega/core_plugins/babel/babel_helper/client/asyncToGenerator/asyncToGenerator.js +0 -34
  129. package/src/omega/core_plugins/babel/babel_helper/client/awaitAsyncGenerator/awaitAsyncGenerator.js +0 -5
  130. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +0 -20
  131. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorGet/classApplyDescriptorGet.js +0 -6
  132. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorSet/classApplyDescriptorSet.js +0 -13
  133. package/src/omega/core_plugins/babel/babel_helper/client/classCallCheck/classCallCheck.js +0 -5
  134. package/src/omega/core_plugins/babel/babel_helper/client/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +0 -5
  135. package/src/omega/core_plugins/babel/babel_helper/client/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +0 -6
  136. package/src/omega/core_plugins/babel/babel_helper/client/classExtractFieldDescriptor/classExtractFieldDescriptor.js +0 -7
  137. package/src/omega/core_plugins/babel/babel_helper/client/classNameTDZError/classNameTDZError.js +0 -4
  138. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +0 -7
  139. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldGet/classPrivateFieldGet.js +0 -7
  140. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +0 -6
  141. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +0 -5
  142. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldSet/classPrivateFieldSet.js +0 -8
  143. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateMethodGet/classPrivateMethodGet.js +0 -6
  144. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateMethodSet/classPrivateMethodSet.js +0 -3
  145. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +0 -9
  146. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +0 -15
  147. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +0 -6
  148. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +0 -3
  149. package/src/omega/core_plugins/babel/babel_helper/client/construct/construct.js +0 -16
  150. package/src/omega/core_plugins/babel/babel_helper/client/createClass/createClass.js +0 -15
  151. package/src/omega/core_plugins/babel/babel_helper/client/createForOfIteratorHelper/createForOfIteratorHelper.js +0 -60
  152. package/src/omega/core_plugins/babel/babel_helper/client/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +0 -23
  153. package/src/omega/core_plugins/babel/babel_helper/client/createRawReactElement/createRawReactElement.js +0 -50
  154. package/src/omega/core_plugins/babel/babel_helper/client/createSuper/createSuper.js +0 -22
  155. package/src/omega/core_plugins/babel/babel_helper/client/decorate/decorate.js +0 -403
  156. package/src/omega/core_plugins/babel/babel_helper/client/defaults/defaults.js +0 -11
  157. package/src/omega/core_plugins/babel/babel_helper/client/defineEnumerableProperties/defineEnumerableProperties.js +0 -23
  158. package/src/omega/core_plugins/babel/babel_helper/client/defineProperty/defineProperty.js +0 -18
  159. package/src/omega/core_plugins/babel/babel_helper/client/extends/extends.js +0 -14
  160. package/src/omega/core_plugins/babel/babel_helper/client/get/get.js +0 -19
  161. package/src/omega/core_plugins/babel/babel_helper/client/getPrototypeOf/getPrototypeOf.js +0 -4
  162. package/src/omega/core_plugins/babel/babel_helper/client/inherits/inherits.js +0 -19
  163. package/src/omega/core_plugins/babel/babel_helper/client/inheritsLoose/inheritsLoose.js +0 -7
  164. package/src/omega/core_plugins/babel/babel_helper/client/initializerDefineProperty/initializerDefineProperty.js +0 -10
  165. package/src/omega/core_plugins/babel/babel_helper/client/initializerWarningHelper/initializerWarningHelper.js +0 -6
  166. package/src/omega/core_plugins/babel/babel_helper/client/instanceof/instanceof.js +0 -6
  167. package/src/omega/core_plugins/babel/babel_helper/client/interopRequireDefault/interopRequireDefault.js +0 -3
  168. package/src/omega/core_plugins/babel/babel_helper/client/interopRequireWildcard/interopRequireWildcard.js +0 -37
  169. package/src/omega/core_plugins/babel/babel_helper/client/isNativeFunction/isNativeFunction.js +0 -4
  170. package/src/omega/core_plugins/babel/babel_helper/client/isNativeReflectConstruct/isNativeReflectConstruct.js +0 -21
  171. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArray/iterableToArray.js +0 -7
  172. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArrayLimit/iterableToArrayLimit.js +0 -36
  173. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +0 -10
  174. package/src/omega/core_plugins/babel/babel_helper/client/jsx/jsx.js +0 -50
  175. package/src/omega/core_plugins/babel/babel_helper/client/maybeArrayLike/maybeArrayLike.js +0 -10
  176. package/src/omega/core_plugins/babel/babel_helper/client/newArrowCheck/newArrowCheck.js +0 -5
  177. package/src/omega/core_plugins/babel/babel_helper/client/nonIterableRest/nonIterableRest.js +0 -5
  178. package/src/omega/core_plugins/babel/babel_helper/client/nonIterableSpread/nonIterableSpread.js +0 -5
  179. package/src/omega/core_plugins/babel/babel_helper/client/objectDestructuringEmpty/objectDestructuringEmpty.js +0 -3
  180. package/src/omega/core_plugins/babel/babel_helper/client/objectSpread/objectSpread.js +0 -23
  181. package/src/omega/core_plugins/babel/babel_helper/client/objectSpread2/objectSpread2.js +0 -41
  182. package/src/omega/core_plugins/babel/babel_helper/client/objectWithoutProperties/objectWithoutProperties.js +0 -19
  183. package/src/omega/core_plugins/babel/babel_helper/client/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +0 -13
  184. package/src/omega/core_plugins/babel/babel_helper/client/possibleConstructorReturn/possibleConstructorReturn.js +0 -10
  185. package/src/omega/core_plugins/babel/babel_helper/client/readOnlyError/readOnlyError.js +0 -4
  186. package/src/omega/core_plugins/babel/babel_helper/client/readme.md +0 -8
  187. package/src/omega/core_plugins/babel/babel_helper/client/set/set.js +0 -44
  188. package/src/omega/core_plugins/babel/babel_helper/client/setPrototypeOf/setPrototypeOf.js +0 -6
  189. package/src/omega/core_plugins/babel/babel_helper/client/skipFirstGeneratorNext/skipFirstGeneratorNext.js +0 -8
  190. package/src/omega/core_plugins/babel/babel_helper/client/slicedToArray/slicedToArray.js +0 -10
  191. package/src/omega/core_plugins/babel/babel_helper/client/slicedToArrayLoose/slicedToArrayLoose.js +0 -13
  192. package/src/omega/core_plugins/babel/babel_helper/client/superPropBase/superPropBase.js +0 -10
  193. package/src/omega/core_plugins/babel/babel_helper/client/taggedTemplateLiteral/taggedTemplateLiteral.js +0 -10
  194. package/src/omega/core_plugins/babel/babel_helper/client/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +0 -7
  195. package/src/omega/core_plugins/babel/babel_helper/client/tdz/tdz.js +0 -4
  196. package/src/omega/core_plugins/babel/babel_helper/client/temporalRef/temporalRef.js +0 -6
  197. package/src/omega/core_plugins/babel/babel_helper/client/temporalUndefined/temporalUndefined.js +0 -3
  198. package/src/omega/core_plugins/babel/babel_helper/client/toArray/toArray.js +0 -10
  199. package/src/omega/core_plugins/babel/babel_helper/client/toConsumableArray/toConsumableArray.js +0 -10
  200. package/src/omega/core_plugins/babel/babel_helper/client/toPrimitive/toPrimitive.js +0 -10
  201. package/src/omega/core_plugins/babel/babel_helper/client/toPropertyKey/toPropertyKey.js +0 -6
  202. package/src/omega/core_plugins/babel/babel_helper/client/typeof/typeof.js +0 -14
  203. package/src/omega/core_plugins/babel/babel_helper/client/unsupportedIterableToArray/unsupportedIterableToArray.js +0 -12
  204. package/src/omega/core_plugins/babel/babel_helper/client/wrapAsyncGenerator/wrapAsyncGenerator.js +0 -8
  205. package/src/omega/core_plugins/babel/babel_helper/client/wrapNativeSuper/wrapNativeSuper.js +0 -30
  206. package/src/omega/core_plugins/babel/babel_helper/client/wrapRegExp/wrapRegExp.js +0 -63
  207. package/src/omega/core_plugins/babel/babel_helper/client/writeOnlyError/writeOnlyError.js +0 -4
  208. package/src/omega/core_plugins/babel/helpers/babel_plugin_structure.js +0 -187
  209. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  210. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  211. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  212. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  213. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  214. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  215. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  216. package/src/omega/core_plugins.js +0 -39
  217. package/src/omega/runtime_support/runtime_support.js +0 -20
  218. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  219. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  220. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  221. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  222. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -21,28 +21,30 @@ import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
21
21
  import {
22
22
  injectQueryParams,
23
23
  setUrlFilename,
24
+ asUrlUntilPathname,
24
25
  } from "@jsenv/utils/urls/url_utils.js"
25
- import { createUrlVersionGenerator } from "@jsenv/utils/urls/url_version_generator.js"
26
+ import { createVersionGenerator } from "@jsenv/utils/versioning/version_generator.js"
26
27
  import { generateSourcemapUrl } from "@jsenv/utils/sourcemap/sourcemap_utils.js"
27
28
  import {
28
29
  parseHtmlString,
29
30
  stringifyHtmlAst,
30
31
  } from "@jsenv/utils/html_ast/html_ast.js"
31
32
 
32
- import { defaultRuntimeSupport } from "../omega/runtime_support/default_runtime_support.js"
33
- import { jsenvPluginInline } from "../omega/core_plugins/inline/jsenv_plugin_inline.js"
33
+ import { jsenvPluginInline } from "../plugins/inline/jsenv_plugin_inline.js"
34
+ import { jsenvPluginAsJsClassic } from "../plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js"
34
35
  import { createUrlGraph } from "../omega/url_graph.js"
35
- import { getCorePlugins } from "../omega/core_plugins.js"
36
+ import { getCorePlugins } from "../plugins/plugins.js"
36
37
  import { createKitchen } from "../omega/kitchen.js"
37
38
  import { loadUrlGraph } from "../omega/url_graph/url_graph_load.js"
38
39
  import { createUrlGraphSummary } from "../omega/url_graph/url_graph_report.js"
39
40
  import { sortUrlGraphByDependencies } from "../omega/url_graph/url_graph_sort.js"
41
+ import { isWebWorkerEntryPointReference } from "../omega/web_workers.js"
40
42
 
43
+ import { GRAPH } from "./graph_utils.js"
41
44
  import { createBuilUrlsGenerator } from "./build_urls_generator.js"
42
- import { injectVersionMappings } from "./inject_version_mappings.js"
43
- import { jsenvPluginBundleJsModule } from "./plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js"
44
- import { jsenvPluginMinifyJs } from "./plugins/minify_js/jsenv_plugin_minify_js.js"
45
- import { jsenvPluginMinifyHtml } from "./plugins/minify_html/jsenv_plugin_minify_html.js"
45
+ import { injectGlobalVersionMapping } from "./inject_global_version_mappings.js"
46
+ import { injectServiceWorkerUrls } from "./inject_service_worker_urls.js"
47
+ import { resyncRessourceHints } from "./resync_ressource_hints.js"
46
48
 
47
49
  export const build = async ({
48
50
  signal = new AbortController().signal,
@@ -54,37 +56,40 @@ export const build = async ({
54
56
  // that will just pass different options to build project
55
57
  // and this function will be agnostic about "preview" concept
56
58
  isPreview = false,
59
+
57
60
  plugins = [],
58
- htmlSupervisor,
61
+ sourcemaps = isPreview ? "file" : false,
59
62
  nodeEsmResolution,
60
63
  fileSystemMagicResolution,
61
- babel,
62
- runtimeSupport = defaultRuntimeSupport,
63
- sourcemaps = isPreview ? "file" : false,
64
-
64
+ injectedGlobals,
65
+ runtimeCompat,
66
+ transpilation = {},
65
67
  bundling = true,
66
- minify = true,
67
- versioning = "filename", // "filename", "search_param", "none"
68
+ minification = true,
69
+ versioning = true,
70
+ versioningMethod = "search_param", // "filename", "search_param"
68
71
  lineBreakNormalization = process.platform === "win32",
69
72
 
70
73
  writeOnFileSystem = true,
71
74
  buildDirectoryClean = true,
72
75
  baseUrl = "/",
76
+ assetManifest = true,
77
+ assetManifestFileRelativeUrl = "asset-manifest.json",
73
78
  }) => {
74
79
  const logger = createLogger({ logLevel })
75
80
  rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
76
81
  buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
77
82
  assertEntryPoints({ entryPoints })
78
- if (!["filename", "search_param", "none"].includes(versioning)) {
83
+ if (!["filename", "search_param"].includes(versioningMethod)) {
79
84
  throw new Error(
80
- `Unexpected "versioning": must be "filename", "search_param" or "none"; got ${versioning}`,
85
+ `Unexpected "versioningMethod": must be "filename", "search_param"; got ${versioning}`,
81
86
  )
82
87
  }
83
88
 
84
89
  const entryPointKeys = Object.keys(entryPoints)
85
90
  if (entryPointKeys.length === 1) {
86
91
  logger.info(`
87
- build ${entryPointKeys[0]}`)
92
+ build "${entryPointKeys[0]}"`)
88
93
  } else {
89
94
  logger.info(`
90
95
  build ${entryPointKeys.length} entry points`)
@@ -97,6 +102,9 @@ build ${entryPointKeys.length} entry points`)
97
102
  logger,
98
103
  rootDirectoryUrl,
99
104
  urlGraph: rawGraph,
105
+ scenario: "build",
106
+ sourcemaps,
107
+ runtimeCompat,
100
108
  plugins: [
101
109
  ...plugins,
102
110
  {
@@ -108,33 +116,34 @@ build ${entryPointKeys.length} entry points`)
108
116
  },
109
117
  },
110
118
  ...getCorePlugins({
111
- htmlSupervisor,
112
119
  nodeEsmResolution,
113
120
  fileSystemMagicResolution,
114
- babel,
121
+ injectedGlobals,
122
+ transpilation: {
123
+ ...transpilation,
124
+ jsModuleAsJsClassic: false,
125
+ },
126
+ minification,
127
+ bundling,
115
128
  }),
116
- jsenvPluginBundleJsModule(),
117
- ...(minify ? [jsenvPluginMinifyJs(), jsenvPluginMinifyHtml()] : []),
118
129
  ],
119
- scenario: "build",
120
- sourcemaps,
121
130
  })
122
- const loadEntryFiles = (cookEntryFile) => {
123
- Object.keys(entryPoints).forEach((key) => {
124
- cookEntryFile({
125
- trace: `"${key}" in entryPoints parameter`,
126
- type: "entry_point",
127
- specifier: key,
128
- })
129
- })
130
- }
131
+ const entryUrls = []
131
132
  try {
132
133
  await loadUrlGraph({
133
134
  urlGraph: rawGraph,
134
135
  kitchen: rawGraphKitchen,
135
136
  outDirectoryUrl: new URL(`.jsenv/build/`, rootDirectoryUrl),
136
- runtimeSupport,
137
- startLoading: loadEntryFiles,
137
+ startLoading: (cookEntryFile) => {
138
+ Object.keys(entryPoints).forEach((key) => {
139
+ const [, entryUrlInfo] = cookEntryFile({
140
+ trace: `"${key}" in entryPoints parameter`,
141
+ type: "entry_point",
142
+ specifier: key,
143
+ })
144
+ entryUrls.push(entryUrlInfo.url)
145
+ })
146
+ },
138
147
  })
139
148
  } catch (e) {
140
149
  prebuildTask.fail()
@@ -147,44 +156,50 @@ build ${entryPointKeys.length} entry points`)
147
156
  ${Object.keys(rawGraph.urlInfos).join("\n")}`,
148
157
  )
149
158
 
159
+ const buildUrlsGenerator = createBuilUrlsGenerator({
160
+ buildDirectoryUrl,
161
+ })
162
+ const rawUrls = {}
163
+ const buildUrls = {}
164
+ const rawUrlRedirections = {}
150
165
  const bundleUrlInfos = {}
151
- if (bundling) {
152
- const bundlers = {}
153
- rawGraphKitchen.pluginController.plugins.forEach((plugin) => {
154
- const bundle = plugin.bundle
155
- if (!bundle) {
166
+ const bundlers = {}
167
+ rawGraphKitchen.pluginController.plugins.forEach((plugin) => {
168
+ const bundle = plugin.bundle
169
+ if (!bundle) {
170
+ return
171
+ }
172
+ if (typeof bundle !== "object") {
173
+ throw new Error(
174
+ `bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
175
+ )
176
+ }
177
+ Object.keys(bundle).forEach((type) => {
178
+ const bundleFunction = bundle[type]
179
+ if (!bundleFunction) {
156
180
  return
157
181
  }
158
- if (typeof bundle !== "object") {
159
- throw new Error(
160
- `bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
161
- )
162
- }
163
- Object.keys(bundle).forEach((type) => {
164
- const bundlerForThatType = bundlers[type]
165
- if (bundlerForThatType) {
166
- // first plugin to define a bundle hook wins
167
- return
168
- }
169
- bundlers[type] = {
170
- plugin,
171
- bundleFunction: bundle[type],
172
- urlInfos: [],
173
- }
174
- })
175
- })
176
- const addToBundlerIfAny = (rawUrlInfo) => {
177
- const bundler = bundlers[rawUrlInfo.type]
178
- if (bundler) {
179
- bundler.urlInfos.push(rawUrlInfo)
182
+ const bundlerForThatType = bundlers[type]
183
+ if (bundlerForThatType) {
184
+ // first plugin to define a bundle hook wins
180
185
  return
181
186
  }
182
- }
183
- Object.keys(rawGraph.urlInfos).forEach((rawUrl) => {
184
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
185
- if (!rawUrlInfo.data.isEntryPoint) {
186
- return
187
+ bundlers[type] = {
188
+ plugin,
189
+ bundleFunction: bundle[type],
190
+ urlInfos: [],
187
191
  }
192
+ })
193
+ })
194
+ const addToBundlerIfAny = (rawUrlInfo) => {
195
+ const bundler = bundlers[rawUrlInfo.type]
196
+ if (bundler) {
197
+ bundler.urlInfos.push(rawUrlInfo)
198
+ return
199
+ }
200
+ }
201
+ GRAPH.forEach(rawGraph, (rawUrlInfo) => {
202
+ if (rawUrlInfo.data.isEntryPoint) {
188
203
  addToBundlerIfAny(rawUrlInfo)
189
204
  if (rawUrlInfo.type === "html") {
190
205
  rawUrlInfo.dependencies.forEach((dependencyUrl) => {
@@ -194,7 +209,8 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
194
209
  // bundle inline script type module deps
195
210
  dependencyUrlInfo.references.forEach((inlineScriptRef) => {
196
211
  if (inlineScriptRef.type === "js_import_export") {
197
- addToBundlerIfAny(rawGraph.getUrlInfo(inlineScriptRef.url))
212
+ const inlineUrlInfo = rawGraph.getUrlInfo(inlineScriptRef.url)
213
+ addToBundlerIfAny(inlineUrlInfo)
198
214
  }
199
215
  })
200
216
  }
@@ -205,231 +221,321 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
205
221
  })
206
222
  return
207
223
  }
208
- })
209
- await Object.keys(bundlers).reduce(async (previous, type) => {
210
- await previous
211
- const bundler = bundlers[type]
212
- const urlInfosToBundle = bundler.urlInfos
213
- if (urlInfosToBundle.length === 0) {
214
- return
215
- }
216
- const bundleTask = createTaskLog(logger, `bundle "${type}"`)
217
- try {
218
- const bundlerGeneratedUrlInfos =
219
- await rawGraphKitchen.pluginController.callAsyncHook(
220
- {
221
- plugin: bundler.plugin,
222
- hookName: "bundle",
223
- value: bundler.bundleFunction,
224
- },
225
- urlInfosToBundle,
226
- {
227
- signal,
228
- logger,
229
- rootDirectoryUrl,
230
- buildDirectoryUrl,
231
- urlGraph: rawGraph,
232
- runtimeSupport,
233
- sourcemaps,
234
- },
235
- )
236
- Object.keys(bundlerGeneratedUrlInfos).forEach((url) => {
237
- const bundleUrlInfo = bundlerGeneratedUrlInfos[url]
238
- const rawUrlInfo = rawGraph.getUrlInfo(url)
239
- bundleUrlInfos[url] = {
240
- type,
241
- ...bundleUrlInfo,
242
- data: {
243
- ...(rawUrlInfo ? rawUrlInfo.data : {}),
244
- ...bundleUrlInfo.data,
245
- fromBundle: true,
246
- },
247
- }
224
+ }
225
+ // File referenced with new URL('./file.js', import.meta.url)
226
+ // are entry points that can be bundled
227
+ // For instance we will bundle service worker/workers detected like this
228
+ if (rawUrlInfo.type === "js_module") {
229
+ rawUrlInfo.references.forEach((reference) => {
230
+ if (reference.type === "js_url_specifier") {
231
+ const urlInfo = rawGraph.getUrlInfo(reference.url)
232
+ addToBundlerIfAny(urlInfo)
233
+ }
234
+ })
235
+ }
236
+ })
237
+ await Object.keys(bundlers).reduce(async (previous, type) => {
238
+ await previous
239
+ const bundler = bundlers[type]
240
+ const urlInfosToBundle = bundler.urlInfos
241
+ if (urlInfosToBundle.length === 0) {
242
+ return
243
+ }
244
+ const bundleTask = createTaskLog(logger, `bundle "${type}"`)
245
+ try {
246
+ const bundlerGeneratedUrlInfos =
247
+ await rawGraphKitchen.pluginController.callAsyncHook(
248
+ {
249
+ plugin: bundler.plugin,
250
+ hookName: "bundle",
251
+ value: bundler.bundleFunction,
252
+ },
253
+ urlInfosToBundle,
254
+ {
255
+ ...rawGraphKitchen.baseContext,
256
+ buildDirectoryUrl,
257
+ },
258
+ )
259
+ Object.keys(bundlerGeneratedUrlInfos).forEach((url) => {
260
+ const rawUrlInfo = rawGraph.getUrlInfo(url)
261
+ const bundlerGeneratedUrlInfo = bundlerGeneratedUrlInfos[url]
262
+ const bundleUrlInfo = {
263
+ type,
264
+ subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
265
+ filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
266
+ ...bundlerGeneratedUrlInfo,
267
+ data: {
268
+ ...(rawUrlInfo ? rawUrlInfo.data : {}),
269
+ ...bundlerGeneratedUrlInfo.data,
270
+ fromBundle: true,
271
+ },
272
+ }
273
+ const buildUrl = buildUrlsGenerator.generate(url, {
274
+ urlInfo: bundleUrlInfo,
248
275
  })
249
- } catch (e) {
250
- bundleTask.fail()
251
- throw e
252
- }
253
- bundleTask.done()
254
- }, Promise.resolve())
255
- }
276
+ rawUrlRedirections[url] = buildUrl
277
+ rawUrls[buildUrl] = url
278
+ bundleUrlInfos[buildUrl] = bundleUrlInfo
279
+ })
280
+ } catch (e) {
281
+ bundleTask.fail()
282
+ throw e
283
+ }
284
+ bundleTask.done()
285
+ }, Promise.resolve())
256
286
 
257
- const buildUrlsGenerator = createBuilUrlsGenerator({
258
- buildDirectoryUrl,
259
- })
260
- const rawUrls = {}
261
- const buildUrls = {}
287
+ const buildUrlRedirections = {}
262
288
  const finalGraph = createUrlGraph()
263
- const optimizeHooks = rawGraphKitchen.pluginController.addHook("optimize")
289
+ const optimizeUrlContentHooks =
290
+ rawGraphKitchen.pluginController.addHook("optimizeUrlContent")
264
291
  const finalGraphKitchen = createKitchen({
265
292
  logger,
266
293
  rootDirectoryUrl,
267
294
  urlGraph: finalGraph,
268
- // Inline content, such as <script> inside html, is transformed during the previous phase.
269
- // If we read the inline content it would be considered as the original content.
270
- // - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
271
- // as the original content.
272
- // - But it would not work when sourcemap are not generated
273
- // - would be a bit slower
274
- // - So instead of reading the inline content directly, we search into raw graph
275
- // to get "originalContent" and "sourcemap"
276
- loadInlineUrlInfos: (finalUrlInfo) => {
277
- const rawUrl = finalUrlInfo.data.rawUrl
278
- const bundleUrlInfo = bundleUrlInfos[rawUrl]
279
- const urlInfo = bundleUrlInfo || finalUrlInfo
280
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
281
- return {
282
- originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
283
- sourcemap: bundleUrlInfo
284
- ? bundleUrlInfo.sourcemap
285
- : rawUrlInfo
286
- ? rawUrlInfo.sourcemap
287
- : undefined,
288
- contentType: urlInfo.contentType,
289
- content: urlInfo.content,
290
- }
291
- },
295
+ scenario: "build",
296
+ sourcemaps,
297
+ runtimeCompat,
292
298
  plugins: [
293
- jsenvPluginInline(),
299
+ jsenvPluginAsJsClassic({
300
+ systemJsInjection: true,
301
+ }),
302
+ jsenvPluginInline({
303
+ fetchInlineUrls: false,
304
+ }),
294
305
  {
295
306
  name: "jsenv:postbuild",
296
307
  appliesDuring: { build: true },
297
- resolve: (reference) => {
298
- if (reference.specifier[0] === "/") {
299
- const url = new URL(reference.specifier.slice(1), rootDirectoryUrl)
300
- .href
301
- return url
308
+ resolveUrl: (reference) => {
309
+ if (reference.specifier[0] === "#") {
310
+ reference.external = true
302
311
  }
303
- const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
304
- if (parentUrlInfo && parentUrlInfo.data.fromBundle) {
305
- // code generated by rollup contains specifier relative
306
- // to the generated file.
307
- // This file does not exists yet we must resolve against the raw url, not the build url
308
- const parentRawUrl = parentUrlInfo.data.rawUrl
309
- const rawUrl = new URL(reference.specifier, parentRawUrl).href
310
- return rawUrl
312
+ let url =
313
+ reference.specifier[0] === "/"
314
+ ? new URL(reference.specifier.slice(1), buildDirectoryUrl).href
315
+ : new URL(reference.specifier, reference.parentUrl).href
316
+ const parentIsFromBundle = Boolean(
317
+ bundleUrlInfos[reference.parentUrl],
318
+ )
319
+ // urls inside css bundled by parcel
320
+ // contains url relative to the bundle file (which is considered inside build directory)
321
+ // if the file is not itself a bundle file it must be resolved against
322
+ // the original css url
323
+ if (
324
+ parentIsFromBundle &&
325
+ !bundleUrlInfos[url] &&
326
+ urlIsInsideOf(url, buildDirectoryUrl)
327
+ ) {
328
+ const parentRawUrl = rawUrls[reference.parentUrl]
329
+ url = new URL(reference.specifier, parentRawUrl).href
311
330
  }
312
- return new URL(reference.specifier, reference.parentUrl).href
331
+ const urlRedirected = rawUrlRedirections[url]
332
+ return urlRedirected || url
313
333
  },
314
- normalize: (reference) => {
334
+ normalizeUrl: (reference) => {
315
335
  if (!reference.url.startsWith("file:")) {
316
336
  return null
317
337
  }
318
338
  // already a build url
319
339
  const rawUrl = rawUrls[reference.url]
320
340
  if (rawUrl) {
321
- reference.data.rawUrl = rawUrl
322
341
  return reference.url
323
342
  }
324
- const bundleUrlInfo = bundleUrlInfos[reference.url]
325
343
  // from rollup or postcss
344
+ const bundleUrlInfo = bundleUrlInfos[reference.url]
326
345
  if (bundleUrlInfo) {
327
- const buildUrl = buildUrlsGenerator.generate(
328
- reference.url,
329
- bundleUrlInfo,
330
- )
331
- reference.data.rawUrl = reference.url
332
- rawUrls[buildUrl] = reference.url
333
- return buildUrl
346
+ return reference.url
334
347
  }
335
- const rawUrlInfo = rawGraph.getUrlInfo(reference.url)
336
- // files from root directory but not given to rollup nor postcss
337
- if (rawUrlInfo) {
338
- const buildUrl = buildUrlsGenerator.generate(
339
- reference.url,
340
- rawUrlInfo,
341
- )
342
- reference.data.rawUrl = reference.url
343
- rawUrls[buildUrl] = reference.url
348
+ // from "js_module_as_js_classic":
349
+ // - injecting "?as_js_classic" for the first time
350
+ // - injecting "?as_js_classic" because the parentUrl has it
351
+ if (reference.original) {
352
+ const referenceOriginalUrl = reference.original.url
353
+ let originalBuildUrl
354
+ if (urlIsInsideOf(referenceOriginalUrl, buildDirectoryUrl)) {
355
+ originalBuildUrl = referenceOriginalUrl
356
+ } else {
357
+ originalBuildUrl = Object.keys(rawUrls).find(
358
+ (key) => rawUrls[key] === referenceOriginalUrl,
359
+ )
360
+ }
361
+ let rawUrl
362
+ if (urlIsInsideOf(reference.url, buildDirectoryUrl)) {
363
+ // rawUrl = rawUrls[reference.url] || reference.url
364
+ const originalBuildUrl =
365
+ buildUrlRedirections[referenceOriginalUrl]
366
+ rawUrl = originalBuildUrl
367
+ ? rawUrls[originalBuildUrl]
368
+ : reference.url
369
+ } else {
370
+ rawUrl = reference.url
371
+ }
372
+ // the url info do not exists yet (it will be created after this "normalize" hook)
373
+ // And the content will be generated when url is cooked by url graph loader.
374
+ // Here we just want to reserve an url for that file
375
+ const buildUrl = buildUrlsGenerator.generate(rawUrl, {
376
+ urlInfo: {
377
+ data: {
378
+ ...reference.data,
379
+ isWebWorkerEntryPoint:
380
+ isWebWorkerEntryPointReference(reference),
381
+ },
382
+ type: reference.expectedType,
383
+ subtype: reference.expectedSubtype,
384
+ filename: reference.filename,
385
+ },
386
+ })
387
+ buildUrlRedirections[originalBuildUrl] = buildUrl
388
+ rawUrls[buildUrl] = rawUrl
344
389
  return buildUrl
345
390
  }
346
391
  if (reference.isInline) {
347
- const rawUrl = Object.keys(rawGraph.urlInfos).find((url) => {
348
- const rawUrlInfo = rawGraph.urlInfos[url]
392
+ const rawUrlInfo = GRAPH.find(rawGraph, (rawUrlInfo) => {
349
393
  if (!rawUrlInfo.isInline) {
350
394
  return false
351
395
  }
352
396
  if (rawUrlInfo.content === reference.content) {
353
397
  return true
354
398
  }
399
+ if (rawUrlInfo.originalContent === reference.content) {
400
+ return true
401
+ }
355
402
  return false
356
403
  })
357
- if (!rawUrl) {
358
- throw new Error(`cannot find raw url`)
359
- }
360
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
361
404
  const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
362
- const buildUrl = buildUrlsGenerator.generate(
363
- reference.url,
364
- rawUrlInfo,
405
+ if (!rawUrlInfo) {
406
+ // generated during final graph
407
+ // (happens for JSON.parse injected for import assertions for instance)
408
+ // throw new Error(`cannot find raw url for "${reference.url}"`)
409
+ return reference.url
410
+ }
411
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
412
+ urlInfo: rawUrlInfo,
365
413
  parentUrlInfo,
366
- )
414
+ })
415
+ rawUrls[buildUrl] = rawUrlInfo.url
416
+ return buildUrl
417
+ }
418
+ // from "js_module_as_js_classic":
419
+ // - to inject "s.js"
420
+ if (reference.injected) {
421
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
422
+ urlInfo: {
423
+ data: {},
424
+ type: "js_classic",
425
+ },
426
+ })
367
427
  rawUrls[buildUrl] = reference.url
368
- reference.data.rawUrl = rawUrl
428
+ return buildUrl
429
+ }
430
+ const rawUrlInfo = rawGraph.getUrlInfo(reference.url)
431
+ // files from root directory but not given to rollup nor postcss
432
+ if (rawUrlInfo) {
433
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
434
+ urlInfo: rawUrlInfo,
435
+ })
436
+ rawUrls[buildUrl] = rawUrlInfo.url
369
437
  return buildUrl
370
438
  }
371
439
  if (reference.type === "sourcemap_comment") {
372
440
  // inherit parent build url
373
441
  return generateSourcemapUrl(reference.parentUrl)
374
442
  }
375
- // files generated during the final graph (sourcemaps)
443
+ // files generated during the final graph:
444
+ // - sourcemaps
376
445
  // const finalUrlInfo = finalGraph.getUrlInfo(url)
377
446
  const buildUrl = buildUrlsGenerator.generate(reference.url, {
378
- data: {},
379
- type: "asset",
447
+ urlInfo: {
448
+ data: {},
449
+ type: "asset",
450
+ },
380
451
  })
381
452
  return buildUrl
382
453
  },
383
- formatReferencedUrl: (reference) => {
384
- if (!reference.url.startsWith("file:")) {
454
+ formatUrl: (reference) => {
455
+ if (!reference.generatedUrl.startsWith("file:")) {
385
456
  return null
386
457
  }
387
- if (!urlIsInsideOf(reference.url, buildDirectoryUrl)) {
458
+ if (!urlIsInsideOf(reference.generatedUrl, buildDirectoryUrl)) {
388
459
  throw new Error(
389
460
  `urls should be inside build directory at this stage, found "${reference.url}"`,
390
461
  )
391
462
  }
463
+ // remove eventual search params and hash
464
+ const urlUntilPathname = asUrlUntilPathname(reference.generatedUrl)
392
465
  // if a file is in the same directory we could prefer the relative notation
393
- // but to keep things simple let's keep the notation relative to baseUrl for now
466
+ // but to keep things simple let's keep the "absolutely relative" to baseUrl for now
394
467
  const specifier = `${baseUrl}${urlToRelativeUrl(
395
- reference.url,
468
+ urlUntilPathname,
396
469
  buildDirectoryUrl,
397
470
  )}`
398
- buildUrls[specifier] = reference.url
471
+ buildUrls[specifier] = reference.generatedUrl
399
472
  return specifier
400
473
  },
401
- load: (finalUrlInfo) => {
402
- const rawUrl = finalUrlInfo.data.rawUrl
403
- const bundleUrlInfo = bundleUrlInfos[rawUrl]
404
- const urlInfo = bundleUrlInfo || rawGraph.getUrlInfo(rawUrl)
405
- return {
406
- data: bundleUrlInfo ? bundleUrlInfo.data : undefined,
407
- originalContent: urlInfo.originalContent,
408
- contentType: urlInfo.contentType,
409
- content: urlInfo.content,
410
- sourcemap: urlInfo.sourcemap,
474
+ fetchUrlContent: async (finalUrlInfo, context) => {
475
+ if (!finalUrlInfo.url.startsWith("file:")) {
476
+ return { external: true }
411
477
  }
412
- },
413
- transform: {
414
- html: (urlInfo) => {
415
- const htmlAst = parseHtmlString(urlInfo.content, {
416
- storeOriginalPositions: false,
417
- })
418
- return {
419
- content: stringifyHtmlAst(htmlAst, {
420
- removeOriginalPositionAttributes: true,
421
- }),
478
+ const fromBundleOrRawGraph = (url) => {
479
+ const bundleUrlInfo = bundleUrlInfos[url]
480
+ if (bundleUrlInfo) {
481
+ return bundleUrlInfo
422
482
  }
423
- },
483
+ const rawUrl = rawUrls[url] || url
484
+ const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
485
+ if (!rawUrlInfo) {
486
+ const originalBuildUrl = buildUrlRedirections[url]
487
+ if (originalBuildUrl) {
488
+ return fromBundleOrRawGraph(originalBuildUrl)
489
+ }
490
+ throw new Error(`Cannot find url`)
491
+ }
492
+ if (rawUrlInfo.isInline) {
493
+ // Inline content, such as <script> inside html, is transformed during the previous phase.
494
+ // If we read the inline content it would be considered as the original content.
495
+ // - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
496
+ // as the original content.
497
+ // - But it would not work when sourcemap are not generated
498
+ // - would be a bit slower
499
+ // - So instead of reading the inline content directly, we search into raw graph
500
+ // to get "originalContent" and "sourcemap"
501
+ finalUrlInfo.type = rawUrlInfo.type
502
+ finalUrlInfo.subtype = rawUrlInfo.subtype
503
+ return rawUrlInfo
504
+ }
505
+ return rawUrlInfo
506
+ }
507
+ // reference injected during "postbuild":
508
+ // - happens for "as_js_classic" injecting "s.js"
509
+ if (context.reference.injected) {
510
+ const [ref, rawUrlInfo] = rawGraphKitchen.injectReference({
511
+ type: context.reference.type,
512
+ expectedType: context.reference.expectedType,
513
+ expectedSubtype: context.reference.expectedSubtype,
514
+ parentUrl: rawUrls[context.reference.parentUrl],
515
+ specifier: context.reference.specifier,
516
+ injected: true,
517
+ })
518
+ await rawGraphKitchen.cook({
519
+ reference: ref,
520
+ urlInfo: rawUrlInfo,
521
+ })
522
+ return rawUrlInfo
523
+ }
524
+ // reference updated during "postbuild":
525
+ // - happens for "as_js_classic"
526
+ if (context.reference.original) {
527
+ return fromBundleOrRawGraph(context.reference.original.url)
528
+ }
529
+ return fromBundleOrRawGraph(finalUrlInfo.url)
424
530
  },
425
531
  },
426
532
  {
427
533
  name: "jsenv:optimize",
428
534
  appliesDuring: { build: true },
429
- transform: async (urlInfo, context) => {
430
- if (optimizeHooks.length) {
535
+ finalizeUrlContent: async (urlInfo, context) => {
536
+ if (optimizeUrlContentHooks.length) {
431
537
  await rawGraphKitchen.pluginController.callAsyncHooks(
432
- "optimize",
538
+ "optimizeUrlContent",
433
539
  urlInfo,
434
540
  context,
435
541
  async (optimizeReturnValue) => {
@@ -443,17 +549,24 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
443
549
  },
444
550
  },
445
551
  ],
446
- scenario: "build",
447
- sourcemaps,
448
552
  })
449
553
  const buildTask = createTaskLog(logger, "build")
554
+ const postBuildEntryUrls = []
450
555
  try {
451
556
  await loadUrlGraph({
452
557
  urlGraph: finalGraph,
453
558
  kitchen: finalGraphKitchen,
454
559
  outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
455
- runtimeSupport,
456
- startLoading: loadEntryFiles,
560
+ startLoading: (cookEntryFile) => {
561
+ entryUrls.forEach((entryUrl) => {
562
+ const [, postBuildEntryUrlInfo] = cookEntryFile({
563
+ trace: `entryPoint`,
564
+ type: "entry_point",
565
+ specifier: entryUrl,
566
+ })
567
+ postBuildEntryUrls.push(postBuildEntryUrlInfo.url)
568
+ })
569
+ },
457
570
  })
458
571
  } catch (e) {
459
572
  buildTask.fail()
@@ -465,7 +578,7 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
465
578
  `graph urls pre-versioning:
466
579
  ${Object.keys(finalGraph.urlInfos).join("\n")}`,
467
580
  )
468
- if (versioning !== "none") {
581
+ if (versioning) {
469
582
  const versioningTask = createTaskLog(logger, "inject version in urls")
470
583
  try {
471
584
  const urlsSorted = sortUrlGraphByDependencies(finalGraph)
@@ -477,23 +590,57 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
477
590
  if (urlInfo.type === "sourcemap") {
478
591
  return
479
592
  }
593
+ // ignore:
594
+ // - inline files:
595
+ // they are already taken into account in the file where they appear
596
+ // - external files
597
+ // we don't know their content
598
+ // - unused files without reference
599
+ // File updated such as style.css -> style.css.js or file.js->file.es5.js
600
+ // Are used at some point just to be discarded later because they need to be converted
601
+ // There is no need to version them and we could not because the file have been ignored
602
+ // so their content is unknown
480
603
  if (urlInfo.isInline) {
481
604
  return
482
605
  }
483
- const urlVersionGenerator = createUrlVersionGenerator()
484
- urlVersionGenerator.augmentWithContent({
485
- content: urlInfo.content,
606
+ if (urlInfo.external) {
607
+ return
608
+ }
609
+ if (!urlInfo.data.isEntryPoint && urlInfo.dependents.size === 0) {
610
+ return
611
+ }
612
+
613
+ const urlContent =
614
+ urlInfo.type === "html"
615
+ ? stringifyHtmlAst(
616
+ parseHtmlString(urlInfo.content, {
617
+ storeOriginalPositions: false,
618
+ }),
619
+ { removeOriginalPositionAttributes: true },
620
+ )
621
+ : urlInfo.content
622
+ const versionGenerator = createVersionGenerator()
623
+ versionGenerator.augmentWithContent({
624
+ content: urlContent,
486
625
  contentType: urlInfo.contentType,
487
626
  lineBreakNormalization,
488
627
  })
489
628
  urlInfo.dependencies.forEach((dependencyUrl) => {
629
+ // this dependency is inline (data:) or remote (http://, https://)
630
+ if (!dependencyUrl.startsWith("file:")) {
631
+ return
632
+ }
490
633
  const dependencyUrlInfo = finalGraph.getUrlInfo(dependencyUrl)
491
- if (dependencyUrlInfo.isInline) {
634
+ if (
492
635
  // this content is part of the file, no need to take into account twice
636
+ dependencyUrlInfo.isInline ||
637
+ // this dependency content is not known
638
+ dependencyUrlInfo.external
639
+ ) {
493
640
  return
494
641
  }
495
642
  if (dependencyUrlInfo.data.version) {
496
- urlVersionGenerator.augmentWithDependencyVersion(
643
+ versionGenerator.augmentWithDependencyVersion(
497
644
  dependencyUrlInfo.data.version,
498
645
  )
499
646
  } else {
@@ -501,18 +648,19 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
501
648
  // it means there is a circular dependency between this file
502
649
  // and it's dependency
503
650
  // in that case we'll use the dependency content
504
- urlVersionGenerator.augmentWithContent({
651
+ versionGenerator.augmentWithContent({
505
652
  content: dependencyUrlInfo.content,
506
653
  contentType: dependencyUrlInfo.contentType,
507
654
  lineBreakNormalization,
508
655
  })
509
656
  }
510
657
  })
511
- urlInfo.data.version = urlVersionGenerator.generate()
658
+ urlInfo.data.version = versionGenerator.generate()
659
+
512
660
  urlInfo.data.versionedUrl = injectVersionIntoBuildUrl({
513
661
  buildUrl: urlInfo.url,
514
662
  version: urlInfo.data.version,
515
- versioning,
663
+ versioningMethod,
516
664
  })
517
665
  })
518
666
  const versionMappings = {}
@@ -521,41 +669,37 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
521
669
  logger,
522
670
  rootDirectoryUrl: buildDirectoryUrl,
523
671
  urlGraph: finalGraph,
524
- loadInlineUrlInfos: (versionedUrlInfo) => {
525
- const rawUrlInfo = rawGraph.getUrlInfo(versionedUrlInfo.data.rawUrl)
526
- const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
527
- return {
528
- originalContent: rawUrlInfo
529
- ? rawUrlInfo.originalContent
530
- : undefined,
531
- sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
532
- contentType: versionedUrlInfo.contentType,
533
- content: versionedUrlInfo.content,
534
- }
535
- },
672
+ scenario: "build",
673
+ sourcemaps,
674
+ runtimeCompat,
536
675
  plugins: [
537
676
  jsenvPluginInline({
677
+ fetchInlineUrls: false,
678
+ analyzeConvertedScripts: true, // to be able to version their urls
538
679
  allowEscapeForVersioning: true,
539
680
  }),
540
681
  {
541
682
  name: "jsenv:versioning",
542
683
  appliesDuring: { build: true },
543
- resolve: ({ parentUrl, specifier }) => {
544
- const buildUrl = buildUrls[specifier]
684
+ resolveUrl: (reference) => {
685
+ if (reference.specifier[0] === "#") {
686
+ reference.external = true
687
+ }
688
+ const buildUrl = buildUrls[reference.specifier]
545
689
  if (buildUrl) {
546
690
  return buildUrl
547
691
  }
548
- const url = new URL(specifier, parentUrl).href
692
+ const url = new URL(reference.specifier, reference.parentUrl).href
549
693
  return url
550
694
  },
551
- formatReferencedUrl: (reference) => {
695
+ formatUrl: (reference) => {
552
696
  if (reference.isInline) {
553
697
  return null
554
698
  }
555
699
  // specifier comes from "normalize" hook done a bit earlier in this file
556
700
  // we want to get back their build url to access their infos
557
701
  const referencedUrlInfo = finalGraph.getUrlInfo(reference.url)
558
- if (referencedUrlInfo.data.isEntryPoint) {
702
+ if (!canUseVersionedUrl(referencedUrlInfo)) {
559
703
  return reference.specifier
560
704
  }
561
705
  // data:* urls and so on
@@ -575,6 +719,8 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
575
719
  buildDirectoryUrl,
576
720
  )}`
577
721
  versionMappings[reference.specifier] = versionedSpecifier
722
+ buildUrls[versionedSpecifier] = versionedUrl
723
+
578
724
  const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
579
725
  if (parentUrlInfo.jsQuote) {
580
726
  // the url is inline inside js quotes
@@ -585,7 +731,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
585
731
  )})+${parentUrlInfo.jsQuote}`
586
732
  }
587
733
  if (
588
- reference.type === "js_import_meta_url_pattern" ||
734
+ reference.type === "js_url_specifier" ||
589
735
  reference.subtype === "import_dynamic"
590
736
  ) {
591
737
  usedVersionMappings.push(reference.specifier)
@@ -593,48 +739,52 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
593
739
  }
594
740
  return versionedSpecifier
595
741
  },
596
- load: ({ url }) => {
597
- const urlInfo = finalGraph.getUrlInfo(url)
598
- return {
599
- originalContent: urlInfo.originalContent,
600
- contentType: urlInfo.contentType,
601
- content: urlInfo.content,
602
- sourcemap: urlInfo.sourcemap,
742
+ fetchUrlContent: (versionedUrlInfo) => {
743
+ if (!versionedUrlInfo.url.startsWith("file:")) {
744
+ return { external: true }
745
+ }
746
+ if (versionedUrlInfo.isInline) {
747
+ const rawUrlInfo = rawGraph.getUrlInfo(
748
+ rawUrls[versionedUrlInfo.url],
749
+ )
750
+ const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
751
+ return {
752
+ originalContent: rawUrlInfo
753
+ ? rawUrlInfo.originalContent
754
+ : undefined,
755
+ sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
756
+ contentType: versionedUrlInfo.contentType,
757
+ content: versionedUrlInfo.content,
758
+ }
603
759
  }
760
+ return versionedUrlInfo
604
761
  },
605
762
  },
606
763
  ],
607
- scenario: "build",
608
- sourcemaps,
609
- })
610
- // arrange state before reloading all files
611
- Object.keys(finalGraph.urlInfos).forEach((url) => {
612
- const urlInfo = finalGraph.urlInfos[url]
613
- urlInfo.data.promise = null
614
764
  })
615
765
  await loadUrlGraph({
616
766
  urlGraph: finalGraph,
617
767
  kitchen: versioningKitchen,
618
- runtimeSupport,
619
- startLoading: loadEntryFiles,
768
+ startLoading: (cookEntryFile) => {
769
+ postBuildEntryUrls.forEach((postBuildEntryUrl) => {
770
+ cookEntryFile({
771
+ trace: `entryPoint`,
772
+ type: "entry_point",
773
+ specifier: postBuildEntryUrl,
774
+ })
775
+ })
776
+ },
620
777
  })
621
778
  if (usedVersionMappings.length) {
622
779
  const versionMappingsNeeded = {}
623
780
  usedVersionMappings.forEach((specifier) => {
624
781
  versionMappingsNeeded[specifier] = versionMappings[specifier]
625
782
  })
626
- await Promise.all(
627
- Object.keys(finalGraph.urlInfos).map(async (buildUrl) => {
628
- const buildUrlInfo = finalGraph.getUrlInfo(buildUrl)
629
- if (!buildUrlInfo.data.isEntryPoint) {
630
- return
631
- }
632
- await injectVersionMappings(buildUrlInfo, {
633
- kitchen: finalGraphKitchen,
634
- versionMappings: versionMappingsNeeded,
635
- })
636
- }),
637
- )
783
+ await injectGlobalVersionMapping({
784
+ finalGraphKitchen,
785
+ finalGraph,
786
+ versionMappings: versionMappingsNeeded,
787
+ })
638
788
  }
639
789
  } catch (e) {
640
790
  versioningTask.fail()
@@ -643,39 +793,90 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
643
793
  versioningTask.done()
644
794
  }
645
795
 
646
- const buildFileContents = {}
647
- const buildInlineFileContents = {}
648
- const buildManifest = {}
649
- Object.keys(finalGraph.urlInfos).forEach((url) => {
650
- if (!url.startsWith("file:")) {
796
+ GRAPH.forEach(finalGraph, (urlInfo) => {
797
+ if (!urlInfo.url.startsWith("file:")) {
651
798
  return
652
799
  }
653
- const buildUrlInfo = finalGraph.getUrlInfo(url)
654
- const versionedUrl = buildUrlInfo.data.versionedUrl
655
- const useVersionedUrl = versionedUrl && !buildUrlInfo.data.isEntryPoint
656
- const buildUrl = useVersionedUrl ? versionedUrl : buildUrlInfo.url
657
- if (!urlIsInsideOf(buildUrl, buildDirectoryUrl)) {
658
- throw new Error(`build url outside build directory`)
800
+ if (urlInfo.external) {
801
+ return
659
802
  }
660
- const buildRelativeUrl = urlToRelativeUrl(buildUrl, buildDirectoryUrl)
661
- if (buildUrlInfo.isInline) {
662
- buildInlineFileContents[buildRelativeUrl] = buildUrlInfo.content
663
- } else {
664
- buildFileContents[buildRelativeUrl] = buildUrlInfo.content
803
+ if (urlInfo.type === "html") {
804
+ const htmlAst = parseHtmlString(urlInfo.content, {
805
+ storeOriginalPositions: false,
806
+ })
807
+ urlInfo.content = stringifyHtmlAst(htmlAst, {
808
+ removeOriginalPositionAttributes: true,
809
+ })
665
810
  }
666
- if (useVersionedUrl) {
667
- const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
668
- buildUrlInfo.url,
669
- buildDirectoryUrl,
670
- )
671
- buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
811
+ const version = urlInfo.data.version
812
+ const useVersionedUrl = version && canUseVersionedUrl(urlInfo, finalGraph)
813
+ const buildUrl = useVersionedUrl ? urlInfo.data.versionedUrl : urlInfo.url
814
+ const buildUrlSpecifier = Object.keys(buildUrls).find(
815
+ (key) => buildUrls[key] === buildUrl,
816
+ )
817
+ urlInfo.data.buildUrl = buildUrl
818
+ urlInfo.data.buildUrlIsVersioned = useVersionedUrl
819
+ urlInfo.data.buildUrlSpecifier = buildUrlSpecifier
820
+ })
821
+
822
+ await resyncRessourceHints({
823
+ finalGraphKitchen,
824
+ finalGraph,
825
+ rawUrls,
826
+ buildUrls,
827
+ })
828
+ const cleanupActions = []
829
+ GRAPH.forEach(finalGraph, (urlInfo) => {
830
+ // nothing uses this url anymore
831
+ // - versioning update inline content
832
+ // - file converted for import assertion of js_classic conversion
833
+ if (
834
+ !urlInfo.data.isEntryPoint &&
835
+ urlInfo.type !== "sourcemap" &&
836
+ urlInfo.dependents.size === 0
837
+ ) {
838
+ cleanupActions.push(() => {
839
+ delete finalGraph.urlInfos[urlInfo.url]
840
+ })
672
841
  }
673
842
  })
843
+ cleanupActions.forEach((cleanupAction) => cleanupAction())
844
+ await injectServiceWorkerUrls({
845
+ finalGraphKitchen,
846
+ finalGraph,
847
+ lineBreakNormalization,
848
+ })
849
+
674
850
  logger.debug(
675
851
  `graph urls post-versioning:
676
852
  ${Object.keys(finalGraph.urlInfos).join("\n")}`,
677
853
  )
678
854
 
855
+ const buildManifest = {}
856
+ const buildFileContents = {}
857
+ const buildInlineContents = {}
858
+ GRAPH.forEach(finalGraph, (urlInfo) => {
859
+ if (urlInfo.external) {
860
+ return
861
+ }
862
+ if (urlInfo.url.startsWith("data:")) {
863
+ return
864
+ }
865
+ const buildRelativeUrl = urlToRelativeUrl(
866
+ urlInfo.data.buildUrl,
867
+ buildDirectoryUrl,
868
+ )
869
+ if (urlInfo.isInline) {
870
+ buildInlineContents[buildRelativeUrl] = urlInfo.content
871
+ } else {
872
+ buildFileContents[buildRelativeUrl] = urlInfo.content
873
+ }
874
+ const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
875
+ urlInfo.url,
876
+ buildDirectoryUrl,
877
+ )
878
+ buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
879
+ })
679
880
  if (writeOnFileSystem) {
680
881
  if (buildDirectoryClean) {
681
882
  await ensureEmptyDirectory(buildDirectoryUrl)
@@ -689,17 +890,23 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
689
890
  )
690
891
  }),
691
892
  )
893
+ if (versioning && assetManifest && Object.keys(buildManifest).length) {
894
+ await writeFile(
895
+ new URL(assetManifestFileRelativeUrl, buildDirectoryUrl),
896
+ JSON.stringify(buildManifest, null, " "),
897
+ )
898
+ }
692
899
  }
693
900
  logger.info(createUrlGraphSummary(finalGraph, { title: "build files" }))
694
901
  return {
695
902
  buildFileContents,
696
- buildInlineFileContents,
903
+ buildInlineContents,
697
904
  buildManifest,
698
905
  }
699
906
  }
700
907
 
701
- const injectVersionIntoBuildUrl = ({ buildUrl, version, versioning }) => {
702
- if (versioning === "search_param") {
908
+ const injectVersionIntoBuildUrl = ({ buildUrl, version, versioningMethod }) => {
909
+ if (versioningMethod === "search_param") {
703
910
  return injectQueryParams(buildUrl, {
704
911
  v: version,
705
912
  })
@@ -735,3 +942,16 @@ const assertEntryPoints = ({ entryPoints }) => {
735
942
  }
736
943
  })
737
944
  }
945
+
946
+ const canUseVersionedUrl = (urlInfo) => {
947
+ if (urlInfo.data.isEntryPoint) {
948
+ return false
949
+ }
950
+ if (urlInfo.type === "webmanifest") {
951
+ return false
952
+ }
953
+ if (urlInfo.subtype === "service_worker") {
954
+ return !urlInfo.data.isWebWorkerEntryPoint
955
+ }
956
+ return true
957
+ }