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