@jsenv/core 27.0.0-alpha.9 → 27.0.0-alpha.92

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 (277) hide show
  1. package/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +95 -0
  2. package/dist/babel_helpers/AwaitValue/AwaitValue.js +3 -0
  3. package/dist/babel_helpers/applyDecoratorDescriptor/applyDecoratorDescriptor.js +29 -0
  4. package/dist/babel_helpers/applyDecs/applyDecs.js +756 -0
  5. package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +9 -0
  6. package/dist/babel_helpers/arrayWithHoles/arrayWithHoles.js +4 -0
  7. package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +5 -0
  8. package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +8 -0
  9. package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +52 -0
  10. package/dist/babel_helpers/asyncIterator/asyncIterator.js +78 -0
  11. package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +39 -0
  12. package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +4 -0
  13. package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +24 -0
  14. package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +7 -0
  15. package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +14 -0
  16. package/dist/babel_helpers/classCallCheck/classCallCheck.js +5 -0
  17. package/dist/babel_helpers/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -0
  18. package/dist/babel_helpers/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -0
  19. package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +8 -0
  20. package/dist/babel_helpers/classNameTDZError/classNameTDZError.js +4 -0
  21. package/dist/babel_helpers/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +6 -0
  22. package/dist/babel_helpers/classPrivateFieldGet/classPrivateFieldGet.js +6 -0
  23. package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +7 -0
  24. package/dist/babel_helpers/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -0
  25. package/dist/babel_helpers/classPrivateFieldSet/classPrivateFieldSet.js +7 -0
  26. package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +7 -0
  27. package/dist/babel_helpers/classPrivateMethodSet/classPrivateMethodSet.js +3 -0
  28. package/dist/babel_helpers/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +8 -0
  29. package/dist/babel_helpers/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +9 -0
  30. package/dist/babel_helpers/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +5 -0
  31. package/dist/babel_helpers/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -0
  32. package/dist/babel_helpers/construct/construct.js +15 -0
  33. package/dist/babel_helpers/createClass/createClass.js +18 -0
  34. package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +63 -0
  35. package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +22 -0
  36. package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +50 -0
  37. package/dist/babel_helpers/createSuper/createSuper.js +22 -0
  38. package/dist/babel_helpers/decorate/decorate.js +622 -0
  39. package/dist/babel_helpers/defaults/defaults.js +14 -0
  40. package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +26 -0
  41. package/dist/babel_helpers/defineProperty/defineProperty.js +19 -0
  42. package/dist/babel_helpers/extends/extends.js +16 -0
  43. package/dist/babel_helpers/get/get.js +21 -0
  44. package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +2 -0
  45. package/dist/babel_helpers/identity/identity.js +3 -0
  46. package/dist/babel_helpers/inherits/inherits.js +21 -0
  47. package/dist/babel_helpers/inheritsLoose/inheritsLoose.js +6 -0
  48. package/dist/babel_helpers/initializerDefineProperty/initializerDefineProperty.js +10 -0
  49. package/dist/babel_helpers/initializerWarningHelper/initializerWarningHelper.js +3 -0
  50. package/dist/babel_helpers/instanceof/instanceof.js +7 -0
  51. package/dist/babel_helpers/interopRequireDefault/interopRequireDefault.js +5 -0
  52. package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +49 -0
  53. package/dist/babel_helpers/isNativeFunction/isNativeFunction.js +4 -0
  54. package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -0
  55. package/dist/babel_helpers/iterableToArray/iterableToArray.js +3 -0
  56. package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +38 -0
  57. package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +13 -0
  58. package/dist/babel_helpers/jsx/jsx.js +49 -0
  59. package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +10 -0
  60. package/dist/babel_helpers/newArrowCheck/newArrowCheck.js +5 -0
  61. package/dist/babel_helpers/nonIterableRest/nonIterableRest.js +3 -0
  62. package/dist/babel_helpers/nonIterableSpread/nonIterableSpread.js +3 -0
  63. package/dist/babel_helpers/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -0
  64. package/dist/babel_helpers/objectSpread/objectSpread.js +22 -0
  65. package/dist/babel_helpers/objectSpread2/objectSpread2.js +41 -0
  66. package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +20 -0
  67. package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +15 -0
  68. package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +10 -0
  69. package/dist/babel_helpers/readOnlyError/readOnlyError.js +4 -0
  70. package/dist/babel_helpers/set/set.js +51 -0
  71. package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +5 -0
  72. package/dist/babel_helpers/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -0
  73. package/dist/babel_helpers/slicedToArray/slicedToArray.js +5 -0
  74. package/dist/babel_helpers/slicedToArrayLoose/slicedToArrayLoose.js +7 -0
  75. package/dist/babel_helpers/superPropBase/superPropBase.js +10 -0
  76. package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +11 -0
  77. package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +8 -0
  78. package/dist/babel_helpers/tdz/tdz.js +4 -0
  79. package/dist/babel_helpers/temporalRef/temporalRef.js +5 -0
  80. package/dist/babel_helpers/temporalUndefined/temporalUndefined.js +3 -0
  81. package/dist/babel_helpers/toArray/toArray.js +5 -0
  82. package/dist/babel_helpers/toConsumableArray/toConsumableArray.js +5 -0
  83. package/dist/babel_helpers/toPrimitive/toPrimitive.js +14 -0
  84. package/dist/babel_helpers/toPropertyKey/toPropertyKey.js +5 -0
  85. package/dist/babel_helpers/typeof/typeof.js +7 -0
  86. package/dist/babel_helpers/unsupportedIterableToArray/unsupportedIterableToArray.js +10 -0
  87. package/dist/babel_helpers/wrapAsyncGenerator/wrapAsyncGenerator.js +7 -0
  88. package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +35 -0
  89. package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +67 -0
  90. package/dist/babel_helpers/writeOnlyError/writeOnlyError.js +4 -0
  91. package/dist/html/explorer.html +557 -0
  92. package/dist/js/controllable_file.mjs +227 -0
  93. package/dist/js/event_source_client.js +528 -0
  94. package/dist/js/global_this.js +32 -0
  95. package/dist/js/html_supervisor_installer.js +522 -0
  96. package/dist/js/html_supervisor_setup.js +82 -0
  97. package/dist/js/import_meta_hot.js +84 -0
  98. package/dist/js/inline_content.js +8 -0
  99. package/dist/js/new_stylesheet.js +409 -0
  100. package/dist/js/regenerator_runtime.js +721 -0
  101. package/dist/js/s.js +429 -0
  102. package/dist/js/uneval.js +804 -0
  103. package/dist/main.js +25163 -0
  104. package/dist/other/jsenv.png +0 -0
  105. package/dist/s.js +626 -0
  106. package/dist/s.js.map +205 -0
  107. package/package.json +61 -57
  108. package/readme.md +6 -14
  109. package/src/build/build.js +1040 -551
  110. package/src/build/build_urls_generator.js +65 -25
  111. package/src/build/graph_utils.js +31 -0
  112. package/src/build/inject_global_version_mappings.js +93 -0
  113. package/src/build/inject_service_worker_urls.js +79 -0
  114. package/src/build/resync_ressource_hints.js +114 -0
  115. package/src/build/start_build_server.js +217 -0
  116. package/src/build/version_generator.js +60 -0
  117. package/src/dev/plugins/explorer/client/explorer.html +1 -1
  118. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +9 -14
  119. package/src/dev/plugins/toolbar/client/util/fetching.js +1 -1
  120. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +6 -4
  121. package/src/dev/start_dev_server.js +173 -38
  122. package/src/execute/execute.js +35 -8
  123. package/src/execute/run.js +21 -57
  124. package/src/execute/runtimes/browsers/from_playwright.js +224 -153
  125. package/src/execute/runtimes/node/child_exec_options.js +1 -1
  126. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  127. package/src/execute/runtimes/node/kill_process_tree.js +2 -4
  128. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  129. package/src/execute/runtimes/node/node_process.js +288 -39
  130. package/src/helpers/command/command.js +73 -0
  131. package/src/{dev/plugins/autoreload/client/event_source_connection.js → helpers/event_source/event_source.js} +2 -0
  132. package/src/helpers/event_source/sse_service.js +53 -0
  133. package/src/helpers/worker_reload.js +57 -0
  134. package/src/main.js +27 -0
  135. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  136. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +16 -17
  137. package/src/omega/errors.js +63 -67
  138. package/src/omega/fetched_content_compliance.js +24 -0
  139. package/src/omega/file_url_converter.js +9 -51
  140. package/src/omega/kitchen.js +607 -466
  141. package/src/omega/omega_server.js +2 -3
  142. package/src/omega/server/file_service.js +88 -41
  143. package/src/omega/server/user_agent.js +5 -5
  144. package/src/omega/url_graph/{url_graph_sort.js → sort_by_dependencies.js} +3 -5
  145. package/src/omega/url_graph/url_graph_load.js +31 -23
  146. package/src/omega/url_graph/url_graph_report.js +94 -51
  147. package/src/omega/url_graph/url_info_transformations.js +54 -24
  148. package/src/omega/url_graph.js +88 -19
  149. package/src/omega/url_specifier_encoding.js +59 -0
  150. package/src/omega/web_workers.js +42 -0
  151. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  152. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +19 -12
  153. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +6 -3
  154. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  155. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  156. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  157. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  158. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  159. package/src/plugins/bundling/css/bundle_css.js +140 -0
  160. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  161. package/src/plugins/bundling/js_module/bundle_js_module.js +362 -0
  162. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  163. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +34 -0
  164. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +56 -43
  165. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +190 -0
  166. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  167. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  168. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +254 -0
  169. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +82 -0
  170. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  171. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  172. package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +239 -0
  173. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +16 -0
  174. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  175. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  176. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +15 -18
  177. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +100 -0
  178. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +35 -10
  179. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  180. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  181. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +56 -54
  182. package/src/plugins/inject_globals/inject_globals.js +57 -0
  183. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +24 -0
  184. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  185. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +22 -21
  186. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +159 -0
  187. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  188. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +8 -11
  189. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +294 -0
  190. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  191. package/src/plugins/minification/css/minify_css.js +9 -0
  192. package/src/plugins/minification/html/minify_html.js +13 -0
  193. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  194. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  195. package/src/plugins/minification/json/minify_json.js +8 -0
  196. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +162 -0
  197. package/src/plugins/node_runtime/jsenv_plugin_node_runtime.js +12 -0
  198. package/src/{omega → plugins}/plugin_controller.js +57 -12
  199. package/src/plugins/plugins.js +91 -0
  200. package/src/plugins/transpilation/as_js_classic/client/s.js +429 -0
  201. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  202. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  203. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +209 -0
  204. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +282 -0
  205. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +55 -0
  206. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +2 -3
  207. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  208. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +3 -4
  209. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +14 -17
  210. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  211. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +40 -33
  212. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +32 -9
  213. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  214. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +2 -3
  215. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  216. package/src/plugins/transpilation/babel/require_babel_plugin.js +8 -0
  217. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  218. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +184 -0
  219. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +80 -0
  220. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +46 -0
  221. package/src/plugins/url_analysis/css/css_urls.js +48 -0
  222. package/src/plugins/url_analysis/html/html_urls.js +257 -0
  223. package/src/plugins/url_analysis/js/js_urls.js +69 -0
  224. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +110 -0
  225. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +20 -0
  226. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +9 -5
  227. package/src/plugins/url_version/jsenv_plugin_url_version.js +28 -0
  228. package/src/require_from_jsenv.js +3 -0
  229. package/src/test/coverage/babel_plugin_instrument.js +82 -0
  230. package/src/test/coverage/coverage_reporter_html_directory.js +36 -0
  231. package/src/test/coverage/coverage_reporter_json_file.js +22 -0
  232. package/src/test/coverage/coverage_reporter_text_log.js +19 -0
  233. package/src/test/coverage/empty_coverage_factory.js +52 -0
  234. package/src/test/coverage/file_by_file_coverage.js +25 -0
  235. package/src/test/coverage/istanbul_coverage_composition.js +28 -0
  236. package/src/test/coverage/istanbul_coverage_map_from_coverage.js +16 -0
  237. package/src/test/coverage/list_files_not_covered.js +15 -0
  238. package/src/test/coverage/missing_coverage.js +41 -0
  239. package/src/test/coverage/report_to_coverage.js +196 -0
  240. package/src/test/coverage/v8_and_istanbul.js +37 -0
  241. package/src/test/coverage/v8_coverage_composition.js +24 -0
  242. package/src/test/coverage/v8_coverage_from_directory.js +87 -0
  243. package/src/test/coverage/v8_coverage_to_istanbul.js +99 -0
  244. package/src/test/execute_plan.js +87 -46
  245. package/src/test/execute_test_plan.js +40 -28
  246. package/src/test/execution_steps.js +2 -5
  247. package/src/test/logs_file_execution.js +56 -49
  248. package/main.js +0 -19
  249. package/src/build/inject_version_mappings.js +0 -62
  250. package/src/build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js +0 -227
  251. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  252. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  253. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  254. package/src/execute/runtimes/node/controlled_process.js +0 -316
  255. package/src/omega/core_plugins/babel/new_stylesheet/client/.eslintrc.cjs +0 -24
  256. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  257. package/src/omega/core_plugins/filesystem_magic/jsenv_plugin_filesystem_magic.js +0 -58
  258. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  259. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  260. package/src/omega/core_plugins/html_supervisor/jsenv_plugin_html_supervisor.js +0 -233
  261. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  262. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  263. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  264. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  265. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  266. package/src/omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js +0 -142
  267. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  268. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  269. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  270. package/src/omega/core_plugins/url_version/jsenv_plugin_url_version.js +0 -50
  271. package/src/omega/core_plugins.js +0 -39
  272. package/src/omega/runtime_support/default_runtime_support.js +0 -13
  273. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  274. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  275. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  276. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  277. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -7,151 +7,249 @@
