@jsenv/core 27.0.0-alpha.12 → 27.0.0-alpha.15
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/main.js +4 -0
- package/package.json +15 -11
- package/readme.md +4 -12
- package/src/build/build.js +451 -388
- package/src/build/build_urls_generator.js +23 -20
- package/src/build/graph_utils.js +31 -0
- package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +31 -14
- package/src/build/inject_service_worker_urls.js +66 -12
- package/src/build/resync_ressource_hints.js +83 -0
- package/src/build/start_build_server.js +176 -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 +16 -22
- package/src/execute/execute.js +19 -6
- package/src/execute/run.js +17 -54
- package/src/execute/runtimes/browsers/from_playwright.js +167 -146
- package/src/execute/runtimes/node/node_process.js +281 -37
- 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} +30 -7
- package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
- package/src/omega/errors.js +51 -58
- package/src/omega/fetched_content_compliance.js +24 -0
- package/src/omega/kitchen.js +403 -283
- package/src/omega/server/file_service.js +9 -11
- package/src/omega/url_graph/url_graph_load.js +13 -7
- package/src/omega/url_graph/url_graph_report.js +7 -5
- package/src/omega/url_graph.js +22 -10
- 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 +41 -0
- package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +25 -166
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
- package/src/plugins/bundling/css/bundle_css.js +17 -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} +100 -75
- package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
- package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -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 +7 -4
- 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/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
- package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -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 +38 -46
- 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 +98 -0
- package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -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 +37 -31
- package/src/{omega/core_plugins → plugins}/inject_globals/jsenv_plugin_inject_globals.js +4 -6
- 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} +61 -40
- 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 +263 -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/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
- package/src/{omega → plugins}/plugin_controller.js +18 -10
- package/src/plugins/plugins.js +73 -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 +191 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -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 +3 -21
- 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 +29 -27
- package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
- 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/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
- package/src/plugins/url_references/css/css_urls.js +49 -0
- package/src/plugins/url_references/html/html_urls.js +273 -0
- package/src/plugins/url_references/js/js_urls.js +170 -0
- package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
- package/src/plugins/url_references/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 +8 -8
- package/src/test/execute_plan.js +23 -11
- package/src/test/execute_test_plan.js +9 -6
- 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/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/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 -207
- package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
- package/src/omega/core_plugins.js +0 -42
- 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,6 +21,7 @@ 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
26
|
import { createVersionGenerator } from "@jsenv/utils/versioning/version_generator.js"
|
|
26
27
|
import { generateSourcemapUrl } from "@jsenv/utils/sourcemap/sourcemap_utils.js"
|
|
@@ -29,21 +30,21 @@ import {
|
|
|
29
30
|
stringifyHtmlAst,
|
|
30
31
|
} from "@jsenv/utils/html_ast/html_ast.js"
|
|
31
32
|
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
33
|
+
import { jsenvPluginInline } from "../plugins/inline/jsenv_plugin_inline.js"
|
|
34
|
+
import { jsenvPluginAsJsClassic } from "../plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js"
|
|
34
35
|
import { createUrlGraph } from "../omega/url_graph.js"
|
|
35
|
-
import { getCorePlugins } from "../
|
|
36
|
+
import { getCorePlugins } from "../plugins/plugins.js"
|
|
36
37
|
import { createKitchen } from "../omega/kitchen.js"
|
|
37
38
|
import { loadUrlGraph } from "../omega/url_graph/url_graph_load.js"
|
|
38
39
|
import { createUrlGraphSummary } from "../omega/url_graph/url_graph_report.js"
|
|
39
40
|
import { sortUrlGraphByDependencies } from "../omega/url_graph/url_graph_sort.js"
|
|
41
|
+
import { isWebWorkerEntryPointReference } from "../omega/web_workers.js"
|
|
40
42
|
|
|
41
|
-
import {
|
|
42
|
-
import { jsenvPluginMinifyJs } from "./plugins/minify_js/jsenv_plugin_minify_js.js"
|
|
43
|
-
import { jsenvPluginMinifyHtml } from "./plugins/minify_html/jsenv_plugin_minify_html.js"
|
|
43
|
+
import { GRAPH } from "./graph_utils.js"
|
|
44
44
|
import { createBuilUrlsGenerator } from "./build_urls_generator.js"
|
|
45
|
-
import {
|
|
45
|
+
import { injectGlobalVersionMapping } from "./inject_global_version_mappings.js"
|
|
46
46
|
import { injectServiceWorkerUrls } from "./inject_service_worker_urls.js"
|
|
47
|
+
import { resyncRessourceHints } from "./resync_ressource_hints.js"
|
|
47
48
|
|
|
48
49
|
export const build = async ({
|
|
49
50
|
signal = new AbortController().signal,
|
|
@@ -55,18 +56,18 @@ export const build = async ({
|
|
|
55
56
|
// that will just pass different options to build project
|
|
56
57
|
// and this function will be agnostic about "preview" concept
|
|
57
58
|
isPreview = false,
|
|
59
|
+
|
|
58
60
|
plugins = [],
|
|
59
|
-
|
|
61
|
+
sourcemaps = isPreview ? "file" : false,
|
|
60
62
|
nodeEsmResolution,
|
|
61
63
|
fileSystemMagicResolution,
|
|
62
|
-
babel,
|
|
63
64
|
injectedGlobals,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
runtimeCompat,
|
|
66
|
+
transpilation = {},
|
|
67
67
|
bundling = true,
|
|
68
|
-
|
|
69
|
-
versioning =
|
|
68
|
+
minification = true,
|
|
69
|
+
versioning = true,
|
|
70
|
+
versioningMethod = "search_param", // "filename", "search_param"
|
|
70
71
|
lineBreakNormalization = process.platform === "win32",
|
|
71
72
|
|
|
72
73
|
writeOnFileSystem = true,
|
|
@@ -79,9 +80,9 @@ export const build = async ({
|
|
|
79
80
|
rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
|
|
80
81
|
buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
|
|
81
82
|
assertEntryPoints({ entryPoints })
|
|
82
|
-
if (!["filename", "search_param"
|
|
83
|
+
if (!["filename", "search_param"].includes(versioningMethod)) {
|
|
83
84
|
throw new Error(
|
|
84
|
-
`Unexpected "
|
|
85
|
+
`Unexpected "versioningMethod": must be "filename", "search_param"; got ${versioning}`,
|
|
85
86
|
)
|
|
86
87
|
}
|
|
87
88
|
|
|
@@ -101,6 +102,9 @@ build ${entryPointKeys.length} entry points`)
|
|
|
101
102
|
logger,
|
|
102
103
|
rootDirectoryUrl,
|
|
103
104
|
urlGraph: rawGraph,
|
|
105
|
+
scenario: "build",
|
|
106
|
+
sourcemaps,
|
|
107
|
+
runtimeCompat,
|
|
104
108
|
plugins: [
|
|
105
109
|
...plugins,
|
|
106
110
|
{
|
|
@@ -112,17 +116,17 @@ build ${entryPointKeys.length} entry points`)
|
|
|
112
116
|
},
|
|
113
117
|
},
|
|
114
118
|
...getCorePlugins({
|
|
115
|
-
htmlSupervisor,
|
|
116
119
|
nodeEsmResolution,
|
|
117
120
|
fileSystemMagicResolution,
|
|
118
|
-
babel,
|
|
119
121
|
injectedGlobals,
|
|
122
|
+
transpilation: {
|
|
123
|
+
...transpilation,
|
|
124
|
+
jsModuleAsJsClassic: false,
|
|
125
|
+
},
|
|
126
|
+
minification,
|
|
127
|
+
bundling,
|
|
120
128
|
}),
|
|
121
|
-
jsenvPluginBundleJsModule(),
|
|
122
|
-
...(minify ? [jsenvPluginMinifyJs(), jsenvPluginMinifyHtml()] : []),
|
|
123
129
|
],
|
|
124
|
-
scenario: "build",
|
|
125
|
-
sourcemaps,
|
|
126
130
|
})
|
|
127
131
|
const entryUrls = []
|
|
128
132
|
try {
|
|
@@ -130,7 +134,6 @@ build ${entryPointKeys.length} entry points`)
|
|
|
130
134
|
urlGraph: rawGraph,
|
|
131
135
|
kitchen: rawGraphKitchen,
|
|
132
136
|
outDirectoryUrl: new URL(`.jsenv/build/`, rootDirectoryUrl),
|
|
133
|
-
runtimeSupport,
|
|
134
137
|
startLoading: (cookEntryFile) => {
|
|
135
138
|
Object.keys(entryPoints).forEach((key) => {
|
|
136
139
|
const [, entryUrlInfo] = cookEntryFile({
|
|
@@ -153,209 +156,207 @@ build ${entryPointKeys.length} entry points`)
|
|
|
153
156
|
${Object.keys(rawGraph.urlInfos).join("\n")}`,
|
|
154
157
|
)
|
|
155
158
|
|
|
159
|
+
const buildUrlsGenerator = createBuilUrlsGenerator({
|
|
160
|
+
buildDirectoryUrl,
|
|
161
|
+
})
|
|
162
|
+
const rawUrls = {}
|
|
163
|
+
const buildUrls = {}
|
|
164
|
+
const rawUrlRedirections = {}
|
|
156
165
|
const bundleUrlInfos = {}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
const bundlers = {}
|
|
167
|
+
rawGraphKitchen.pluginController.plugins.forEach((plugin) => {
|
|
168
|
+
const bundle = plugin.bundle
|
|
169
|
+
if (!bundle) {
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
if (typeof bundle !== "object") {
|
|
173
|
+
throw new Error(
|
|
174
|
+
`bundle must be an object, found "${bundle}" on plugin named "${plugin.name}"`,
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
Object.keys(bundle).forEach((type) => {
|
|
178
|
+
const bundleFunction = bundle[type]
|
|
179
|
+
if (!bundleFunction) {
|
|
162
180
|
return
|
|
163
181
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
Object.keys(bundle).forEach((type) => {
|
|
170
|
-
const bundlerForThatType = bundlers[type]
|
|
171
|
-
if (bundlerForThatType) {
|
|
172
|
-
// first plugin to define a bundle hook wins
|
|
173
|
-
return
|
|
174
|
-
}
|
|
175
|
-
bundlers[type] = {
|
|
176
|
-
plugin,
|
|
177
|
-
bundleFunction: bundle[type],
|
|
178
|
-
urlInfos: [],
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
})
|
|
182
|
-
const addToBundlerIfAny = (rawUrlInfo) => {
|
|
183
|
-
const bundler = bundlers[rawUrlInfo.type]
|
|
184
|
-
if (bundler) {
|
|
185
|
-
bundler.urlInfos.push(rawUrlInfo)
|
|
182
|
+
const bundlerForThatType = bundlers[type]
|
|
183
|
+
if (bundlerForThatType) {
|
|
184
|
+
// first plugin to define a bundle hook wins
|
|
186
185
|
return
|
|
187
186
|
}
|
|
187
|
+
bundlers[type] = {
|
|
188
|
+
plugin,
|
|
189
|
+
bundleFunction: bundle[type],
|
|
190
|
+
urlInfos: [],
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
const addToBundlerIfAny = (rawUrlInfo) => {
|
|
195
|
+
const bundler = bundlers[rawUrlInfo.type]
|
|
196
|
+
if (bundler) {
|
|
197
|
+
bundler.urlInfos.push(rawUrlInfo)
|
|
198
|
+
return
|
|
188
199
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return
|
|
200
|
+
}
|
|
201
|
+
GRAPH.forEach(rawGraph, (rawUrlInfo) => {
|
|
202
|
+
if (rawUrlInfo.data.isEntryPoint) {
|
|
203
|
+
addToBundlerIfAny(rawUrlInfo)
|
|
204
|
+
if (rawUrlInfo.type === "html") {
|
|
205
|
+
rawUrlInfo.dependencies.forEach((dependencyUrl) => {
|
|
206
|
+
const dependencyUrlInfo = rawGraph.getUrlInfo(dependencyUrl)
|
|
207
|
+
if (dependencyUrlInfo.isInline) {
|
|
208
|
+
if (dependencyUrlInfo.type === "js_module") {
|
|
209
|
+
// bundle inline script type module deps
|
|
210
|
+
dependencyUrlInfo.references.forEach((inlineScriptRef) => {
|
|
211
|
+
if (inlineScriptRef.type === "js_import_export") {
|
|
212
|
+
const inlineUrlInfo = rawGraph.getUrlInfo(inlineScriptRef.url)
|
|
213
|
+
addToBundlerIfAny(inlineUrlInfo)
|
|
214
|
+
}
|
|
215
|
+
})
|
|
206
216
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// File referenced with new URL('./file.js', import.meta.url)
|
|
213
|
-
// are entry points that can be bundled
|
|
214
|
-
// For instance we will bundle service worker/workers detected like this
|
|
215
|
-
if (rawUrlInfo.type === "js_module") {
|
|
216
|
-
rawUrlInfo.references.forEach((reference) => {
|
|
217
|
-
if (reference.type === "js_import_meta_url_pattern") {
|
|
218
|
-
const urlInfo = rawGraph.getUrlInfo(reference.url)
|
|
219
|
-
addToBundlerIfAny(urlInfo)
|
|
217
|
+
// inline content cannot be bundled
|
|
218
|
+
return
|
|
220
219
|
}
|
|
220
|
+
addToBundlerIfAny(dependencyUrlInfo)
|
|
221
221
|
})
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
await Object.keys(bundlers).reduce(async (previous, type) => {
|
|
225
|
-
await previous
|
|
226
|
-
const bundler = bundlers[type]
|
|
227
|
-
const urlInfosToBundle = bundler.urlInfos
|
|
228
|
-
if (urlInfosToBundle.length === 0) {
|
|
229
222
|
return
|
|
230
223
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
224
|
+
}
|
|
225
|
+
// File referenced with new URL('./file.js', import.meta.url)
|
|
226
|
+
// are entry points that can be bundled
|
|
227
|
+
// For instance we will bundle service worker/workers detected like this
|
|
228
|
+
if (rawUrlInfo.type === "js_module") {
|
|
229
|
+
rawUrlInfo.references.forEach((reference) => {
|
|
230
|
+
if (reference.type === "js_url_specifier") {
|
|
231
|
+
const urlInfo = rawGraph.getUrlInfo(reference.url)
|
|
232
|
+
addToBundlerIfAny(urlInfo)
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
await Object.keys(bundlers).reduce(async (previous, type) => {
|
|
238
|
+
await previous
|
|
239
|
+
const bundler = bundlers[type]
|
|
240
|
+
const urlInfosToBundle = bundler.urlInfos
|
|
241
|
+
if (urlInfosToBundle.length === 0) {
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
const bundleTask = createTaskLog(logger, `bundle "${type}"`)
|
|
245
|
+
try {
|
|
246
|
+
const bundlerGeneratedUrlInfos =
|
|
247
|
+
await rawGraphKitchen.pluginController.callAsyncHook(
|
|
248
|
+
{
|
|
249
|
+
plugin: bundler.plugin,
|
|
250
|
+
hookName: "bundle",
|
|
251
|
+
value: bundler.bundleFunction,
|
|
252
|
+
},
|
|
253
|
+
urlInfosToBundle,
|
|
254
|
+
{
|
|
255
|
+
...rawGraphKitchen.baseContext,
|
|
256
|
+
buildDirectoryUrl,
|
|
257
|
+
},
|
|
258
|
+
)
|
|
259
|
+
Object.keys(bundlerGeneratedUrlInfos).forEach((url) => {
|
|
260
|
+
const rawUrlInfo = rawGraph.getUrlInfo(url)
|
|
261
|
+
const bundlerGeneratedUrlInfo = bundlerGeneratedUrlInfos[url]
|
|
262
|
+
const bundleUrlInfo = {
|
|
263
|
+
type,
|
|
264
|
+
subtype: rawUrlInfo ? rawUrlInfo.subtype : undefined,
|
|
265
|
+
filename: rawUrlInfo ? rawUrlInfo.filename : undefined,
|
|
266
|
+
...bundlerGeneratedUrlInfo,
|
|
267
|
+
data: {
|
|
268
|
+
...(rawUrlInfo ? rawUrlInfo.data : {}),
|
|
269
|
+
...bundlerGeneratedUrlInfo.data,
|
|
270
|
+
fromBundle: true,
|
|
271
|
+
},
|
|
272
|
+
}
|
|
273
|
+
const buildUrl = buildUrlsGenerator.generate(url, {
|
|
274
|
+
urlInfo: bundleUrlInfo,
|
|
264
275
|
})
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
276
|
+
rawUrlRedirections[url] = buildUrl
|
|
277
|
+
rawUrls[buildUrl] = url
|
|
278
|
+
bundleUrlInfos[buildUrl] = bundleUrlInfo
|
|
279
|
+
})
|
|
280
|
+
} catch (e) {
|
|
281
|
+
bundleTask.fail()
|
|
282
|
+
throw e
|
|
283
|
+
}
|
|
284
|
+
bundleTask.done()
|
|
285
|
+
}, Promise.resolve())
|
|
272
286
|
|
|
273
|
-
const
|
|
274
|
-
buildDirectoryUrl,
|
|
275
|
-
})
|
|
276
|
-
const rawUrls = {}
|
|
277
|
-
const buildUrls = {}
|
|
287
|
+
const buildUrlRedirections = {}
|
|
278
288
|
const finalGraph = createUrlGraph()
|
|
279
|
-
const
|
|
289
|
+
const optimizeUrlContentHooks =
|
|
290
|
+
rawGraphKitchen.pluginController.addHook("optimizeUrlContent")
|
|
280
291
|
const finalGraphKitchen = createKitchen({
|
|
281
292
|
logger,
|
|
282
293
|
rootDirectoryUrl,
|
|
283
294
|
urlGraph: finalGraph,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// as the original content.
|
|
288
|
-
// - But it would not work when sourcemap are not generated
|
|
289
|
-
// - would be a bit slower
|
|
290
|
-
// - So instead of reading the inline content directly, we search into raw graph
|
|
291
|
-
// to get "originalContent" and "sourcemap"
|
|
292
|
-
loadInlineUrlInfos: (finalUrlInfo) => {
|
|
293
|
-
const rawUrl = finalUrlInfo.data.rawUrl
|
|
294
|
-
const bundleUrlInfo = bundleUrlInfos[rawUrl]
|
|
295
|
-
const urlInfo = bundleUrlInfo || finalUrlInfo
|
|
296
|
-
const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
|
|
297
|
-
return {
|
|
298
|
-
originalContent: rawUrlInfo ? rawUrlInfo.originalContent : undefined,
|
|
299
|
-
sourcemap: bundleUrlInfo
|
|
300
|
-
? bundleUrlInfo.sourcemap
|
|
301
|
-
: rawUrlInfo
|
|
302
|
-
? rawUrlInfo.sourcemap
|
|
303
|
-
: undefined,
|
|
304
|
-
contentType: urlInfo.contentType,
|
|
305
|
-
content: urlInfo.content,
|
|
306
|
-
}
|
|
307
|
-
},
|
|
295
|
+
scenario: "build",
|
|
296
|
+
sourcemaps,
|
|
297
|
+
runtimeCompat,
|
|
308
298
|
plugins: [
|
|
309
|
-
|
|
299
|
+
jsenvPluginAsJsClassic({
|
|
300
|
+
systemJsInjection: true,
|
|
301
|
+
}),
|
|
302
|
+
jsenvPluginInline({
|
|
303
|
+
fetchInlineUrls: false,
|
|
304
|
+
}),
|
|
310
305
|
{
|
|
311
306
|
name: "jsenv:postbuild",
|
|
312
307
|
appliesDuring: { build: true },
|
|
313
|
-
|
|
314
|
-
if (reference.specifier[0] === "
|
|
315
|
-
|
|
316
|
-
.href
|
|
317
|
-
return url
|
|
318
|
-
}
|
|
319
|
-
const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
|
|
320
|
-
if (parentUrlInfo && parentUrlInfo.data.fromBundle) {
|
|
321
|
-
// code generated by rollup contains specifier relative
|
|
322
|
-
// to the generated file.
|
|
323
|
-
// This file does not exists yet we must resolve against the raw url, not the build url
|
|
324
|
-
const parentRawUrl = parentUrlInfo.data.rawUrl
|
|
325
|
-
const rawUrl = new URL(reference.specifier, parentRawUrl).href
|
|
326
|
-
return rawUrl
|
|
308
|
+
resolveUrl: (reference) => {
|
|
309
|
+
if (reference.specifier[0] === "#") {
|
|
310
|
+
reference.external = true
|
|
327
311
|
}
|
|
328
|
-
|
|
312
|
+
const url =
|
|
313
|
+
reference.specifier[0] === "/"
|
|
314
|
+
? new URL(reference.specifier.slice(1), buildDirectoryUrl).href
|
|
315
|
+
: new URL(reference.specifier, reference.parentUrl).href
|
|
316
|
+
const urlRedirected = rawUrlRedirections[url]
|
|
317
|
+
return urlRedirected || url
|
|
329
318
|
},
|
|
330
|
-
|
|
319
|
+
normalizeUrl: (reference) => {
|
|
331
320
|
if (!reference.url.startsWith("file:")) {
|
|
332
321
|
return null
|
|
333
322
|
}
|
|
334
323
|
// already a build url
|
|
335
324
|
const rawUrl = rawUrls[reference.url]
|
|
336
325
|
if (rawUrl) {
|
|
337
|
-
reference.data.rawUrl = rawUrl
|
|
338
326
|
return reference.url
|
|
339
327
|
}
|
|
340
|
-
const bundleUrlInfo = bundleUrlInfos[reference.url]
|
|
341
328
|
// from rollup or postcss
|
|
329
|
+
const bundleUrlInfo = bundleUrlInfos[reference.url]
|
|
342
330
|
if (bundleUrlInfo) {
|
|
343
|
-
|
|
344
|
-
reference.url,
|
|
345
|
-
bundleUrlInfo,
|
|
346
|
-
)
|
|
347
|
-
reference.data.rawUrl = reference.url
|
|
348
|
-
rawUrls[buildUrl] = reference.url
|
|
349
|
-
return buildUrl
|
|
331
|
+
return reference.url
|
|
350
332
|
}
|
|
351
|
-
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
|
|
333
|
+
// from "js_module_as_js_classic":
|
|
334
|
+
// - injecting "?as_js_classic" for the first time
|
|
335
|
+
// - injecting "?as_js_classic" because the parentUrl has it
|
|
336
|
+
if (reference.original) {
|
|
337
|
+
// the url info do not exists yet (it will be created after this "normalize" hook)
|
|
338
|
+
// And the content will be generated when url is cooked by url graph loader.
|
|
339
|
+
// Here we just want to reserve an url for that file
|
|
340
|
+
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
341
|
+
urlInfo: {
|
|
342
|
+
data: {
|
|
343
|
+
...reference.data,
|
|
344
|
+
isWebWorkerEntryPoint:
|
|
345
|
+
isWebWorkerEntryPointReference(reference),
|
|
346
|
+
},
|
|
347
|
+
type: reference.expectedType,
|
|
348
|
+
subtype: reference.expectedSubtype,
|
|
349
|
+
filename: reference.filename,
|
|
350
|
+
},
|
|
351
|
+
})
|
|
352
|
+
const originalUrl = reference.original.url
|
|
353
|
+
const originalBuildUrl = urlIsInsideOf(
|
|
355
354
|
reference.url,
|
|
356
|
-
|
|
355
|
+
buildDirectoryUrl,
|
|
357
356
|
)
|
|
358
|
-
|
|
357
|
+
? originalUrl
|
|
358
|
+
: Object.keys(rawUrls).find((key) => rawUrls[key] === originalUrl)
|
|
359
|
+
buildUrlRedirections[originalBuildUrl] = buildUrl
|
|
359
360
|
rawUrls[buildUrl] = reference.url
|
|
360
361
|
return buildUrl
|
|
361
362
|
}
|
|
@@ -367,84 +368,146 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
|
|
|
367
368
|
if (rawUrlInfo.content === reference.content) {
|
|
368
369
|
return true
|
|
369
370
|
}
|
|
371
|
+
if (rawUrlInfo.originalContent === reference.content) {
|
|
372
|
+
return true
|
|
373
|
+
}
|
|
370
374
|
return false
|
|
371
375
|
})
|
|
376
|
+
const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
|
|
372
377
|
if (!rawUrlInfo) {
|
|
373
|
-
|
|
378
|
+
// generated during final graph
|
|
379
|
+
// (happens for JSON.parse injected for import assertions for instance)
|
|
380
|
+
// throw new Error(`cannot find raw url for "${reference.url}"`)
|
|
381
|
+
return reference.url
|
|
374
382
|
}
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
reference.url,
|
|
378
|
-
rawUrlInfo,
|
|
383
|
+
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
384
|
+
urlInfo: rawUrlInfo,
|
|
379
385
|
parentUrlInfo,
|
|
380
|
-
)
|
|
386
|
+
})
|
|
387
|
+
rawUrls[buildUrl] = rawUrlInfo.url
|
|
388
|
+
return buildUrl
|
|
389
|
+
}
|
|
390
|
+
// from "js_module_as_js_classic":
|
|
391
|
+
// - to inject "s.js"
|
|
392
|
+
if (reference.injected) {
|
|
393
|
+
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
394
|
+
urlInfo: {
|
|
395
|
+
data: {},
|
|
396
|
+
type: "js_classic",
|
|
397
|
+
},
|
|
398
|
+
})
|
|
381
399
|
rawUrls[buildUrl] = reference.url
|
|
382
|
-
|
|
400
|
+
return buildUrl
|
|
401
|
+
}
|
|
402
|
+
const rawUrlInfo = rawGraph.getUrlInfo(reference.url)
|
|
403
|
+
// files from root directory but not given to rollup nor postcss
|
|
404
|
+
if (rawUrlInfo) {
|
|
405
|
+
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
406
|
+
urlInfo: rawUrlInfo,
|
|
407
|
+
})
|
|
408
|
+
rawUrls[buildUrl] = rawUrlInfo.url
|
|
383
409
|
return buildUrl
|
|
384
410
|
}
|
|
385
411
|
if (reference.type === "sourcemap_comment") {
|
|
386
412
|
// inherit parent build url
|
|
387
413
|
return generateSourcemapUrl(reference.parentUrl)
|
|
388
414
|
}
|
|
389
|
-
// files generated during the final graph
|
|
415
|
+
// files generated during the final graph:
|
|
416
|
+
// - sourcemaps
|
|
390
417
|
// const finalUrlInfo = finalGraph.getUrlInfo(url)
|
|
391
418
|
const buildUrl = buildUrlsGenerator.generate(reference.url, {
|
|
392
|
-
|
|
393
|
-
|
|
419
|
+
urlInfo: {
|
|
420
|
+
data: {},
|
|
421
|
+
type: "asset",
|
|
422
|
+
},
|
|
394
423
|
})
|
|
395
424
|
return buildUrl
|
|
396
425
|
},
|
|
397
|
-
|
|
398
|
-
if (!reference.
|
|
426
|
+
formatUrl: (reference) => {
|
|
427
|
+
if (!reference.generatedUrl.startsWith("file:")) {
|
|
399
428
|
return null
|
|
400
429
|
}
|
|
401
|
-
if (!urlIsInsideOf(reference.
|
|
430
|
+
if (!urlIsInsideOf(reference.generatedUrl, buildDirectoryUrl)) {
|
|
402
431
|
throw new Error(
|
|
403
432
|
`urls should be inside build directory at this stage, found "${reference.url}"`,
|
|
404
433
|
)
|
|
405
434
|
}
|
|
435
|
+
// remove eventual search params and hash
|
|
436
|
+
const urlUntilPathname = asUrlUntilPathname(reference.generatedUrl)
|
|
406
437
|
// if a file is in the same directory we could prefer the relative notation
|
|
407
|
-
// but to keep things simple let's keep the
|
|
438
|
+
// but to keep things simple let's keep the "absolutely relative" to baseUrl for now
|
|
408
439
|
const specifier = `${baseUrl}${urlToRelativeUrl(
|
|
409
|
-
|
|
440
|
+
urlUntilPathname,
|
|
410
441
|
buildDirectoryUrl,
|
|
411
442
|
)}`
|
|
412
|
-
buildUrls[specifier] = reference.
|
|
443
|
+
buildUrls[specifier] = reference.generatedUrl
|
|
413
444
|
return specifier
|
|
414
445
|
},
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const urlInfo = bundleUrlInfo || rawGraph.getUrlInfo(rawUrl)
|
|
419
|
-
finalUrlInfo.subtype = urlInfo.subtype
|
|
420
|
-
return {
|
|
421
|
-
data: bundleUrlInfo ? bundleUrlInfo.data : undefined,
|
|
422
|
-
originalContent: urlInfo.originalContent,
|
|
423
|
-
contentType: urlInfo.contentType,
|
|
424
|
-
content: urlInfo.content,
|
|
425
|
-
sourcemap: urlInfo.sourcemap,
|
|
446
|
+
fetchUrlContent: async (finalUrlInfo, context) => {
|
|
447
|
+
if (!finalUrlInfo.url.startsWith("file:")) {
|
|
448
|
+
return { external: true }
|
|
426
449
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
storeOriginalPositions: false,
|
|
432
|
-
})
|
|
433
|
-
return {
|
|
434
|
-
content: stringifyHtmlAst(htmlAst, {
|
|
435
|
-
removeOriginalPositionAttributes: true,
|
|
436
|
-
}),
|
|
450
|
+
const fromBundleOrRawGraph = (url) => {
|
|
451
|
+
const bundleUrlInfo = bundleUrlInfos[url]
|
|
452
|
+
if (bundleUrlInfo) {
|
|
453
|
+
return bundleUrlInfo
|
|
437
454
|
}
|
|
438
|
-
|
|
455
|
+
const rawUrl = rawUrls[url] || url
|
|
456
|
+
const rawUrlInfo = rawGraph.getUrlInfo(rawUrl)
|
|
457
|
+
if (!rawUrlInfo) {
|
|
458
|
+
const originalBuildUrl = buildUrlRedirections[url]
|
|
459
|
+
if (originalBuildUrl) {
|
|
460
|
+
return fromBundleOrRawGraph(originalBuildUrl)
|
|
461
|
+
}
|
|
462
|
+
throw new Error(`Cannot find url`)
|
|
463
|
+
}
|
|
464
|
+
if (rawUrlInfo.isInline) {
|
|
465
|
+
// Inline content, such as <script> inside html, is transformed during the previous phase.
|
|
466
|
+
// If we read the inline content it would be considered as the original content.
|
|
467
|
+
// - It could be "fixed" by taking into account sourcemap and consider sourcemap sources
|
|
468
|
+
// as the original content.
|
|
469
|
+
// - But it would not work when sourcemap are not generated
|
|
470
|
+
// - would be a bit slower
|
|
471
|
+
// - So instead of reading the inline content directly, we search into raw graph
|
|
472
|
+
// to get "originalContent" and "sourcemap"
|
|
473
|
+
finalUrlInfo.type = rawUrlInfo.type
|
|
474
|
+
finalUrlInfo.subtype = rawUrlInfo.subtype
|
|
475
|
+
return rawUrlInfo
|
|
476
|
+
}
|
|
477
|
+
return rawUrlInfo
|
|
478
|
+
}
|
|
479
|
+
// reference injected during "postbuild":
|
|
480
|
+
// - happens for "as_js_classic" injecting "s.js"
|
|
481
|
+
if (context.reference.injected) {
|
|
482
|
+
const [ref, rawUrlInfo] = rawGraphKitchen.injectReference({
|
|
483
|
+
type: context.reference.type,
|
|
484
|
+
expectedType: context.reference.expectedType,
|
|
485
|
+
expectedSubtype: context.reference.expectedSubtype,
|
|
486
|
+
parentUrl: rawUrls[context.reference.parentUrl],
|
|
487
|
+
specifier: context.reference.specifier,
|
|
488
|
+
injected: true,
|
|
489
|
+
})
|
|
490
|
+
await rawGraphKitchen.cook({
|
|
491
|
+
reference: ref,
|
|
492
|
+
urlInfo: rawUrlInfo,
|
|
493
|
+
})
|
|
494
|
+
return rawUrlInfo
|
|
495
|
+
}
|
|
496
|
+
// reference updated during "postbuild":
|
|
497
|
+
// - happens for "as_js_classic"
|
|
498
|
+
if (context.reference.original) {
|
|
499
|
+
return fromBundleOrRawGraph(context.reference.original.url)
|
|
500
|
+
}
|
|
501
|
+
return fromBundleOrRawGraph(finalUrlInfo.url)
|
|
439
502
|
},
|
|
440
503
|
},
|
|
441
504
|
{
|
|
442
505
|
name: "jsenv:optimize",
|
|
443
506
|
appliesDuring: { build: true },
|
|
444
|
-
|
|
445
|
-
if (
|
|
507
|
+
finalizeUrlContent: async (urlInfo, context) => {
|
|
508
|
+
if (optimizeUrlContentHooks.length) {
|
|
446
509
|
await rawGraphKitchen.pluginController.callAsyncHooks(
|
|
447
|
-
"
|
|
510
|
+
"optimizeUrlContent",
|
|
448
511
|
urlInfo,
|
|
449
512
|
context,
|
|
450
513
|
async (optimizeReturnValue) => {
|
|
@@ -458,8 +521,6 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
|
|
|
458
521
|
},
|
|
459
522
|
},
|
|
460
523
|
],
|
|
461
|
-
scenario: "build",
|
|
462
|
-
sourcemaps,
|
|
463
524
|
})
|
|
464
525
|
const buildTask = createTaskLog(logger, "build")
|
|
465
526
|
const postBuildEntryUrls = []
|
|
@@ -468,7 +529,6 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
|
|
|
468
529
|
urlGraph: finalGraph,
|
|
469
530
|
kitchen: finalGraphKitchen,
|
|
470
531
|
outDirectoryUrl: new URL(".jsenv/postbuild/", rootDirectoryUrl),
|
|
471
|
-
runtimeSupport,
|
|
472
532
|
startLoading: (cookEntryFile) => {
|
|
473
533
|
entryUrls.forEach((entryUrl) => {
|
|
474
534
|
const [, postBuildEntryUrlInfo] = cookEntryFile({
|
|
@@ -490,7 +550,7 @@ ${Object.keys(rawGraph.urlInfos).join("\n")}`,
|
|
|
490
550
|
`graph urls pre-versioning:
|
|
491
551
|
${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
492
552
|
)
|
|
493
|
-
if (versioning
|
|
553
|
+
if (versioning) {
|
|
494
554
|
const versioningTask = createTaskLog(logger, "inject version in urls")
|
|
495
555
|
try {
|
|
496
556
|
const urlsSorted = sortUrlGraphByDependencies(finalGraph)
|
|
@@ -502,19 +562,53 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
502
562
|
if (urlInfo.type === "sourcemap") {
|
|
503
563
|
return
|
|
504
564
|
}
|
|
565
|
+
// ignore:
|
|
566
|
+
// - inline files:
|
|
567
|
+
// they are already taken into account in the file where they appear
|
|
568
|
+
// - external files
|
|
569
|
+
// we don't know their content
|
|
570
|
+
// - unused files without reference
|
|
571
|
+
// File updated such as style.css -> style.css.js or file.js->file.es5.js
|
|
572
|
+
// Are used at some point just to be discarded later because they need to be converted
|
|
573
|
+
// There is no need to version them and we could not because the file have been ignored
|
|
574
|
+
// so their content is unknown
|
|
505
575
|
if (urlInfo.isInline) {
|
|
506
576
|
return
|
|
507
577
|
}
|
|
578
|
+
if (urlInfo.external) {
|
|
579
|
+
return
|
|
580
|
+
}
|
|
581
|
+
if (!urlInfo.data.isEntryPoint && urlInfo.dependents.size === 0) {
|
|
582
|
+
return
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const urlContent =
|
|
586
|
+
urlInfo.type === "html"
|
|
587
|
+
? stringifyHtmlAst(
|
|
588
|
+
parseHtmlString(urlInfo.content, {
|
|
589
|
+
storeOriginalPositions: false,
|
|
590
|
+
}),
|
|
591
|
+
{ removeOriginalPositionAttributes: true },
|
|
592
|
+
)
|
|
593
|
+
: urlInfo.content
|
|
508
594
|
const versionGenerator = createVersionGenerator()
|
|
509
595
|
versionGenerator.augmentWithContent({
|
|
510
|
-
content:
|
|
596
|
+
content: urlContent,
|
|
511
597
|
contentType: urlInfo.contentType,
|
|
512
598
|
lineBreakNormalization,
|
|
513
599
|
})
|
|
514
600
|
urlInfo.dependencies.forEach((dependencyUrl) => {
|
|
601
|
+
// this dependency is inline (data:) or remote (http://, https://)
|
|
602
|
+
if (!dependencyUrl.startsWith("file:")) {
|
|
603
|
+
return
|
|
604
|
+
}
|
|
515
605
|
const dependencyUrlInfo = finalGraph.getUrlInfo(dependencyUrl)
|
|
516
|
-
if (
|
|
606
|
+
if (
|
|
517
607
|
// this content is part of the file, no need to take into account twice
|
|
608
|
+
dependencyUrlInfo.isInline ||
|
|
609
|
+
// this dependency content is not known
|
|
610
|
+
dependencyUrlInfo.external
|
|
611
|
+
) {
|
|
518
612
|
return
|
|
519
613
|
}
|
|
520
614
|
if (dependencyUrlInfo.data.version) {
|
|
@@ -534,10 +628,11 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
534
628
|
}
|
|
535
629
|
})
|
|
536
630
|
urlInfo.data.version = versionGenerator.generate()
|
|
631
|
+
|
|
537
632
|
urlInfo.data.versionedUrl = injectVersionIntoBuildUrl({
|
|
538
633
|
buildUrl: urlInfo.url,
|
|
539
634
|
version: urlInfo.data.version,
|
|
540
|
-
|
|
635
|
+
versioningMethod,
|
|
541
636
|
})
|
|
542
637
|
})
|
|
543
638
|
const versionMappings = {}
|
|
@@ -546,26 +641,22 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
546
641
|
logger,
|
|
547
642
|
rootDirectoryUrl: buildDirectoryUrl,
|
|
548
643
|
urlGraph: finalGraph,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
return {
|
|
553
|
-
originalContent: rawUrlInfo
|
|
554
|
-
? rawUrlInfo.originalContent
|
|
555
|
-
: undefined,
|
|
556
|
-
sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
|
|
557
|
-
contentType: versionedUrlInfo.contentType,
|
|
558
|
-
content: versionedUrlInfo.content,
|
|
559
|
-
}
|
|
560
|
-
},
|
|
644
|
+
scenario: "build",
|
|
645
|
+
sourcemaps,
|
|
646
|
+
runtimeCompat,
|
|
561
647
|
plugins: [
|
|
562
648
|
jsenvPluginInline({
|
|
649
|
+
fetchInlineUrls: false,
|
|
650
|
+
analyzeConvertedScripts: true, // to be able to version their urls
|
|
563
651
|
allowEscapeForVersioning: true,
|
|
564
652
|
}),
|
|
565
653
|
{
|
|
566
654
|
name: "jsenv:versioning",
|
|
567
655
|
appliesDuring: { build: true },
|
|
568
|
-
|
|
656
|
+
resolveUrl: (reference) => {
|
|
657
|
+
if (reference.specifier[0] === "#") {
|
|
658
|
+
reference.external = true
|
|
659
|
+
}
|
|
569
660
|
const buildUrl = buildUrls[reference.specifier]
|
|
570
661
|
if (buildUrl) {
|
|
571
662
|
return buildUrl
|
|
@@ -573,18 +664,14 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
573
664
|
const url = new URL(reference.specifier, reference.parentUrl).href
|
|
574
665
|
return url
|
|
575
666
|
},
|
|
576
|
-
|
|
667
|
+
formatUrl: (reference) => {
|
|
577
668
|
if (reference.isInline) {
|
|
578
669
|
return null
|
|
579
670
|
}
|
|
580
671
|
// specifier comes from "normalize" hook done a bit earlier in this file
|
|
581
672
|
// we want to get back their build url to access their infos
|
|
582
673
|
const referencedUrlInfo = finalGraph.getUrlInfo(reference.url)
|
|
583
|
-
if (
|
|
584
|
-
referencedUrlInfo.data.isEntryPoint ||
|
|
585
|
-
referencedUrlInfo.subtype === "service_worker" ||
|
|
586
|
-
referencedUrlInfo.type === "webmanifest"
|
|
587
|
-
) {
|
|
674
|
+
if (!canUseVersionedUrl(referencedUrlInfo)) {
|
|
588
675
|
return reference.specifier
|
|
589
676
|
}
|
|
590
677
|
// data:* urls and so on
|
|
@@ -604,6 +691,8 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
604
691
|
buildDirectoryUrl,
|
|
605
692
|
)}`
|
|
606
693
|
versionMappings[reference.specifier] = versionedSpecifier
|
|
694
|
+
buildUrls[versionedSpecifier] = versionedUrl
|
|
695
|
+
|
|
607
696
|
const parentUrlInfo = finalGraph.getUrlInfo(reference.parentUrl)
|
|
608
697
|
if (parentUrlInfo.jsQuote) {
|
|
609
698
|
// the url is inline inside js quotes
|
|
@@ -614,7 +703,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
614
703
|
)})+${parentUrlInfo.jsQuote}`
|
|
615
704
|
}
|
|
616
705
|
if (
|
|
617
|
-
reference.type === "
|
|
706
|
+
reference.type === "js_url_specifier" ||
|
|
618
707
|
reference.subtype === "import_dynamic"
|
|
619
708
|
) {
|
|
620
709
|
usedVersionMappings.push(reference.specifier)
|
|
@@ -622,27 +711,32 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
622
711
|
}
|
|
623
712
|
return versionedSpecifier
|
|
624
713
|
},
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
714
|
+
fetchUrlContent: (versionedUrlInfo) => {
|
|
715
|
+
if (!versionedUrlInfo.url.startsWith("file:")) {
|
|
716
|
+
return { external: true }
|
|
717
|
+
}
|
|
718
|
+
if (versionedUrlInfo.isInline) {
|
|
719
|
+
const rawUrlInfo = rawGraph.getUrlInfo(
|
|
720
|
+
rawUrls[versionedUrlInfo.url],
|
|
721
|
+
)
|
|
722
|
+
const finalUrlInfo = finalGraph.getUrlInfo(versionedUrlInfo.url)
|
|
723
|
+
return {
|
|
724
|
+
originalContent: rawUrlInfo
|
|
725
|
+
? rawUrlInfo.originalContent
|
|
726
|
+
: undefined,
|
|
727
|
+
sourcemap: finalUrlInfo ? finalUrlInfo.sourcemap : undefined,
|
|
728
|
+
contentType: versionedUrlInfo.contentType,
|
|
729
|
+
content: versionedUrlInfo.content,
|
|
730
|
+
}
|
|
631
731
|
}
|
|
732
|
+
return versionedUrlInfo
|
|
632
733
|
},
|
|
633
734
|
},
|
|
634
735
|
],
|
|
635
|
-
scenario: "build",
|
|
636
|
-
sourcemaps,
|
|
637
|
-
})
|
|
638
|
-
// arrange state before reloading all files
|
|
639
|
-
GRAPH.forEach(finalGraph, (finalUrlInfo) => {
|
|
640
|
-
finalUrlInfo.data.promise = null
|
|
641
736
|
})
|
|
642
737
|
await loadUrlGraph({
|
|
643
738
|
urlGraph: finalGraph,
|
|
644
739
|
kitchen: versioningKitchen,
|
|
645
|
-
runtimeSupport,
|
|
646
740
|
startLoading: (cookEntryFile) => {
|
|
647
741
|
postBuildEntryUrls.forEach((postBuildEntryUrl) => {
|
|
648
742
|
cookEntryFile({
|
|
@@ -658,18 +752,11 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
658
752
|
usedVersionMappings.forEach((specifier) => {
|
|
659
753
|
versionMappingsNeeded[specifier] = versionMappings[specifier]
|
|
660
754
|
})
|
|
661
|
-
await
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
await injectVersionMappings({
|
|
667
|
-
urlInfo,
|
|
668
|
-
kitchen: finalGraphKitchen,
|
|
669
|
-
versionMappings: versionMappingsNeeded,
|
|
670
|
-
})
|
|
671
|
-
}),
|
|
672
|
-
)
|
|
755
|
+
await injectGlobalVersionMapping({
|
|
756
|
+
finalGraphKitchen,
|
|
757
|
+
finalGraph,
|
|
758
|
+
versionMappings: versionMappingsNeeded,
|
|
759
|
+
})
|
|
673
760
|
}
|
|
674
761
|
} catch (e) {
|
|
675
762
|
versioningTask.fail()
|
|
@@ -682,99 +769,87 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
682
769
|
if (!urlInfo.url.startsWith("file:")) {
|
|
683
770
|
return
|
|
684
771
|
}
|
|
772
|
+
if (urlInfo.external) {
|
|
773
|
+
return
|
|
774
|
+
}
|
|
775
|
+
if (urlInfo.type === "html") {
|
|
776
|
+
const htmlAst = parseHtmlString(urlInfo.content, {
|
|
777
|
+
storeOriginalPositions: false,
|
|
778
|
+
})
|
|
779
|
+
urlInfo.content = stringifyHtmlAst(htmlAst, {
|
|
780
|
+
removeOriginalPositionAttributes: true,
|
|
781
|
+
})
|
|
782
|
+
}
|
|
685
783
|
const version = urlInfo.data.version
|
|
686
|
-
const useVersionedUrl =
|
|
687
|
-
!urlInfo.data.isEntryPoint &&
|
|
688
|
-
urlInfo.subtype !== "service_worker" &&
|
|
689
|
-
urlInfo.type !== "webmanifest" &&
|
|
690
|
-
version
|
|
784
|
+
const useVersionedUrl = version && canUseVersionedUrl(urlInfo, finalGraph)
|
|
691
785
|
const buildUrl = useVersionedUrl ? urlInfo.data.versionedUrl : urlInfo.url
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const buildRelativeUrl = urlToRelativeUrl(buildUrl, buildDirectoryUrl)
|
|
786
|
+
const buildUrlSpecifier = Object.keys(buildUrls).find(
|
|
787
|
+
(key) => buildUrls[key] === buildUrl,
|
|
788
|
+
)
|
|
696
789
|
urlInfo.data.buildUrl = buildUrl
|
|
697
790
|
urlInfo.data.buildUrlIsVersioned = useVersionedUrl
|
|
698
|
-
urlInfo.data.
|
|
791
|
+
urlInfo.data.buildUrlSpecifier = buildUrlSpecifier
|
|
699
792
|
})
|
|
700
793
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
794
|
+
await resyncRessourceHints({
|
|
795
|
+
finalGraphKitchen,
|
|
796
|
+
finalGraph,
|
|
797
|
+
rawUrls,
|
|
798
|
+
buildUrls,
|
|
799
|
+
buildUrlRedirections,
|
|
800
|
+
})
|
|
801
|
+
const cleanupActions = []
|
|
802
|
+
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
803
|
+
// nothing uses this url anymore
|
|
804
|
+
// - versioning update inline content
|
|
805
|
+
// - file converted for import assertion of js_classic conversion
|
|
806
|
+
if (
|
|
807
|
+
!urlInfo.data.isEntryPoint &&
|
|
808
|
+
urlInfo.type !== "sourcemap" &&
|
|
809
|
+
urlInfo.dependents.size === 0
|
|
810
|
+
) {
|
|
811
|
+
cleanupActions.push(() => {
|
|
812
|
+
delete finalGraph.urlInfos[urlInfo.url]
|
|
813
|
+
})
|
|
814
|
+
}
|
|
815
|
+
})
|
|
816
|
+
cleanupActions.forEach((cleanupAction) => cleanupAction())
|
|
817
|
+
await injectServiceWorkerUrls({
|
|
818
|
+
finalGraphKitchen,
|
|
819
|
+
finalGraph,
|
|
820
|
+
lineBreakNormalization,
|
|
821
|
+
})
|
|
822
|
+
|
|
823
|
+
logger.debug(
|
|
824
|
+
`graph urls post-versioning:
|
|
825
|
+
${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
706
826
|
)
|
|
707
|
-
if (hasServiceWorker) {
|
|
708
|
-
const serviceWorkerUrls = {}
|
|
709
|
-
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
710
|
-
if (!urlInfo.url.startsWith("file:")) {
|
|
711
|
-
return
|
|
712
|
-
}
|
|
713
|
-
if (urlInfo.isInline) {
|
|
714
|
-
return
|
|
715
|
-
}
|
|
716
|
-
if (urlInfo.data.buildUrlIsVersioned) {
|
|
717
|
-
serviceWorkerUrls[urlInfo.data.buildRelativeUrl] = {
|
|
718
|
-
versioned: true,
|
|
719
|
-
}
|
|
720
|
-
return
|
|
721
|
-
}
|
|
722
|
-
if (!urlInfo.data.version) {
|
|
723
|
-
// when url is not versioned we compute a "version" for that url anyway
|
|
724
|
-
// so that service worker source still changes and navigator
|
|
725
|
-
// detect there is a change
|
|
726
|
-
const versionGenerator = createVersionGenerator()
|
|
727
|
-
versionGenerator.augmentWithContent({
|
|
728
|
-
content: urlInfo.content,
|
|
729
|
-
contentType: urlInfo.contentType,
|
|
730
|
-
lineBreakNormalization,
|
|
731
|
-
})
|
|
732
|
-
const version = versionGenerator.generate()
|
|
733
|
-
urlInfo.data.version = version
|
|
734
|
-
}
|
|
735
|
-
serviceWorkerUrls[urlInfo.data.buildRelativeUrl] = {
|
|
736
|
-
versioned: false,
|
|
737
|
-
version: urlInfo.data.version,
|
|
738
|
-
}
|
|
739
|
-
})
|
|
740
|
-
await Promise.all(
|
|
741
|
-
GRAPH.map(finalGraph, async (urlInfo) => {
|
|
742
|
-
if (urlInfo.subtype !== "service_worker") {
|
|
743
|
-
return
|
|
744
|
-
}
|
|
745
|
-
await injectServiceWorkerUrls({
|
|
746
|
-
urlInfo,
|
|
747
|
-
kitchen: finalGraphKitchen,
|
|
748
|
-
serviceWorkerUrls,
|
|
749
|
-
})
|
|
750
|
-
}),
|
|
751
|
-
)
|
|
752
|
-
}
|
|
753
827
|
|
|
754
828
|
const buildManifest = {}
|
|
755
829
|
const buildFileContents = {}
|
|
756
|
-
const
|
|
830
|
+
const buildInlineContents = {}
|
|
757
831
|
GRAPH.forEach(finalGraph, (urlInfo) => {
|
|
758
|
-
|
|
832
|
+
if (urlInfo.external) {
|
|
833
|
+
return
|
|
834
|
+
}
|
|
835
|
+
if (urlInfo.url.startsWith("data:")) {
|
|
836
|
+
return
|
|
837
|
+
}
|
|
838
|
+
const buildRelativeUrl = urlToRelativeUrl(
|
|
839
|
+
urlInfo.data.buildUrl,
|
|
840
|
+
buildDirectoryUrl,
|
|
841
|
+
)
|
|
759
842
|
if (urlInfo.isInline) {
|
|
760
|
-
|
|
843
|
+
buildInlineContents[buildRelativeUrl] = urlInfo.content
|
|
761
844
|
} else {
|
|
762
845
|
buildFileContents[buildRelativeUrl] = urlInfo.content
|
|
763
846
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
|
|
770
|
-
}
|
|
847
|
+
const buildRelativeUrlWithoutVersioning = urlToRelativeUrl(
|
|
848
|
+
urlInfo.url,
|
|
849
|
+
buildDirectoryUrl,
|
|
850
|
+
)
|
|
851
|
+
buildManifest[buildRelativeUrlWithoutVersioning] = buildRelativeUrl
|
|
771
852
|
})
|
|
772
|
-
|
|
773
|
-
logger.debug(
|
|
774
|
-
`graph urls post-versioning:
|
|
775
|
-
${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
776
|
-
)
|
|
777
|
-
|
|
778
853
|
if (writeOnFileSystem) {
|
|
779
854
|
if (buildDirectoryClean) {
|
|
780
855
|
await ensureEmptyDirectory(buildDirectoryUrl)
|
|
@@ -788,11 +863,7 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
788
863
|
)
|
|
789
864
|
}),
|
|
790
865
|
)
|
|
791
|
-
if (
|
|
792
|
-
versioning !== "none" &&
|
|
793
|
-
assetManifest &&
|
|
794
|
-
Object.keys(buildManifest).length
|
|
795
|
-
) {
|
|
866
|
+
if (versioning && assetManifest && Object.keys(buildManifest).length) {
|
|
796
867
|
await writeFile(
|
|
797
868
|
new URL(assetManifestFileRelativeUrl, buildDirectoryUrl),
|
|
798
869
|
JSON.stringify(buildManifest, null, " "),
|
|
@@ -802,34 +873,13 @@ ${Object.keys(finalGraph.urlInfos).join("\n")}`,
|
|
|
802
873
|
logger.info(createUrlGraphSummary(finalGraph, { title: "build files" }))
|
|
803
874
|
return {
|
|
804
875
|
buildFileContents,
|
|
805
|
-
|
|
876
|
+
buildInlineContents,
|
|
806
877
|
buildManifest,
|
|
807
878
|
}
|
|
808
879
|
}
|
|
809
880
|
|
|
810
|
-
const
|
|
811
|
-
|
|
812
|
-
return Object.keys(graph.urlInfos).map((url) => {
|
|
813
|
-
return callback(graph.urlInfos[url])
|
|
814
|
-
})
|
|
815
|
-
},
|
|
816
|
-
|
|
817
|
-
forEach: (graph, callback) => {
|
|
818
|
-
Object.keys(graph.urlInfos).forEach((url) => {
|
|
819
|
-
callback(graph.urlInfos[url], url)
|
|
820
|
-
})
|
|
821
|
-
},
|
|
822
|
-
|
|
823
|
-
find: (graph, callback) => {
|
|
824
|
-
const urlFound = Object.keys(graph.urlInfos).find((url) => {
|
|
825
|
-
return callback(graph.urlInfos[url])
|
|
826
|
-
})
|
|
827
|
-
return graph.urlInfos[urlFound]
|
|
828
|
-
},
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
const injectVersionIntoBuildUrl = ({ buildUrl, version, versioning }) => {
|
|
832
|
-
if (versioning === "search_param") {
|
|
881
|
+
const injectVersionIntoBuildUrl = ({ buildUrl, version, versioningMethod }) => {
|
|
882
|
+
if (versioningMethod === "search_param") {
|
|
833
883
|
return injectQueryParams(buildUrl, {
|
|
834
884
|
v: version,
|
|
835
885
|
})
|
|
@@ -865,3 +915,16 @@ const assertEntryPoints = ({ entryPoints }) => {
|
|
|
865
915
|
}
|
|
866
916
|
})
|
|
867
917
|
}
|
|
918
|
+
|
|
919
|
+
const canUseVersionedUrl = (urlInfo) => {
|
|
920
|
+
if (urlInfo.data.isEntryPoint) {
|
|
921
|
+
return false
|
|
922
|
+
}
|
|
923
|
+
if (urlInfo.type === "webmanifest") {
|
|
924
|
+
return false
|
|
925
|
+
}
|
|
926
|
+
if (urlInfo.subtype === "service_worker") {
|
|
927
|
+
return !urlInfo.data.isWebWorkerEntryPoint
|
|
928
|
+
}
|
|
929
|
+
return true
|
|
930
|
+
}
|