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