@jsenv/core 27.0.0-alpha.2 → 27.0.0-alpha.20

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