7
7
  */
8
8
 
9
9
  import {
10
- assertAndNormalizeDirectoryUrl,
11
- ensureEmptyDirectory,
10
+ injectQueryParams,
11
+ setUrlFilename,
12
+ asUrlUntilPathname,
13
+ normalizeUrl,
14
+ asUrlWithoutSearch,
15
+ ensurePathnameTrailingSlash,
12
16
  urlIsInsideOf,
13
17
  urlToBasename,
14
18
  urlToExtension,
15
19
  urlToRelativeUrl,
20
+ } from "@jsenv/urls"
21
+ import {
22
+ assertAndNormalizeDirectoryUrl,
23
+ ensureEmptyDirectory,
16
24
  writeFile,
25
+ registerDirectoryLifecycle,
17
26
  } from "@jsenv/filesystem"
18
- import { createLogger } from "@jsenv/logger"
19
-
20
- import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
21
- import {
22
- injectQueryParams,
23
- setUrlFilename,
24
- } from "@jsenv/utils/urls/url_utils.js"
25
- import { createUrlVersionGenerator } from "@jsenv/utils/urls/url_version_generator.js"
26
- import { generateSourcemapUrl } from "@jsenv/utils/sourcemap/sourcemap_utils.js"
27
- import {
28
- parseHtmlString,
29
- stringifyHtmlAst,
30
- } from "@jsenv/utils/html_ast/html_ast.js"
27
+ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
28
+ import { createLogger, loggerToLevels, createTaskLog } from "@jsenv/log"
29
+ import { generateSourcemapFileUrl } from "@jsenv/sourcemap"
30
+ import { parseHtmlString, stringifyHtmlAst } from "@jsenv/ast"
31
31
 
32
- import { defaultRuntimeSupport } from "../omega/runtime_support/default_runtime_support.js"
33
- import { jsenvPluginInline } from "../omega/core_plugins/inline/jsenv_plugin_inline.js"
32
+ import { sortByDependencies } from "../omega/url_graph/sort_by_dependencies.js"
34
33
  import { createUrlGraph } from "../omega/url_graph.js"
35
- import { getCorePlugins } from "../omega/core_plugins.js"
34
+ import { jsenvPluginUrlAnalysis } from "../plugins/url_analysis/jsenv_plugin_url_analysis.js"
35
+ import { jsenvPluginInline } from "../plugins/inline/jsenv_plugin_inline.js"
36
+ import { jsenvPluginAsJsClassic } from "../plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js"
37
+ import { getCorePlugins } from "../plugins/plugins.js"
36
38
  import { createKitchen } from "../omega/kitchen.js"
37
39
  import { loadUrlGraph } from "../omega/url_graph/url_graph_load.js"
38
40
  import { createUrlGraphSummary } from "../omega/url_graph/url_graph_report.js"
39
- 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 { createVersionGenerator } from "./version_generator.js"
47
+ import { injectServiceWorkerUrls } from "./inject_service_worker_urls.js"
48
+ import { resyncRessourceHints } from "./resync_ressource_hints.js"
46
49
 
