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