50
+ /**
51
+ * Generate an optimized version of source files into a directory
52
+ * @param {Object} buildParameters
53
+ * @param {string|url} buildParameters.rootDirectoryUrl
54
+ * Directory containing source files
55
+ * @param {string|url} buildParameters.buildDirectoryUrl
56
+ * Directory where optimized files will be written
57
+ * @param {object} buildParameters.entryPoints
58
+ * Describe entry point paths and control their names in the build directory
59
+ * @param {object} buildParameters.runtimeCompat
60
+ * Code generated will be compatible with these runtimes
61
+ * @param {string="/"} buildParameters.baseUrl
62
+ * All urls in build file contents are prefixed with this url
63
+ * @param {boolean|object} [buildParameters.minification=true]
64
+ * Minify build file contents
65
+ * @param {boolean} [buildParameters.versioning=true]
66
+ * Controls if url in build file contents are versioned
67
+ * @param {('search_param'|'filename')} [buildParameters.versioningMethod="search_param"]
68
+ * Controls how url are versioned
69
+ * @param {boolean|string} [buildParameters.sourcemaps=false]
70
+ * Generate sourcemaps in the build directory
71
+ * @return {Object} buildReturnValue
72
+ * @return {Object} buildReturnValue.buildFileContents
73
+ * Contains all build file paths relative to the build directory and their content
74
+ * @return {Object} buildReturnValue.buildInlineContents
75
+ * Contains content that is inline into build files
76
+ * @return {Object} buildReturnValue.buildManifest
77
+ * Map build file paths without versioning to versioned file paths
78
+ */
47
79
  export const build = async ({
48
80
  signal = new AbortController().signal,
81
+ handleSIGINT = true,
49
82
  logLevel = "info",
50
83
  rootDirectoryUrl,
51
84
  buildDirectoryUrl,
52
85
  entryPoints = {},
53
- // for now it's here but I think preview will become an other script
54
- // that will just pass different options to build project
55
- // and this function will be agnostic about "preview" concept
56
- isPreview = false,
86
+ baseUrl = "/",
87
+
88
+ // default runtimeCompat corresponds to dynamic import
89
+ // (meaning we can keep <script type="module">)
90
+ runtimeCompat = {
91
+ // android: "8",
92
+ chrome: "63",
93
+ edge: "79",
94
+ firefox: "67",
95
+ ios: "11.3",
96
+ opera: "50",
97
+ safari: "11.3",
98
+ samsung: "8.2",
99
+ },
57
100
  plugins = [],
58
- htmlSupervisor,
101
+ sourcemaps = false,
102
+ sourcemapsSourcesContent,
103
+ urlAnalysis = {},
59
104
  nodeEsmResolution,
60
105
  fileSystemMagicResolution,
61
- babel,
62
- runtimeSupport = defaultRuntimeSupport,
63
- sourcemaps = isPreview ? "file" : false,
64
-
106
+ directoryReferenceAllowed,
107
+ transpilation = {},
65
108
  bundling = true,
66
- minify = true,
67
- versioning = "filename", // "filename", "search_param", "none"
109
+ minification = true,
110
+ versioning = true,
111
+ versioningMethod = "search_param", // "filename", "search_param"
68
112
  lineBreakNormalization = process.platform === "win32",
69
113
 
70
- writeOnFileSystem = true,
114
+ clientFiles = {
115
+ "./src/": true,
116
+ },
117
+ cooldownBetweenFileEvents,
118
+ watch = false,
119
+
71
120
  buildDirectoryClean = true,
72
- baseUrl = "/",
121
+ writeOnFileSystem = true,
122
+ writeGeneratedFiles = false,
73
123
  assetManifest = true,
74
124
  assetManifestFileRelativeUrl = "asset-manifest.json",
75
125
  }) => {
76
- const logger = createLogger({ logLevel })
126
+ const operation = Abort.startOperation()
127
+ operation.addAbortSignal(signal)
128
+ if (handleSIGINT) {
129
+ operation.addAbortSource((abort) => {
130
+ return raceProcessTeardownEvents(
131
+ {
132
+ SIGINT: true,
133
+ },
134
+ abort,
135
+ )
136
+ })
137
+ }
138
+
77
139
  rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
78
140
  buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
79
141
  assertEntryPoints({ entryPoints })
80
- if (!["filename", "search_param", "none"].includes(versioning)) {
142
+ if (!["filename", "search_param"].includes(versioningMethod)) {
81
143
  throw new Error(
82
- `Unexpected "versioning": must be "filename", "search_param" or "none"; got ${versioning}`,
144
+ `Unexpected "versioningMethod": must be "filename", "search_param"; got ${versioning}`,
83
145
  )
84
146
  }
85
147
 
86
- const entryPointKeys = Object.keys(entryPoints)
87
- if (entryPointKeys.length === 1) {
88
- logger.info(`
148
+ const runBuild = async ({ signal, logLevel }) => {
149
+ const logger = createLogger({ logLevel })
150
+ const buildOperation = Abort.startOperation()
151
+ const infoLogsAreDisabled = !loggerToLevels(logger).info
152
+ buildOperation.addAbortSignal(signal)
153
+ const entryPointKeys = Object.keys(entryPoints)
154
+ if (entryPointKeys.length === 1) {
155
+ logger.info(`
89
156
  build "${entryPointKeys[0]}"`)
90
- } else {
91
- logger.info(`
157
+ } else {
158
+ logger.info(`
92
159
  build ${entryPointKeys.length} entry points`)
93
- }
94
- const rawGraph = createUrlGraph()
95
- const prebuildTask = createTaskLog(logger, "prebuild")
96
- let urlCount = 0
97
- const rawGraphKitchen = createKitchen({
98
- signal,
99
- logger,
100
- rootDirectoryUrl,
101
- urlGraph: rawGraph,
102
- plugins: [
103
- ...plugins,
104
- {
105
- name: "jsenv:build_log",
106
- appliesDuring: { build: true },
107
- cooked: () => {
108
- urlCount++
109
- prebuildTask.setRightText(urlCount)
110
- },
111
- },
112
- ...getCorePlugins({
113
- htmlSupervisor,
114
- nodeEsmResolution,
115
- fileSystemMagicResolution,
116
- babel,
117
- }),
118
- jsenvPluginBundleJsModule(),
119
- ...(minify ? [jsenvPluginMinifyJs(), jsenvPluginMinifyHtml()] : []),
120
- ],
121
- scenario: "build",
122
- sourcemaps,
123
- })
124
- const entryUrls = []
125
- try {
126
- await loadUrlGraph({
160
+ }
161
+ const useExplicitJsClassicConversion = entryPointKeys.some((key) =>
162
+ entryPoints[key].includes("?as_js_classic"),
163
+ )
164
+
165
+ const rawGraph = createUrlGraph()
166
+ const prebuildTask = createTaskLog("prebuild", {
167
+ disabled: infoLogsAreDisabled,
168
+ })
169
+ const prebuildRedirections = new Map()
170
+ const rawGraphKitchen = createKitchen({
171
+ signal,
172
+ logger,
173
+ rootDirectoryUrl,
127
174
  urlGraph: rawGraph,
128
- kitchen: rawGraphKitchen,
129
- outDirectoryUrl: new URL(`.jsenv/build/`, rootDirectoryUrl),
130
- runtimeSupport,
131
- startLoading: (cookEntryFile) => {
132
- Object.keys(entryPoints).forEach((key) => {
133
- const [, entryUrlInfo] = cookEntryFile({
134
- trace: `"${key}" in entryPoints parameter`,
135
- type: "entry_point",
136
- specifier: key,
137
- })
138
- entryUrls.push(entryUrlInfo.url)
139
- })
140
- },
175
+ scenario: "build",
176
+ sourcemaps,
177
+ sourcemapsSourcesContent,
178
+ runtimeCompat,
179
+ writeGeneratedFiles,
180
+ plugins: [
181
+ ...plugins,
182
+ {
183
+ appliesDuring: "build",
184
+ fetchUrlContent: (urlInfo, context) => {
185
+ if (context.reference.original) {
186
+ prebuildRedirections.set(
187
+ context.reference.original.url,
188
+ context.reference.url,
189
+ )
190
+ }
191
+ },
192
+ formatUrl: (reference) => {
193
+ if (!reference.shouldHandle) {
194
+ return `ignore:${reference.specifier}`
195
+ }
196
+ return null
197
+ },
198
+ },
199
+ ...getCorePlugins({
200
+ rootDirectoryUrl,
201
+ urlGraph: rawGraph,
202
+ scenario: "build",
203
+ runtimeCompat,
204
+
205
+ urlAnalysis,
206
+ nodeEsmResolution,
207
+ fileSystemMagicResolution,
208
+ directoryReferenceAllowed,
209
+ transpilation: {
210
+ ...transpilation,
211
+ babelHelpersAsImport: !useExplicitJsClassicConversion,
212
+ jsModuleAsJsClassic: false,
213
+ },
214
+ minification,
215
+ bundling,
216
+ }),
217
+ ],
141
218
  })
142
- } catch (e) {
143
- prebuildTask.fail()
144
- throw e
145
- }
146
- // here we can perform many checks such as ensuring ressource hints are used
147
- prebuildTask.done()
148
- logger.debug(
149
- `raw graph urls:
150
- ${Object.keys(rawGraph.urlInfos).join("\n")}`,
151
- )
219
+ const entryUrls = []
220
+ try {
221
+ await loadUrlGraph({
222
+ operation: buildOperation,
223
+ urlGraph: rawGraph,
224
+ kitchen: rawGraphKitchen,
225
+ writeGeneratedFiles,
226
+ outDirectoryUrl: new URL(`.jsenv/build/`, rootDirectoryUrl),
227
+ startLoading: (cookEntryFile) => {
228
+ Object.keys(entryPoints).forEach((key) => {
229
+ const [, entryUrlInfo] = cookEntryFile({
230
+ trace: `"${key}" in entryPoints parameter`,
231
+ type: "entry_point",
232
+ specifier: key,
233
+ })
234
+ entryUrls.push(entryUrlInfo.url)
235
+ entryUrlInfo.filename = entryPoints[key]
236
+ // entryUrlInfo.data.entryPointKey = key
237
+ })
238
+ },
239
+ })
240
+ } catch (e) {
241
+ prebuildTask.fail()
242
+ throw e
243
+ }
244
+ prebuildTask.done()
152
245
 
153
- const bundleUrlInfos = {}
154
- if (bundling) {
246
+ const buildUrlsGenerator = createBuilUrlsGenerator({
247
+ buildDirectoryUrl,
248
+ })
249
+ const rawUrls = {}
250
+ const bundleRedirections = {}
251
+ const buildUrls = {}
252
+ const bundleUrlInfos = {}
155
253
  const bundlers = {}
156
254
  rawGraphKitchen.pluginController.plugins.forEach((plugin) => {
157
255
  const bundle = plugin.bundle
@@ -164,6 +262,10 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
164
262
  )
165
263
  }
166
264
  Object.keys(bundle).forEach((type) => {
265
+ const bundleFunction = bundle[type]
266
+ if (!bundleFunction) {
267
+ return
268
+ }
167
269
  const bundlerForThatType = bundlers[type]
168
270
  if (bundlerForThatType) {
169
271
  // first plugin to define a bundle hook wins
@@ -183,8 +285,7 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
183
285
  return
184
286
  }
185
287
  }
186
- Object.keys(rawGraph.urlInfos).forEach((rawUrl) => {
187
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
288
+ GRAPH.forEach(rawGraph, (rawUrlInfo) => {
188
289
  if (rawUrlInfo.data.isEntryPoint) {
189
290
  addToBundlerIfAny(rawUrlInfo)
190
291
  if (rawUrlInfo.type === "html") {
@@ -195,7 +296,10 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
195
296
  // bundle inline script type module deps
196
297
  dependencyUrlInfo.references.forEach((inlineScriptRef) => {
197
298
  if (inlineScriptRef.type === "js_import_export") {
198
- addToBundlerIfAny(rawGraph.getUrlInfo(inlineScriptRef.url))
299
+ const inlineUrlInfo = rawGraph.getUrlInfo(
300
+ inlineScriptRef.url,
301
+ )
302
+ addToBundlerIfAny(inlineUrlInfo)
199
303
  }
200
304
  })
201
305
  }
@@ -204,6 +308,21 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
204
308
  }
205
309
  addToBundlerIfAny(dependencyUrlInfo)
206
310
  })
311
+ rawUrlInfo.references.forEach((reference) => {
312
+ if (
313
+ reference.isRessourceHint &&
314
+ reference.expectedType === "js_module"
315
+ ) {
316
+ const referencedUrlInfo = rawGraph.getUrlInfo(reference.url)
317
+ if (
318
+ referencedUrlInfo &&
319
+ // something else than the ressource hint is using this url
320
+ referencedUrlInfo.dependents.size > 0
321
+ ) {
322
+ addToBundlerIfAny(referencedUrlInfo)
323
+ }
324
+ }
325
+ })
207
326
  return
208
327
  }
209
328
  }
@@ -212,13 +331,14 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
212
331
  // For instance we will bundle service worker/workers detected like this
213
332
  if (rawUrlInfo.type === "js_module") {
214
333
  rawUrlInfo.references.forEach((reference) => {
215
- if (reference.type === "js_import_meta_url_pattern") {
334
+ if (reference.type === "js_url_specifier") {
216
335
  const urlInfo = rawGraph.getUrlInfo(reference.url)
217
336
  addToBundlerIfAny(urlInfo)
218
337
  }
219
338
  })
220
339
  }
221
340
  })
341
+ const bundleInternalRedirections = {}
222
342
  await Object.keys(bundlers).reduce(async (previous, type) => {
223
343
  await previous
224
344
  const bundler = bundlers[type]
@@ -226,7 +346,9 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
226
346
  if (urlInfosToBundle.length === 0) {
227
347
  return
228
348
  }
229
- const bundleTask = createTaskLog(logger, `bundle "${type}"`)
349
+ const bundleTask = createTaskLog(`bundle "${type}"`, {
350
+ disabled: infoLogsAreDisabled,
351
+ })
230
352
  try {
231
353
  const bundlerGeneratedUrlInfos =
232
354
  await rawGraphKitchen.pluginController.callAsyncHook(
@@ -237,27 +359,46 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
237
359
  },
238
360
  urlInfosToBundle,
239
361
  {
240
- signal,
241
- logger,
242
- rootDirectoryUrl,
362
+ ...rawGraphKitchen.kitchenContext,
243
363
  buildDirectoryUrl,
244
- urlGraph: rawGraph,
245
- runtimeSupport,
246
- sourcemaps,
247
364
  },
248
365
  )
249
366
  Object.keys(bundlerGeneratedUrlInfos).forEach((url) => {
250
- const bundleUrlInfo = bundlerGeneratedUrlInfos[url]
251
367
  const rawUrlInfo = rawGraph.getUrlInfo(url)
252
- bundleUrlInfos[url] = {
368
+ const bundlerGeneratedUrlInfo = bundlerGeneratedUrlInfos[url]
369
+ const bundleUrlInfo = {
253
370
  type,
254
- ...bundleUrlInfo,
371
+ subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
372
+ filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
373
+ originalUrl: rawUrlInfo ? rawUrlInfo.originalUrl : undefined,
374
+ originalContent: rawUrlInfo
375
+ ? rawUrlInfo.originalContent
376
+ : undefined,
377
+ ...bundlerGeneratedUrlInfo,
255
378
  data: {
256
379
  ...(rawUrlInfo ? rawUrlInfo.data : {}),
257
- ...bundleUrlInfo.data,
380
+ ...bundlerGeneratedUrlInfo.data,
258
381
  fromBundle: true,
259
382
  },
260
383
  }
384
+ const buildUrl = buildUrlsGenerator.generate(url, {
385
+ urlInfo: bundleUrlInfo,
386
+ })
387
+ bundleRedirections[url] = buildUrl
388
+ rawUrls[buildUrl] = url
389
+ bundleUrlInfos[buildUrl] = bundleUrlInfo
390
+ if (buildUrl.includes("?")) {
391
+ bundleUrlInfos[asUrlWithoutSearch(buildUrl)] = bundleUrlInfo
392
+ }
393
+ if (bundlerGeneratedUrlInfo.data.bundleRelativeUrl) {
394
+ const urlForBundler = new URL(
395
+ bundlerGeneratedUrlInfo.data.bundleRelativeUrl,
396
+ buildDirectoryUrl,
397
+ ).href
398
+ if (urlForBundler !== buildUrl) {
399
+ bundleInternalRedirections[urlForBundler] = buildUrl
400
+ }
401
+ }
261
402
  })
262
403
  } catch (e) {
263
404
  bundleTask.fail()
@@ -265,482 +406,817 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
265
406
  }
266
407
  bundleTask.done()
267
408
  }, Promise.resolve())
268
- }
269
409
 
270
- const buildUrlsGenerator = createBuilUrlsGenerator({
271
- buildDirectoryUrl,
272
- })
273
- const rawUrls = {}
274
- const buildUrls = {}
275
- const finalGraph = createUrlGraph()
276
- const optimizeHooks = rawGraphKitchen.pluginController.addHook("optimize")
277
- const finalGraphKitchen = createKitchen({
278
- logger,
279
- rootDirectoryUrl,
280
- urlGraph: finalGraph,
281
- // Inline content, such as <script> inside html, is transformed during the previous phase.
282
- // If we read the inline content it would be considered as the original content.
283
- // - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
284
- // as the original content.
285
- // - But it would not work when sourcemap are not generated
286
- // - would be a bit slower
287
- // - So instead of reading the inline content directly, we search into raw graph
288
- // to get "originalContent" and "sourcemap"
289
- loadInlineUrlInfos: (finalUrlInfo) => {
290
- const rawUrl = finalUrlInfo.data.rawUrl
291
- const bundleUrlInfo = bundleUrlInfos[rawUrl]
292
- const urlInfo = bundleUrlInfo || finalUrlInfo
293
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
294
- return {
295
- originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
296
- sourcemap: bundleUrlInfo
297
- ? bundleUrlInfo.sourcemap
298
- : rawUrlInfo
299
- ? rawUrlInfo.sourcemap
300
- : undefined,
301
- contentType: urlInfo.contentType,
302
- content: urlInfo.content,
303
- }
304
- },
305
- plugins: [
306
- jsenvPluginInline(),
307
- {
308
- name: "jsenv:postbuild",
309
- appliesDuring: { build: true },
310
- resolve: (reference) => {
311
- if (reference.specifier[0] === "/") {
312
- const url = new URL(reference.specifier.slice(1), rootDirectoryUrl)
313
- .href
314
- return url
315
- }
316
- const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
317
- if (parentUrlInfo && parentUrlInfo.data.fromBundle) {
318
- // code generated by rollup contains specifier relative
319
- // to the generated file.
320
- // This file does not exists yet we must resolve against the raw url, not the build url
321
- const parentRawUrl = parentUrlInfo.data.rawUrl
322
- const rawUrl = new URL(reference.specifier, parentRawUrl).href
323
- return rawUrl
324
- }
325
- return new URL(reference.specifier, reference.parentUrl).href
326
- },
327
- normalize: (reference) => {
328
- if (!reference.url.startsWith("file:")) {
329
- return null
330
- }
331
- // already a build url
332
- const rawUrl = rawUrls[reference.url]
333
- if (rawUrl) {
334
- reference.data.rawUrl = rawUrl
335
- return reference.url
336
- }
337
- const bundleUrlInfo = bundleUrlInfos[reference.url]
338
- // from rollup or postcss
339
- if (bundleUrlInfo) {
340
- const buildUrl = buildUrlsGenerator.generate(
341
- reference.url,
342
- bundleUrlInfo,
343
- )
344
- reference.data.rawUrl = reference.url
345
- rawUrls[buildUrl] = reference.url
346
- return buildUrl
347
- }
348
- const rawUrlInfo = rawGraph.getUrlInfo(reference.url)
349
- // files from root directory but not given to rollup nor postcss
350
- if (rawUrlInfo) {
351
- const buildUrl = buildUrlsGenerator.generate(
352
- reference.url,
353
- rawUrlInfo,
354
- )
355
- reference.data.rawUrl = reference.url
356
- rawUrls[buildUrl] = reference.url
357
- return buildUrl
358
- }
359
- if (reference.isInline) {
360
- const rawUrl = Object.keys(rawGraph.urlInfos).find((url) => {
361
- const rawUrlInfo = rawGraph.urlInfos[url]
362
- if (!rawUrlInfo.isInline) {
363
- return false
410
+ const urlAnalysisPlugin = jsenvPluginUrlAnalysis({
411
+ rootDirectoryUrl,
412
+ ...urlAnalysis,
413
+ })
414
+ const postBuildRedirections = {}
415
+ const finalGraph = createUrlGraph()
416
+ const optimizeUrlContentHooks =
417
+ rawGraphKitchen.pluginController.addHook("optimizeUrlContent")
418
+ const finalGraphKitchen = createKitchen({
419
+ logger,
420
+ rootDirectoryUrl,
421
+ urlGraph: finalGraph,
422
+ scenario: "build",
423
+ sourcemaps,
424
+ sourcemapsSourcesContent,
425
+ sourcemapsRelativeSources: !versioning,
426
+ runtimeCompat,
427
+ writeGeneratedFiles,
428
+ plugins: [
429
+ urlAnalysisPlugin,
430
+ jsenvPluginAsJsClassic({ systemJsInjection: true }),
431
+ jsenvPluginInline({ fetchInlineUrls: false }),
432
+ {
433
+ name: "jsenv:postbuild",
434
+ appliesDuring: "build",
435
+ resolveUrl: (reference) => {
436
+ const performInternalRedirections = (url) => {
437
+ const prebuildRedirection = prebuildRedirections.get(url)
438
+ if (prebuildRedirection) {
439
+ logger.debug(
440
+ `\nprebuild redirection\n${url} ->\n${prebuildRedirection}\n`,
441
+ )
442
+ url = prebuildRedirection
364
443
  }
365
- if (rawUrlInfo.content === reference.content) {
366
- return true
444
+ const bundleRedirection = bundleRedirections[url]
445
+ if (bundleRedirection) {
446
+ logger.debug(
447
+ `\nbundler redirection\n${url} ->\n${bundleRedirection}\n`,
448
+ )
449
+ url = bundleRedirection
367
450
  }
368
- return false
369
- })
370
- if (!rawUrl) {
371
- throw new Error(`cannot find raw url`)
451
+ const bundleInternalRedirection = bundleInternalRedirections[url]
452
+ if (bundleInternalRedirection) {
453
+ logger.debug(
454
+ `\nbundler internal redirection\n${url} ->\n${bundleInternalRedirection}\n`,
455
+ )
456
+ url = bundleInternalRedirection
457
+ }
458
+ return url
372
459
  }
373
- const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
374
- const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
375
- const buildUrl = buildUrlsGenerator.generate(
376
- reference.url,
377
- rawUrlInfo,
378
- parentUrlInfo,
379
- )
380
- rawUrls[buildUrl] = reference.url
381
- reference.data.rawUrl = rawUrl
382
- return buildUrl
383
- }
384
- if (reference.type === "sourcemap_comment") {
385
- // inherit parent build url
386
- return generateSourcemapUrl(reference.parentUrl)
387
- }
388
- // files generated during the final graph (sourcemaps)
389
- // const finalUrlInfo = finalGraph.getUrlInfo(url)
390
- const buildUrl = buildUrlsGenerator.generate(reference.url, {
391
- data: {},
392
- type: "asset",
393
- })
394
- return buildUrl
395
- },
396
- formatReferencedUrl: (reference) => {
397
- if (!reference.url.startsWith("file:")) {
398
- return null
399
- }
400
- if (!urlIsInsideOf(reference.url, buildDirectoryUrl)) {
401
- throw new Error(
402
- `urls should be inside build directory at this stage, found "${reference.url}"`,
403
- )
404
- }
405
- // if a file is in the same directory we could prefer the relative notation
406
- // but to keep things simple let's keep the notation relative to baseUrl for now
407
- const specifier = `${baseUrl}${urlToRelativeUrl(
408
- reference.url,
409
- buildDirectoryUrl,
410
- )}`
411
- buildUrls[specifier] = reference.url
412
- return specifier
413
- },
414
- load: (finalUrlInfo) => {
415
- const rawUrl = finalUrlInfo.data.rawUrl
416
- const bundleUrlInfo = bundleUrlInfos[rawUrl]
417
- const urlInfo = bundleUrlInfo || rawGraph.getUrlInfo(rawUrl)
418
- return {
419
- data: bundleUrlInfo ? bundleUrlInfo.data : undefined,
420
- originalContent: urlInfo.originalContent,
421
- contentType: urlInfo.contentType,
422
- content: urlInfo.content,
423
- sourcemap: urlInfo.sourcemap,
424
- }
425
- },
426
- transform: {
427
- html: (urlInfo) => {
428
- const htmlAst = parseHtmlString(urlInfo.content, {
429
- storeOriginalPositions: false,
430
- })
431
- return {
432
- content: stringifyHtmlAst(htmlAst, {
433
- removeOriginalPositionAttributes: true,
434
- }),
460
+
461
+ if (reference.type === "filesystem") {
462
+ const parentRawUrl = rawUrls[reference.parentUrl]
463
+ const baseUrl = ensurePathnameTrailingSlash(parentRawUrl)
464
+ return performInternalRedirections(
465
+ new URL(reference.specifier, baseUrl).href,
466
+ )
435
467
  }
468
+ if (reference.specifier[0] === "/") {
469
+ return performInternalRedirections(
470
+ new URL(reference.specifier.slice(1), buildDirectoryUrl).href,
471
+ )
472
+ }
473
+ return performInternalRedirections(
474
+ new URL(
475
+ reference.specifier,
476
+ reference.baseUrl || reference.parentUrl,
477
+ ).href,
478
+ )
436
479
  },
437
- },
438
- },
439
- {
440
- name: "jsenv:optimize",
441
- appliesDuring: { build: true },
442
- transform: async (urlInfo, context) => {
443
- if (optimizeHooks.length) {
444
- await rawGraphKitchen.pluginController.callAsyncHooks(
445
- "optimize",
446
- urlInfo,
447
- context,
448
- async (optimizeReturnValue) => {
449
- await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
450
- urlInfo,
451
- optimizeReturnValue,
480
+ // redirecting urls into the build directory
481
+ redirectUrl: (reference) => {
482
+ if (!reference.url.startsWith("file:")) {
483
+ return null
484
+ }
485
+ // already a build url
486
+ const rawUrl = rawUrls[reference.url]
487
+ if (rawUrl) {
488
+ return reference.url
489
+ }
490
+ // from "js_module_as_js_classic":
491
+ // - injecting "?as_js_classic" for the first time
492
+ // - injecting "?as_js_classic" because the parentUrl has it
493
+ if (reference.original) {
494
+ const referenceOriginalUrl = reference.original.url
495
+ let originalBuildUrl
496
+ if (urlIsInsideOf(referenceOriginalUrl, buildDirectoryUrl)) {
497
+ originalBuildUrl = referenceOriginalUrl
498
+ } else {
499
+ originalBuildUrl = Object.keys(rawUrls).find(
500
+ (key) => rawUrls[key] === referenceOriginalUrl,
452
501
  )
453
- },
454
- )
455
- }
456
- },
457
- },
458
- ],
459
- scenario: "build",
460
- sourcemaps,
461
- })
462
- const buildTask = createTaskLog(logger, "build")
463
- const postBuildEntryUrls = []
464
- try {
465
- await loadUrlGraph({
466
- urlGraph: finalGraph,
467
- kitchen: finalGraphKitchen,
468
- outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
469
- runtimeSupport,
470
- startLoading: (cookEntryFile) => {
471
- entryUrls.forEach((entryUrl) => {
472
- const [, postBuildEntryUrlInfo] = cookEntryFile({
473
- trace: `entryPoint`,
474
- type: "entry_point",
475
- specifier: entryUrl,
476
- })
477
- postBuildEntryUrls.push(postBuildEntryUrlInfo.url)
478
- })
479
- },
480
- })
481
- } catch (e) {
482
- buildTask.fail()
483
- throw e
484
- }
485
- buildTask.done()
486
-
487
- logger.debug(
488
- `graph urls pre-versioning:
489
- ${Object.keys(finalGraph.urlInfos).join("\n")}`,
490
- )
491
- if (versioning !== "none") {
492
- const versioningTask = createTaskLog(logger, "inject version in urls")
493
- try {
494
- const urlsSorted = sortUrlGraphByDependencies(finalGraph)
495
- urlsSorted.forEach((url) => {
496
- if (url.startsWith("data:")) {
497
- return
498
- }
499
- const urlInfo = finalGraph.getUrlInfo(url)
500
- if (urlInfo.type === "sourcemap") {
501
- return
502
- }
503
- if (urlInfo.isInline) {
504
- return
505
- }
506
- const urlVersionGenerator = createUrlVersionGenerator()
507
- urlVersionGenerator.augmentWithContent({
508
- content: urlInfo.content,
509
- contentType: urlInfo.contentType,
510
- lineBreakNormalization,
511
- })
512
- urlInfo.dependencies.forEach((dependencyUrl) => {
513
- const dependencyUrlInfo = finalGraph.getUrlInfo(dependencyUrl)
514
- if (dependencyUrlInfo.isInline) {
515
- // this content is part of the file, no need to take into account twice
516
- return
517
- }
518
- if (dependencyUrlInfo.data.version) {
519
- urlVersionGenerator.augmentWithDependencyVersion(
520
- dependencyUrlInfo.data.version,
521
- )
522
- } else {
523
- // because all dependencies are know, if the dependency has no version
524
- // it means there is a circular dependency between this file
525
- // and it's dependency
526
- // in that case we'll use the dependency content
527
- urlVersionGenerator.augmentWithContent({
528
- content: dependencyUrlInfo.content,
529
- contentType: dependencyUrlInfo.contentType,
530
- lineBreakNormalization,
531
- })
532
- }
533
- })
534
- urlInfo.data.version = urlVersionGenerator.generate()
535
- urlInfo.data.versionedUrl = injectVersionIntoBuildUrl({
536
- buildUrl: urlInfo.url,
537
- version: urlInfo.data.version,
538
- versioning,
539
- })
540
- })
541
- const versionMappings = {}
542
- const usedVersionMappings = []
543
- const versioningKitchen = createKitchen({
544
- logger,
545
- rootDirectoryUrl: buildDirectoryUrl,
546
- urlGraph: finalGraph,
547
- loadInlineUrlInfos: (versionedUrlInfo) => {
548
- const rawUrlInfo = rawGraph.getUrlInfo(versionedUrlInfo.data.rawUrl)
549
- const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
550
- return {
551
- originalContent: rawUrlInfo
552
- ? rawUrlInfo.originalContent
553
- : undefined,
554
- sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
555
- contentType: versionedUrlInfo.contentType,
556
- content: versionedUrlInfo.content,
557
- }
558
- },
559
- plugins: [
560
- jsenvPluginInline({
561
- allowEscapeForVersioning: true,
562
- }),
563
- {
564
- name: "jsenv:versioning",
565
- appliesDuring: { build: true },
566
- resolve: (reference) => {
567
- const buildUrl = buildUrls[reference.specifier]
568
- if (buildUrl) {
569
- return buildUrl
570
502
  }
571
- const url = new URL(reference.specifier, reference.parentUrl).href
572
- return url
573
- },
574
- formatReferencedUrl: (reference) => {
575
- if (reference.isInline) {
576
- return null
503
+ let rawUrl
504
+ if (urlIsInsideOf(reference.url, buildDirectoryUrl)) {
505
+ const originalBuildUrl =
506
+ postBuildRedirections[referenceOriginalUrl]
507
+ rawUrl = originalBuildUrl
508
+ ? rawUrls[originalBuildUrl]
509
+ : reference.url
510
+ } else {
511
+ rawUrl = reference.url
577
512
  }
578
- // specifier comes from "normalize" hook done a bit earlier in this file
579
- // we want to get back their build url to access their infos
580
- const referencedUrlInfo = finalGraph.getUrlInfo(reference.url)
581
- if (referencedUrlInfo.data.isEntryPoint) {
582
- return reference.specifier
513
+ // the url info do not exists yet (it will be created after this "normalize" hook)
514
+ // And the content will be generated when url is cooked by url graph loader.
515
+ // Here we just want to reserve an url for that file
516
+ const buildUrl = buildUrlsGenerator.generate(rawUrl, {
517
+ urlInfo: {
518
+ data: {
519
+ ...reference.data,
520
+ isWebWorkerEntryPoint:
521
+ isWebWorkerEntryPointReference(reference),
522
+ },
523
+ type: reference.expectedType,
524
+ subtype: reference.expectedSubtype,
525
+ filename: reference.filename,
526
+ },
527
+ })
528
+ postBuildRedirections[originalBuildUrl] = buildUrl
529
+ rawUrls[buildUrl] = rawUrl
530
+ return buildUrl
531
+ }
532
+ if (reference.isInline) {
533
+ const rawUrlInfo = GRAPH.find(rawGraph, (rawUrlInfo) => {
534
+ if (!rawUrlInfo.isInline) {
535
+ return false
536
+ }
537
+ if (rawUrlInfo.content === reference.content) {
538
+ return true
539
+ }
540
+ if (rawUrlInfo.originalContent === reference.content) {
541
+ return true
542
+ }
543
+ return false
544
+ })
545
+ const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
546
+ if (!rawUrlInfo) {
547
+ // generated during final graph
548
+ // (happens for JSON.parse injected for import assertions for instance)
549
+ // throw new Error(`cannot find raw url for "${reference.url}"`)
550
+ return reference.url
583
551
  }
584
- // data:* urls and so on
585
- if (!referencedUrlInfo.url.startsWith("file:")) {
586
- return null
552
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
553
+ urlInfo: rawUrlInfo,
554
+ parentUrlInfo,
555
+ })
556
+ rawUrls[buildUrl] = rawUrlInfo.url
557
+ return buildUrl
558
+ }
559
+ // from "js_module_as_js_classic":
560
+ // - to inject "s.js"
561
+ if (reference.injected) {
562
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
563
+ urlInfo: {
564
+ data: {},
565
+ type: "js_classic",
566
+ },
567
+ })
568
+ rawUrls[buildUrl] = reference.url
569
+ return buildUrl
570
+ }
571
+ const rawUrlInfo = rawGraph.getUrlInfo(reference.url)
572
+ const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
573
+ // files from root directory but not given to rollup nor postcss
574
+ if (rawUrlInfo) {
575
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
576
+ urlInfo: rawUrlInfo,
577
+ parentUrlInfo,
578
+ })
579
+ rawUrls[buildUrl] = rawUrlInfo.url
580
+ if (buildUrl.includes("?")) {
581
+ rawUrls[asUrlWithoutSearch(buildUrl)] = rawUrlInfo.url
587
582
  }
588
- const versionedUrl = referencedUrlInfo.data.versionedUrl
589
- if (!versionedUrl) {
590
- // happens for sourcemap
591
- return `${baseUrl}${urlToRelativeUrl(
592
- referencedUrlInfo.url,
593
- buildDirectoryUrl,
594
- )}`
583
+ return buildUrl
584
+ }
585
+ if (reference.type === "sourcemap_comment") {
586
+ // inherit parent build url
587
+ return generateSourcemapFileUrl(reference.parentUrl)
588
+ }
589
+ // files generated during the final graph:
590
+ // - sourcemaps
591
+ // const finalUrlInfo = finalGraph.getUrlInfo(url)
592
+ const buildUrl = buildUrlsGenerator.generate(reference.url, {
593
+ urlInfo: {
594
+ data: {},
595
+ type: "asset",
596
+ },
597
+ })
598
+ return buildUrl
599
+ },
600
+ formatUrl: (reference) => {
601
+ if (!reference.generatedUrl.startsWith("file:")) {
602
+ if (!versioning && reference.generatedUrl.startsWith("ignore:")) {
603
+ return reference.generatedUrl.slice("ignore:".length)
595
604
  }
596
- const versionedSpecifier = `${baseUrl}${urlToRelativeUrl(
597
- versionedUrl,
605
+ return null
606
+ }
607
+ if (!urlIsInsideOf(reference.generatedUrl, buildDirectoryUrl)) {
608
+ throw new Error(
609
+ `urls should be inside build directory at this stage, found "${reference.url}"`,
610
+ )
611
+ }
612
+ if (reference.isRessourceHint) {
613
+ // return the raw url, we will resync at the end
614
+ return rawUrls[reference.url]
615
+ }
616
+ // remove eventual search params and hash
617
+ const urlUntilPathname = asUrlUntilPathname(reference.generatedUrl)
618
+ let specifier
619
+ if (baseUrl === "./") {
620
+ const relativeUrl = urlToRelativeUrl(
621
+ urlUntilPathname,
622
+ reference.parentUrl === rootDirectoryUrl
623
+ ? buildDirectoryUrl
624
+ : reference.parentUrl,
625
+ )
626
+ // ensure "./" on relative url (otherwise it could be a "bare specifier")
627
+ specifier =
628
+ relativeUrl[0] === "." ? relativeUrl : `./${relativeUrl}`
629
+ } else {
630
+ // if a file is in the same directory we could prefer the relative notation
631
+ // but to keep things simple let's keep the "absolutely relative" to baseUrl for now
632
+ specifier = `${baseUrl}${urlToRelativeUrl(
633
+ urlUntilPathname,
598
634
  buildDirectoryUrl,
599
635
  )}`
600
- versionMappings[reference.specifier] = versionedSpecifier
601
- const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
602
- if (parentUrlInfo.jsQuote) {
603
- // the url is inline inside js quotes
604
- usedVersionMappings.push(reference.specifier)
605
- return () =>
606
- `${parentUrlInfo.jsQuote}+__v__(${JSON.stringify(
607
- reference.specifier,
608
- )})+${parentUrlInfo.jsQuote}`
636
+ }
637
+ buildUrls[specifier] = reference.generatedUrl
638
+ return specifier
639
+ },
640
+ fetchUrlContent: async (finalUrlInfo, context) => {
641
+ const fromBundleOrRawGraph = (url) => {
642
+ const bundleUrlInfo = bundleUrlInfos[url]
643
+ if (bundleUrlInfo) {
644
+ logger.debug(`fetching from bundle ${url}`)
645
+ return bundleUrlInfo
609
646
  }
610
- if (
611
- reference.type === "js_import_meta_url_pattern" ||
612
- reference.subtype === "import_dynamic"
613
- ) {
614
- usedVersionMappings.push(reference.specifier)
615
- return () => `__v__(${JSON.stringify(reference.specifier)})`
647
+ const rawUrl = rawUrls[url] || url
648
+ const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
649
+ if (!rawUrlInfo) {
650
+ throw new Error(`Cannot find url`)
616
651
  }
617
- return versionedSpecifier
618
- },
619
- load: ({ url }) => {
620
- const urlInfo = finalGraph.getUrlInfo(url)
621
- return {
622
- originalContent: urlInfo.originalContent,
623
- contentType: urlInfo.contentType,
624
- content: urlInfo.content,
625
- sourcemap: urlInfo.sourcemap,
652
+ logger.debug(`fetching from raw graph ${url}`)
653
+ if (rawUrlInfo.isInline) {
654
+ // Inline content, such as <script> inside html, is transformed during the previous phase.
655
+ // If we read the inline content it would be considered as the original content.
656
+ // - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
657
+ // as the original content.
658
+ // - But it would not work when sourcemap are not generated
659
+ // - would be a bit slower
660
+ // - So instead of reading the inline content directly, we search into raw graph
661
+ // to get "originalContent" and "sourcemap"
662
+ finalUrlInfo.type = rawUrlInfo.type
663
+ finalUrlInfo.subtype = rawUrlInfo.subtype
664
+ return rawUrlInfo
626
665
  }
627
- },
666
+ return rawUrlInfo
667
+ }
668
+ // reference injected during "postbuild":
669
+ // - happens for "as_js_classic" injecting "s.js"
670
+ if (context.reference.injected) {
671
+ const [ref, rawUrlInfo] = rawGraphKitchen.injectReference({
672
+ type: context.reference.type,
673
+ expectedType: context.reference.expectedType,
674
+ expectedSubtype: context.reference.expectedSubtype,
675
+ parentUrl: rawUrls[context.reference.parentUrl],
676
+ specifier: context.reference.specifier,
677
+ injected: true,
678
+ })
679
+ await rawGraphKitchen.cook(rawUrlInfo, { reference: ref })
680
+ return rawUrlInfo
681
+ }
682
+ // reference updated during "postbuild":
683
+ // - happens for "as_js_classic"
684
+ if (context.reference.original) {
685
+ return fromBundleOrRawGraph(context.reference.original.url)
686
+ }
687
+ return fromBundleOrRawGraph(finalUrlInfo.url)
628
688
  },
629
- ],
630
- scenario: "build",
631
- sourcemaps,
632
- })
633
- // arrange state before reloading all files
634
- Object.keys(finalGraph.urlInfos).forEach((url) => {
635
- const urlInfo = finalGraph.urlInfos[url]
636
- urlInfo.data.promise = null
637
- })
689
+ },
690
+ {
691
+ name: "jsenv:optimize",
692
+ appliesDuring: "build",
693
+ finalizeUrlContent: async (urlInfo, context) => {
694
+ if (optimizeUrlContentHooks.length) {
695
+ await rawGraphKitchen.pluginController.callAsyncHooks(
696
+ "optimizeUrlContent",
697
+ urlInfo,
698
+ context,
699
+ async (optimizeReturnValue) => {
700
+ await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
701
+ urlInfo,
702
+ optimizeReturnValue,
703
+ )
704
+ },
705
+ )
706
+ }
707
+ },
708
+ },
709
+ ],
710
+ })
711
+ const buildTask = createTaskLog("build", { disabled: infoLogsAreDisabled })
712
+ const postBuildEntryUrls = []
713
+ try {
638
714
  await loadUrlGraph({
715
+ operation: buildOperation,
639
716
  urlGraph: finalGraph,
640
- kitchen: versioningKitchen,
641
- runtimeSupport,
717
+ kitchen: finalGraphKitchen,
718
+ outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
719
+ writeGeneratedFiles,
720
+ skipRessourceHint: true,
642
721
  startLoading: (cookEntryFile) => {
643
- postBuildEntryUrls.forEach((postBuildEntryUrl) => {
644
- cookEntryFile({
722
+ entryUrls.forEach((entryUrl) => {
723
+ const [, postBuildEntryUrlInfo] = cookEntryFile({
645
724
  trace: `entryPoint`,
646
725
  type: "entry_point",
647
- specifier: postBuildEntryUrl,
726
+ specifier: entryUrl,
648
727
  })
728
+ postBuildEntryUrls.push(postBuildEntryUrlInfo.url)
649
729
  })
650
730
  },
651
731
  })
652
- if (usedVersionMappings.length) {
653
- const versionMappingsNeeded = {}
654
- usedVersionMappings.forEach((specifier) => {
655
- versionMappingsNeeded[specifier] = versionMappings[specifier]
656
- })
657
- await Promise.all(
658
- Object.keys(finalGraph.urlInfos).map(async (buildUrl) => {
659
- const buildUrlInfo = finalGraph.getUrlInfo(buildUrl)
660
- if (!buildUrlInfo.data.isEntryPoint) {
661
- return
662
- }
663
- await injectVersionMappings(buildUrlInfo, {
664
- kitchen: finalGraphKitchen,
665
- versionMappings: versionMappingsNeeded,
666
- })
667
- }),
668
- )
669
- }
670
732
  } catch (e) {
671
- versioningTask.fail()
733
+ buildTask.fail()
672
734
  throw e
673
735
  }
674
- versioningTask.done()
675
- }
736
+ buildTask.done()
676
737
 
677
- const buildFileContents = {}
678
- const buildInlineFileContents = {}
679
- const buildManifest = {}
680
- Object.keys(finalGraph.urlInfos).forEach((url) => {
681
- if (!url.startsWith("file:")) {
682
- return
683
- }
684
- const buildUrlInfo = finalGraph.getUrlInfo(url)
685
- const versionedUrl = buildUrlInfo.data.versionedUrl
686
- const useVersionedUrl = versionedUrl && !buildUrlInfo.data.isEntryPoint
687
- const buildUrl = useVersionedUrl ? versionedUrl : buildUrlInfo.url
688
- if (!urlIsInsideOf(buildUrl, buildDirectoryUrl)) {
689
- throw new Error(`build url outside build directory`)
690
- }
691
- const buildRelativeUrl = urlToRelativeUrl(buildUrl, buildDirectoryUrl)
692
- if (buildUrlInfo.isInline) {
693
- buildInlineFileContents[buildRelativeUrl] = buildUrlInfo.content
694
- } else {
695
- buildFileContents[buildRelativeUrl] = buildUrlInfo.content
738
+ logger.debug(
739
+ `graph urls pre-versioning:
740
+ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
741
+ )
742
+ if (versioning) {
743
+ await applyUrlVersioning({
744
+ buildOperation,
745
+ logger,
746
+ infoLogsAreDisabled,
747
+ buildDirectoryUrl,
748
+ rawUrls,
749
+ buildUrls,
750
+ baseUrl,
751
+ postBuildEntryUrls,
752
+ sourcemaps,
753
+ sourcemapsSourcesContent,
754
+ runtimeCompat,
755
+ writeGeneratedFiles,
756
+ rawGraph,
757
+ urlAnalysisPlugin,
758
+ finalGraph,
759
+ finalGraphKitchen,
760
+ lineBreakNormalization,
761
+ versioningMethod,
762
+ })
696
763
  }
697
- if (useVersionedUrl) {
698
- const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
699
- buildUrlInfo.url,
764
+ GRAPH.forEach(finalGraph, (urlInfo) => {
765
+ if (!urlInfo.shouldHandle) {
766
+ return
767
+ }
768
+ if (!urlInfo.url.startsWith("file:")) {
769
+ return
770
+ }
771
+ if (urlInfo.type === "html") {
772
+ const htmlAst = parseHtmlString(urlInfo.content, {
773
+ storeOriginalPositions: false,
774
+ })
775
+ urlInfo.content = stringifyHtmlAst(htmlAst, {
776
+ removeOriginalPositionAttributes: true,
777
+ })
778
+ }
779
+ const version = urlInfo.data.version
780
+ const useVersionedUrl = version && canUseVersionedUrl(urlInfo, finalGraph)
781
+ const buildUrl = useVersionedUrl ? urlInfo.data.versionedUrl : urlInfo.url
782
+ const buildUrlSpecifier = Object.keys(buildUrls).find(
783
+ (key) => buildUrls[key] === buildUrl,
784
+ )
785
+ urlInfo.data.buildUrl = buildUrl
786
+ urlInfo.data.buildUrlIsVersioned = useVersionedUrl
787
+ urlInfo.data.buildUrlSpecifier = buildUrlSpecifier
788
+ })
789
+ await resyncRessourceHints({
790
+ logger,
791
+ finalGraphKitchen,
792
+ finalGraph,
793
+ rawUrls,
794
+ postBuildRedirections,
795
+ })
796
+ buildOperation.throwIfAborted()
797
+ const cleanupActions = []
798
+ GRAPH.forEach(finalGraph, (urlInfo) => {
799
+ // nothing uses this url anymore
800
+ // - versioning update inline content
801
+ // - file converted for import assertion of js_classic conversion
802
+ if (
803
+ !urlInfo.data.isEntryPoint &&
804
+ urlInfo.type !== "sourcemap" &&
805
+ urlInfo.dependents.size === 0
806
+ ) {
807
+ cleanupActions.push(() => {
808
+ finalGraph.deleteUrlInfo(urlInfo.url)
809
+ })
810
+ }
811
+ })
812
+ cleanupActions.forEach((cleanupAction) => cleanupAction())
813
+ await injectServiceWorkerUrls({
814
+ finalGraphKitchen,
815
+ finalGraph,
816
+ lineBreakNormalization,
817
+ })
818
+ buildOperation.throwIfAborted()
819
+
820
+ const buildManifest = {}
821
+ const buildFileContents = {}
822
+ const buildInlineContents = {}
823
+ GRAPH.forEach(finalGraph, (urlInfo) => {
824
+ if (!urlInfo.shouldHandle) {
825
+ return
826
+ }
827
+ if (!urlInfo.url.startsWith("file:")) {
828
+ return
829
+ }
830
+ if (urlInfo.type === "directory") {
831
+ return
832
+ }
833
+ const buildRelativeUrl = urlToRelativeUrl(
834
+ urlInfo.data.buildUrl,
700
835
  buildDirectoryUrl,
701
836
  )
702
- buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
837
+ if (urlInfo.isInline) {
838
+ buildInlineContents[buildRelativeUrl] = urlInfo.content
839
+ } else {
840
+ buildFileContents[buildRelativeUrl] = urlInfo.content
841
+ const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
842
+ urlInfo.url,
843
+ buildDirectoryUrl,
844
+ )
845
+ buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
846
+ }
847
+ })
848
+ if (writeOnFileSystem) {
849
+ if (buildDirectoryClean) {
850
+ await ensureEmptyDirectory(buildDirectoryUrl)
851
+ }
852
+ const buildRelativeUrls = Object.keys(buildFileContents)
853
+ await Promise.all(
854
+ buildRelativeUrls.map(async (buildRelativeUrl) => {
855
+ await writeFile(
856
+ new URL(buildRelativeUrl, buildDirectoryUrl),
857
+ buildFileContents[buildRelativeUrl],
858
+ )
859
+ }),
860
+ )
861
+ if (versioning && assetManifest && Object.keys(buildManifest).length) {
862
+ await writeFile(
863
+ new URL(assetManifestFileRelativeUrl, buildDirectoryUrl),
864
+ JSON.stringify(buildManifest, null, " "),
865
+ )
866
+ }
867
+ }
868
+ logger.info(createUrlGraphSummary(finalGraph, { title: "build files" }))
869
+ return {
870
+ buildFileContents,
871
+ buildInlineContents,
872
+ buildManifest,
703
873
  }
874
+ }
875
+
876
+ if (!watch) {
877
+ return runBuild({ signal: operation.signal, logLevel })
878
+ }
879
+
880
+ let resolveFirstBuild
881
+ let rejectFirstBuild
882
+ const firstBuildPromise = new Promise((resolve, reject) => {
883
+ resolveFirstBuild = resolve
884
+ rejectFirstBuild = reject
704
885
  })
705
- logger.debug(
706
- `graph urls post-versioning:
707
- ${Object.keys(finalGraph.urlInfos).join("\n")}`,
708
- )
886
+ let buildAbortController
887
+ let watchFilesTask
888
+ const startBuild = async () => {
889
+ const buildTask = createTaskLog("build")
890
+ buildAbortController = new AbortController()
891
+ try {
892
+ const result = await runBuild({
893
+ signal: buildAbortController.signal,
894
+ logLevel: "warn",
895
+ })
896
+ buildTask.done()
897
+ resolveFirstBuild(result)
898
+ watchFilesTask = createTaskLog("watch files")
899
+ } catch (e) {
900
+ if (Abort.isAbortError(e)) {
901
+ buildTask.fail(`build aborted`)
902
+ } else if (e.code === "PARSE_ERROR") {
903
+ buildTask.fail()
904
+ console.error(e.stack)
905
+ watchFilesTask = createTaskLog("watch files")
906
+ } else {
907
+ buildTask.fail()
908
+ rejectFirstBuild(e)
909
+ throw e
910
+ }
911
+ }
912
+ }
709
913
 
710
- if (writeOnFileSystem) {
711
- if (buildDirectoryClean) {
712
- await ensureEmptyDirectory(buildDirectoryUrl)
914
+ startBuild()
915
+ let startTimeout
916
+ const clientFileChangeCallback = ({ relativeUrl, event }) => {
917
+ const url = new URL(relativeUrl, rootDirectoryUrl).href
918
+ if (watchFilesTask) {
919
+ watchFilesTask.happen(`${url.slice(rootDirectoryUrl.length)} ${event}`)
920
+ watchFilesTask = null
713
921
  }
714
- const buildRelativeUrls = Object.keys(buildFileContents)
715
- await Promise.all(
716
- buildRelativeUrls.map(async (buildRelativeUrl) => {
717
- await writeFile(
718
- new URL(buildRelativeUrl, buildDirectoryUrl),
719
- buildFileContents[buildRelativeUrl],
720
- )
721
- }),
722
- )
723
- if (
724
- versioning !== "none" &&
725
- assetManifest &&
726
- Object.keys(buildManifest).length
727
- ) {
728
- await writeFile(
729
- new URL(assetManifestFileRelativeUrl, buildDirectoryUrl),
730
- JSON.stringify(buildManifest, null, " "),
922
+ buildAbortController.abort()
923
+ // setTimeout is to ensure the abortController.abort() above
924
+ // is properly taken into account so that logs about abort comes first
925
+ // then logs about re-running the build happens
926
+ clearTimeout(startTimeout)
927
+ startTimeout = setTimeout(startBuild, 20)
928
+ }
929
+ const stopWatchingClientFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
930
+ watchPatterns: clientFiles,
931
+ cooldownBetweenFileEvents,
932
+ keepProcessAlive: true,
933
+ recursive: true,
934
+ added: ({ relativeUrl }) => {
935
+ clientFileChangeCallback({ relativeUrl, event: "added" })
936
+ },
937
+ updated: ({ relativeUrl }) => {
938
+ clientFileChangeCallback({ relativeUrl, event: "modified" })
939
+ },
940
+ removed: ({ relativeUrl }) => {
941
+ clientFileChangeCallback({ relativeUrl, event: "removed" })
942
+ },
943
+ })
944
+ operation.addAbortCallback(() => {
945
+ stopWatchingClientFiles()
946
+ })
947
+ await firstBuildPromise
948
+ return stopWatchingClientFiles
949
+ }
950
+
951
+ const applyUrlVersioning = async ({
952
+ buildOperation,
953
+ logger,
954
+ infoLogsAreDisabled,
955
+ buildDirectoryUrl,
956
+ rawUrls,
957
+ buildUrls,
958
+ baseUrl,
959
+ postBuildEntryUrls,
960
+ sourcemaps,
961
+ sourcemapsSourcesContent,
962
+ runtimeCompat,
963
+ writeGeneratedFiles,
964
+ rawGraph,
965
+ urlAnalysisPlugin,
966
+ finalGraph,
967
+ finalGraphKitchen,
968
+ lineBreakNormalization,
969
+ versioningMethod,
970
+ }) => {
971
+ const versioningTask = createTaskLog("inject version in urls", {
972
+ disabled: infoLogsAreDisabled,
973
+ })
974
+ try {
975
+ const urlsSorted = sortByDependencies(finalGraph.urlInfos)
976
+ urlsSorted.forEach((url) => {
977
+ if (url.startsWith("data:")) {
978
+ return
979
+ }
980
+ const urlInfo = finalGraph.getUrlInfo(url)
981
+ if (urlInfo.type === "sourcemap") {
982
+ return
983
+ }
984
+ // ignore:
985
+ // - inline files:
986
+ // they are already taken into account in the file where they appear
987
+ // - ignored files:
988
+ // we don't know their content
989
+ // - unused files without reference
990
+ // File updated such as style.css -> style.css.js or file.js->file.es5.js
991
+ // Are used at some point just to be discarded later because they need to be converted
992
+ // There is no need to version them and we could not because the file have been ignored
993
+ // so their content is unknown
994
+ if (urlInfo.isInline) {
995
+ return
996
+ }
997
+ if (!urlInfo.shouldHandle) {
998
+ return
999
+ }
1000
+ if (!urlInfo.data.isEntryPoint && urlInfo.dependents.size === 0) {
1001
+ return
1002
+ }
1003
+
1004
+ const urlContent =
1005
+ urlInfo.type === "html"
1006
+ ? stringifyHtmlAst(
1007
+ parseHtmlString(urlInfo.content, {
1008
+ storeOriginalPositions: false,
1009
+ }),
1010
+ { removeOriginalPositionAttributes: true },
1011
+ )
1012
+ : urlInfo.content
1013
+ const versionGenerator = createVersionGenerator()
1014
+ versionGenerator.augmentWithContent({
1015
+ content: urlContent,
1016
+ contentType: urlInfo.contentType,
1017
+ lineBreakNormalization,
1018
+ })
1019
+ urlInfo.dependencies.forEach((dependencyUrl) => {
1020
+ // this dependency is inline
1021
+ if (dependencyUrl.startsWith("data:")) {
1022
+ return
1023
+ }
1024
+ const dependencyUrlInfo = finalGraph.getUrlInfo(dependencyUrl)
1025
+ if (
1026
+ // this content is part of the file, no need to take into account twice
1027
+ dependencyUrlInfo.isInline ||
1028
+ // this dependency content is not known
1029
+ !dependencyUrlInfo.shouldHandle
1030
+ ) {
1031
+ return
1032
+ }
1033
+ if (dependencyUrlInfo.data.version) {
1034
+ versionGenerator.augmentWithDependencyVersion(
1035
+ dependencyUrlInfo.data.version,
1036
+ )
1037
+ } else {
1038
+ // because all dependencies are know, if the dependency has no version
1039
+ // it means there is a circular dependency between this file
1040
+ // and it's dependency
1041
+ // in that case we'll use the dependency content
1042
+ versionGenerator.augmentWithContent({
1043
+ content: dependencyUrlInfo.content,
1044
+ contentType: dependencyUrlInfo.contentType,
1045
+ lineBreakNormalization,
1046
+ })
1047
+ }
1048
+ })
1049
+ urlInfo.data.version = versionGenerator.generate()
1050
+
1051
+ urlInfo.data.versionedUrl = normalizeUrl(
1052
+ injectVersionIntoBuildUrl({
1053
+ buildUrl: urlInfo.url,
1054
+ version: urlInfo.data.version,
1055
+ versioningMethod,
1056
+ }),
731
1057
  )
1058
+ })
1059
+ const versionMappings = {}
1060
+ const usedVersionMappings = []
1061
+ const versioningKitchen = createKitchen({
1062
+ logger,
1063
+ rootDirectoryUrl: buildDirectoryUrl,
1064
+ urlGraph: finalGraph,
1065
+ scenario: "build",
1066
+ sourcemaps,
1067
+ sourcemapsSourcesContent,
1068
+ sourcemapsRelativeSources: true,
1069
+ runtimeCompat,
1070
+ writeGeneratedFiles,
1071
+ plugins: [
1072
+ urlAnalysisPlugin,
1073
+ jsenvPluginInline({
1074
+ fetchInlineUrls: false,
1075
+ analyzeConvertedScripts: true, // to be able to version their urls
1076
+ allowEscapeForVersioning: true,
1077
+ }),
1078
+ {
1079
+ name: "jsenv:versioning",
1080
+ appliesDuring: { build: true },
1081
+ resolveUrl: (reference) => {
1082
+ const buildUrl = buildUrls[reference.specifier]
1083
+ if (buildUrl) {
1084
+ return buildUrl
1085
+ }
1086
+ const urlObject = new URL(
1087
+ reference.specifier,
1088
+ reference.baseUrl || reference.parentUrl,
1089
+ )
1090
+ const url = urlObject.href
1091
+ // during versioning we revisit the deps
1092
+ // but the code used to enforce trailing slash on directories
1093
+ // is not applied because "jsenv:file_url_resolution" is not used
1094
+ // so here we search if the url with a trailing slash exists
1095
+ if (
1096
+ reference.type === "filesystem" &&
1097
+ !urlObject.pathname.endsWith("/")
1098
+ ) {
1099
+ const urlWithTrailingSlash = `${url}/`
1100
+ const specifier = Object.keys(buildUrls).find(
1101
+ (key) => buildUrls[key] === urlWithTrailingSlash,
1102
+ )
1103
+ if (specifier) {
1104
+ return urlWithTrailingSlash
1105
+ }
1106
+ }
1107
+ return url
1108
+ },
1109
+ formatUrl: (reference) => {
1110
+ if (!reference.shouldHandle) {
1111
+ if (reference.generatedUrl.startsWith("ignore:")) {
1112
+ return reference.generatedUrl.slice("ignore:".length)
1113
+ }
1114
+ return null
1115
+ }
1116
+ if (reference.isInline || reference.url.startsWith("data:")) {
1117
+ return null
1118
+ }
1119
+ if (reference.isRessourceHint) {
1120
+ return null
1121
+ }
1122
+ // specifier comes from "normalize" hook done a bit earlier in this file
1123
+ // we want to get back their build url to access their infos
1124
+ const referencedUrlInfo = finalGraph.getUrlInfo(reference.url)
1125
+ if (!canUseVersionedUrl(referencedUrlInfo)) {
1126
+ return reference.specifier
1127
+ }
1128
+ if (!referencedUrlInfo.shouldHandle) {
1129
+ return null
1130
+ }
1131
+ const versionedUrl = referencedUrlInfo.data.versionedUrl
1132
+ if (!versionedUrl) {
1133
+ // happens for sourcemap
1134
+ return `${baseUrl}${urlToRelativeUrl(
1135
+ referencedUrlInfo.url,
1136
+ buildDirectoryUrl,
1137
+ )}`
1138
+ }
1139
+ const versionedSpecifier = `${baseUrl}${urlToRelativeUrl(
1140
+ versionedUrl,
1141
+ buildDirectoryUrl,
1142
+ )}`
1143
+ versionMappings[reference.specifier] = versionedSpecifier
1144
+ buildUrls[versionedSpecifier] = versionedUrl
1145
+
1146
+ const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
1147
+ if (parentUrlInfo.jsQuote) {
1148
+ // the url is inline inside js quotes
1149
+ usedVersionMappings.push(reference.specifier)
1150
+ return () =>
1151
+ `${parentUrlInfo.jsQuote}+__v__(${JSON.stringify(
1152
+ reference.specifier,
1153
+ )})+${parentUrlInfo.jsQuote}`
1154
+ }
1155
+ if (
1156
+ reference.type === "js_url_specifier" ||
1157
+ reference.subtype === "import_dynamic"
1158
+ ) {
1159
+ usedVersionMappings.push(reference.specifier)
1160
+ return () => `__v__(${JSON.stringify(reference.specifier)})`
1161
+ }
1162
+ return versionedSpecifier
1163
+ },
1164
+ fetchUrlContent: (versionedUrlInfo) => {
1165
+ if (versionedUrlInfo.isInline) {
1166
+ const rawUrlInfo = rawGraph.getUrlInfo(
1167
+ rawUrls[versionedUrlInfo.url],
1168
+ )
1169
+ const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
1170
+ return {
1171
+ content: versionedUrlInfo.content,
1172
+ contentType: versionedUrlInfo.contentType,
1173
+ originalContent: rawUrlInfo
1174
+ ? rawUrlInfo.originalContent
1175
+ : undefined,
1176
+ sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
1177
+ }
1178
+ }
1179
+ return versionedUrlInfo
1180
+ },
1181
+ },
1182
+ ],
1183
+ })
1184
+ await loadUrlGraph({
1185
+ operation: buildOperation,
1186
+ urlGraph: finalGraph,
1187
+ kitchen: versioningKitchen,
1188
+ skipRessourceHint: true,
1189
+ writeGeneratedFiles,
1190
+ startLoading: (cookEntryFile) => {
1191
+ postBuildEntryUrls.forEach((postBuildEntryUrl) => {
1192
+ cookEntryFile({
1193
+ trace: `entryPoint`,
1194
+ type: "entry_point",
1195
+ specifier: postBuildEntryUrl,
1196
+ })
1197
+ })
1198
+ },
1199
+ })
1200
+ if (usedVersionMappings.length) {
1201
+ const versionMappingsNeeded = {}
1202
+ usedVersionMappings.forEach((specifier) => {
1203
+ versionMappingsNeeded[specifier] = versionMappings[specifier]
1204
+ })
1205
+ await injectGlobalVersionMapping({
1206
+ finalGraphKitchen,
1207
+ finalGraph,
1208
+ versionMappings: versionMappingsNeeded,
1209
+ })
732
1210
  }
1211
+ } catch (e) {
1212
+ versioningTask.fail()
1213
+ throw e
733
1214
  }
734
- logger.info(createUrlGraphSummary(finalGraph, { title: "build files" }))
735
- return {
736
- buildFileContents,
737
- buildInlineFileContents,
738
- buildManifest,
739
- }
1215
+ versioningTask.done()
740
1216
  }
741
1217
 
742
- const injectVersionIntoBuildUrl = ({ buildUrl, version, versioning }) => {
743
- if (versioning === "search_param") {
1218
+ const injectVersionIntoBuildUrl = ({ buildUrl, version, versioningMethod }) => {
1219
+ if (versioningMethod === "search_param") {
744
1220
  return injectQueryParams(buildUrl, {
745
1221
  v: version,
746
1222
  })
@@ -776,3 +1252,16 @@ const assertEntryPoints = ({ entryPoints }) => {
776
1252
  }
777
1253
  })
778
1254
  }
1255
+
1256
+ const canUseVersionedUrl = (urlInfo) => {
1257
+ if (urlInfo.data.isEntryPoint) {
1258
+ return false
1259
+ }
1260
+ if (urlInfo.type === "webmanifest") {
1261
+ return false
1262
+ }
1263
+ if (urlInfo.subtype === "service_worker") {
1264
+ return !urlInfo.data.isWebWorkerEntryPoint
1265
+ }
1266
+ return true
1267
+ }