@jsenv/core 27.0.0-alpha.83 → 27.0.0-alpha.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html/explorer.html +1 -1
- package/dist/js/event_source_client.js +3 -3
- package/dist/js/s.js +2 -2
- package/dist/main.js +503 -417
- package/dist/s.js +2 -2
- package/dist/s.js.map +2 -1
- package/package.json +7 -3
- package/src/build/build.js +5 -8
- package/src/build/build_urls_generator.js +1 -2
- package/src/build/inject_global_version_mappings.js +4 -4
- package/src/build/inject_service_worker_urls.js +2 -2
- package/src/build/resync_ressource_hints.js +17 -18
- package/src/build/start_build_server.js +5 -1
- package/src/build/version_generator.js +60 -0
- package/src/dev/plugins/explorer/client/explorer.html +1 -1
- package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -3
- package/src/dev/plugins/toolbar/client/util/fetching.js +1 -1
- package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -3
- package/src/dev/start_dev_server.js +5 -1
- package/src/execute/runtimes/browsers/from_playwright.js +2 -2
- package/src/execute/runtimes/node/node_process.js +2 -2
- package/src/helpers/command/command.js +73 -0
- package/src/helpers/worker_reload.js +4 -3
- package/src/omega/compat/runtime_compat.js +2 -1
- package/src/omega/kitchen.js +4 -1
- package/src/omega/server/user_agent.js +2 -1
- package/src/omega/url_graph/sort_by_dependencies.js +27 -0
- package/src/omega/url_graph/url_info_transformations.js +24 -14
- package/src/plugins/autoreload/dev_sse/client/reload.js +6 -3
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +3 -3
- package/src/plugins/bundling/css/bundle_css.js +4 -4
- package/src/plugins/bundling/js_module/bundle_js_module.js +86 -67
- package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -5
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +62 -74
- package/src/plugins/http_urls/jsenv_plugin_http_urls.js +10 -6
- package/src/plugins/import_meta_hot/html_hot_dependencies.js +9 -15
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +3 -3
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +2 -2
- package/src/plugins/importmap/jsenv_plugin_importmap.js +25 -27
- package/src/plugins/inject_globals/inject_globals.js +4 -4
- package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +41 -43
- package/src/plugins/inline/jsenv_plugin_js_inline_content.js +4 -4
- package/src/plugins/minification/css/minify_css.js +1 -1
- package/src/plugins/transpilation/as_js_classic/client/s.js +2 -2
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +2 -4
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +45 -67
- package/src/plugins/transpilation/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +2 -3
- package/src/plugins/transpilation/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +3 -4
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
- package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +2 -3
- package/src/plugins/transpilation/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +2 -3
- package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +1 -1
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
- package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +2 -1
- package/src/plugins/url_analysis/css/css_urls.js +2 -3
- package/src/plugins/url_analysis/html/html_urls.js +98 -113
- package/src/plugins/url_analysis/js/js_urls.js +3 -2
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +10 -6
- package/src/test/coverage/empty_coverage_factory.js +1 -1
- package/src/test/coverage/file_by_file_coverage.js +1 -2
package/dist/main.js
CHANGED
|
@@ -6,42 +6,30 @@ import { urlToRelativeUrl, generateInlineContentUrl, ensurePathnameTrailingSlash
|
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
7
|
import { workerData, Worker } from "node:worker_threads";
|
|
8
8
|
import { URL_META } from "@jsenv/url-meta";
|
|
9
|
-
import { parseHtmlString, stringifyHtmlAst,
|
|
10
|
-
import {
|
|
11
|
-
import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js";
|
|
12
|
-
import { applyPostCss } from "@jsenv/utils/css_ast/apply_post_css.js";
|
|
13
|
-
import { postCssPluginUrlVisitor } from "@jsenv/utils/css_ast/postcss_plugin_url_visitor.js";
|
|
14
|
-
import { parseJsUrls } from "@jsenv/utils/js_ast/parse_js_urls.js";
|
|
9
|
+
import { parseHtmlString, stringifyHtmlAst, visitHtmlNodes, getHtmlNodeAttribute, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, findHtmlNode, getHtmlNodeText, removeHtmlNode, setHtmlNodeText, analyzeScriptNode, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode } from "@jsenv/ast";
|
|
10
|
+
import { createMagicSource, composeTwoSourcemaps, sourcemapConverter, SOURCEMAP, generateSourcemapFileUrl, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
15
11
|
import { resolveImport, normalizeImportMap, composeTwoImportMaps } from "@jsenv/importmap";
|
|
16
12
|
import { applyNodeEsmResolution, defaultLookupPackageScope, defaultReadPackageJson, readCustomConditionsFromProcessArgs, applyFileSystemMagicResolution, getExtensionsToTry } from "@jsenv/node-esm-resolution";
|
|
17
13
|
import { statSync, realpathSync, readdirSync, readFileSync, existsSync } from "node:fs";
|
|
18
|
-
import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js";
|
|
19
|
-
import { JS_QUOTES } from "@jsenv/utils/string/js_quotes.js";
|
|
20
|
-
import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js";
|
|
21
|
-
import { transpileWithParcel, minifyWithParcel } from "@jsenv/utils/css_ast/parcel_css.js";
|
|
14
|
+
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
15
|
+
import { JS_QUOTES } from "@jsenv/utils/src/string/js_quotes.js";
|
|
22
16
|
import { createRequire } from "node:module";
|
|
23
|
-
import { composeTwoSourcemaps } from "@jsenv/utils/sourcemap/sourcemap_composition_v3.js";
|
|
24
17
|
import babelParser from "@babel/parser";
|
|
25
|
-
import { findHighestVersion } from "@jsenv/utils/semantic_versioning/highest_version.js";
|
|
26
|
-
import { injectImport } from "@jsenv/utils/js_ast/babel_utils.js";
|
|
27
|
-
import { sortByDependencies } from "@jsenv/utils/graph/sort_by_dependencies.js";
|
|
28
|
-
import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js";
|
|
29
|
-
import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js";
|
|
30
|
-
import { SOURCEMAP, generateSourcemapUrl, sourcemapToBase64Url } from "@jsenv/utils/sourcemap/sourcemap_utils.js";
|
|
18
|
+
import { findHighestVersion } from "@jsenv/utils/src/semantic_versioning/highest_version.js";
|
|
31
19
|
import { validateResponseIntegrity } from "@jsenv/integrity";
|
|
32
20
|
import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js";
|
|
33
|
-
import { memoizeByFirstArgument } from "@jsenv/utils/memoize/memoize_by_first_argument.js";
|
|
21
|
+
import { memoizeByFirstArgument } from "@jsenv/utils/src/memoize/memoize_by_first_argument.js";
|
|
34
22
|
import { memoryUsage } from "node:process";
|
|
35
23
|
import wrapAnsi from "wrap-ansi";
|
|
36
24
|
import stripAnsi from "strip-ansi";
|
|
37
25
|
import cuid from "cuid";
|
|
38
26
|
import v8 from "node:v8";
|
|
39
27
|
import { runInNewContext, Script } from "node:vm";
|
|
40
|
-
import { memoize } from "@jsenv/utils/memoize/memoize.js";
|
|
41
|
-
import { escapeRegexpSpecialChars } from "@jsenv/utils/string/escape_regexp_special_chars.js";
|
|
28
|
+
import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
|
|
29
|
+
import { escapeRegexpSpecialChars } from "@jsenv/utils/src/string/escape_regexp_special_chars.js";
|
|
42
30
|
import { fork } from "node:child_process";
|
|
43
31
|
import { uneval } from "@jsenv/uneval";
|
|
44
|
-
import {
|
|
32
|
+
import { createHash } from "node:crypto";
|
|
45
33
|
|
|
46
34
|
const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
47
35
|
const workerFilePath = fileURLToPath(workerFileUrl);
|
|
@@ -75,12 +63,13 @@ const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
|
75
63
|
worker.once("error", error => {
|
|
76
64
|
console.error(error);
|
|
77
65
|
});
|
|
78
|
-
worker.once("exit", () => {
|
|
79
|
-
worker = null;
|
|
80
|
-
});
|
|
81
66
|
await new Promise(resolve => {
|
|
82
67
|
worker.once("online", resolve);
|
|
83
68
|
});
|
|
69
|
+
worker.once("exit", () => {
|
|
70
|
+
worker = null;
|
|
71
|
+
});
|
|
72
|
+
return worker;
|
|
84
73
|
};
|
|
85
74
|
|
|
86
75
|
const reload = async () => {
|
|
@@ -118,9 +107,14 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
118
107
|
column,
|
|
119
108
|
originalLine,
|
|
120
109
|
originalColumn,
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
node,
|
|
111
|
+
attributeName,
|
|
112
|
+
specifier
|
|
123
113
|
}) => {
|
|
114
|
+
const {
|
|
115
|
+
crossorigin,
|
|
116
|
+
integrity
|
|
117
|
+
} = readFetchMetas(node);
|
|
124
118
|
const isRessourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(subtype);
|
|
125
119
|
const [reference] = referenceUtils.found({
|
|
126
120
|
type,
|
|
@@ -130,10 +124,14 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
130
124
|
specifier,
|
|
131
125
|
specifierLine: line,
|
|
132
126
|
specifierColumn: column,
|
|
133
|
-
isRessourceHint
|
|
127
|
+
isRessourceHint,
|
|
128
|
+
crossorigin,
|
|
129
|
+
integrity
|
|
134
130
|
});
|
|
135
131
|
actions.push(async () => {
|
|
136
|
-
|
|
132
|
+
setHtmlNodeAttributes(node, {
|
|
133
|
+
[attributeName]: await referenceUtils.readGeneratedSpecifier(reference)
|
|
134
|
+
});
|
|
137
135
|
});
|
|
138
136
|
}
|
|
139
137
|
});
|
|
@@ -147,6 +145,24 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
|
|
|
147
145
|
content: stringifyHtmlAst(htmlAst)
|
|
148
146
|
};
|
|
149
147
|
};
|
|
148
|
+
const crossOriginCompatibleTagNames = ["script", "link", "img", "source"];
|
|
149
|
+
const integrityCompatibleTagNames = ["script", "link", "img", "source"];
|
|
150
|
+
|
|
151
|
+
const readFetchMetas = node => {
|
|
152
|
+
const meta = {};
|
|
153
|
+
|
|
154
|
+
if (crossOriginCompatibleTagNames.includes(node.nodeName)) {
|
|
155
|
+
const crossorigin = getHtmlNodeAttribute(node, "crossorigin") !== undefined;
|
|
156
|
+
meta.crossorigin = crossorigin;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (integrityCompatibleTagNames.includes(node.nodeName)) {
|
|
160
|
+
const integrity = getHtmlNodeAttribute(node, "integrity");
|
|
161
|
+
meta.integrity = integrity;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return meta;
|
|
165
|
+
};
|
|
150
166
|
|
|
151
167
|
const visitHtmlUrls = ({
|
|
152
168
|
url,
|
|
@@ -158,18 +174,18 @@ const visitHtmlUrls = ({
|
|
|
158
174
|
subtype,
|
|
159
175
|
expectedType,
|
|
160
176
|
node,
|
|
161
|
-
|
|
177
|
+
attributeName,
|
|
162
178
|
specifier
|
|
163
179
|
}) => {
|
|
164
|
-
const generatedFromInlineContent =
|
|
180
|
+
const generatedFromInlineContent = getHtmlNodeAttribute(node, "generated-from-inline-content") !== undefined;
|
|
165
181
|
let position;
|
|
166
182
|
|
|
167
183
|
if (generatedFromInlineContent) {
|
|
168
184
|
// when generated from inline content,
|
|
169
185
|
// line, column is not "src" nor "generated-from-src" but "original-position"
|
|
170
|
-
position =
|
|
186
|
+
position = getHtmlNodePosition(node);
|
|
171
187
|
} else {
|
|
172
|
-
position =
|
|
188
|
+
position = getHtmlNodeAttributePosition(node, attributeName);
|
|
173
189
|
}
|
|
174
190
|
|
|
175
191
|
const {
|
|
@@ -185,19 +201,68 @@ const visitHtmlUrls = ({
|
|
|
185
201
|
column,
|
|
186
202
|
// originalLine, originalColumn
|
|
187
203
|
specifier,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// srcGeneratedFromInlineContent
|
|
191
|
-
...readFetchMetas(node)
|
|
204
|
+
node,
|
|
205
|
+
attributeName
|
|
192
206
|
});
|
|
193
207
|
};
|
|
194
208
|
|
|
195
|
-
const
|
|
209
|
+
const visitAttributeAsUrlSpecifier = ({
|
|
210
|
+
node,
|
|
211
|
+
attributeName,
|
|
212
|
+
...rest
|
|
213
|
+
}) => {
|
|
214
|
+
const value = getHtmlNodeAttribute(node, attributeName);
|
|
215
|
+
|
|
216
|
+
if (value) {
|
|
217
|
+
const generatedBy = getHtmlNodeAttribute(node, "generated-by");
|
|
218
|
+
|
|
219
|
+
if (generatedBy !== undefined) {
|
|
220
|
+
// during build the importmap is inlined
|
|
221
|
+
// and shoud not be considered as a dependency anymore
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
addDependency({ ...rest,
|
|
226
|
+
node,
|
|
227
|
+
attributeName,
|
|
228
|
+
specifier: attributeName === "generated-from-src" || attributeName === "generated-from-href" ? new URL(value, url).href : value
|
|
229
|
+
});
|
|
230
|
+
} else if (attributeName === "src") {
|
|
231
|
+
visitAttributeAsUrlSpecifier({ ...rest,
|
|
232
|
+
node,
|
|
233
|
+
attributeName: "generated-from-src"
|
|
234
|
+
});
|
|
235
|
+
} else if (attributeName === "href") {
|
|
236
|
+
visitAttributeAsUrlSpecifier({ ...rest,
|
|
237
|
+
node,
|
|
238
|
+
attributeName: "generated-from-href"
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const visitSrcset = ({
|
|
244
|
+
type,
|
|
245
|
+
node
|
|
246
|
+
}) => {
|
|
247
|
+
const srcset = getHtmlNodeAttribute(node, "srcset");
|
|
248
|
+
|
|
249
|
+
if (srcset) {
|
|
250
|
+
const srcCandidates = parseSrcSet(srcset);
|
|
251
|
+
srcCandidates.forEach(srcCandidate => {
|
|
252
|
+
addDependency({
|
|
253
|
+
type,
|
|
254
|
+
node,
|
|
255
|
+
attributeName: "srcset",
|
|
256
|
+
specifier: srcCandidate.specifier
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
visitHtmlNodes(htmlAst, {
|
|
196
263
|
link: node => {
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
const typeAttribute = getHtmlNodeAttributeByName(node, "type");
|
|
200
|
-
const type = typeAttribute ? typeAttribute.value : undefined;
|
|
264
|
+
const rel = getHtmlNodeAttribute(node, "rel");
|
|
265
|
+
const type = getHtmlNodeAttribute(node, "type");
|
|
201
266
|
visitAttributeAsUrlSpecifier({
|
|
202
267
|
type: "link_href",
|
|
203
268
|
subtype: rel,
|
|
@@ -213,15 +278,16 @@ const visitHtmlUrls = ({
|
|
|
213
278
|
},
|
|
214
279
|
// style: () => {},
|
|
215
280
|
script: node => {
|
|
216
|
-
const
|
|
281
|
+
const type = getHtmlNodeAttribute(node, "type");
|
|
282
|
+
const expectedType = {
|
|
283
|
+
"undefined": "js_classic",
|
|
284
|
+
"text/javascript": "js_classic",
|
|
285
|
+
"module": "js_module",
|
|
286
|
+
"importmap": "importmap"
|
|
287
|
+
}[type];
|
|
217
288
|
visitAttributeAsUrlSpecifier({
|
|
218
289
|
type: "script_src",
|
|
219
|
-
expectedType
|
|
220
|
-
"undefined": "js_classic",
|
|
221
|
-
"text/javascript": "js_classic",
|
|
222
|
-
"module": "js_module",
|
|
223
|
-
"importmap": "importmap"
|
|
224
|
-
}[typeAttributeNode ? typeAttributeNode.value : undefined],
|
|
290
|
+
expectedType,
|
|
225
291
|
node,
|
|
226
292
|
attributeName: "src"
|
|
227
293
|
});
|
|
@@ -277,102 +343,9 @@ const visitHtmlUrls = ({
|
|
|
277
343
|
attributeName: "href"
|
|
278
344
|
});
|
|
279
345
|
}
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
const visitAttributeAsUrlSpecifier = ({
|
|
283
|
-
type,
|
|
284
|
-
subtype,
|
|
285
|
-
expectedType,
|
|
286
|
-
node,
|
|
287
|
-
attributeName
|
|
288
|
-
}) => {
|
|
289
|
-
const attribute = getHtmlNodeAttributeByName(node, attributeName);
|
|
290
|
-
const value = attribute ? attribute.value : undefined;
|
|
291
|
-
|
|
292
|
-
if (value) {
|
|
293
|
-
const generatedBy = getHtmlNodeAttributeByName(node, "generated-by");
|
|
294
|
-
|
|
295
|
-
if (generatedBy) {
|
|
296
|
-
// during build the importmap is inlined
|
|
297
|
-
// and shoud not be considered as a dependency anymore
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
addDependency({
|
|
302
|
-
type,
|
|
303
|
-
subtype,
|
|
304
|
-
expectedType,
|
|
305
|
-
node,
|
|
306
|
-
attribute,
|
|
307
|
-
specifier: attributeName === "generated-from-src" || attributeName === "generated-from-href" ? new URL(value, url).href : value
|
|
308
|
-
});
|
|
309
|
-
} else if (attributeName === "src") {
|
|
310
|
-
visitAttributeAsUrlSpecifier({
|
|
311
|
-
type,
|
|
312
|
-
subtype,
|
|
313
|
-
expectedType,
|
|
314
|
-
node,
|
|
315
|
-
attributeName: "generated-from-src"
|
|
316
|
-
});
|
|
317
|
-
} else if (attributeName === "href") {
|
|
318
|
-
visitAttributeAsUrlSpecifier({
|
|
319
|
-
type,
|
|
320
|
-
subtype,
|
|
321
|
-
expectedType,
|
|
322
|
-
node,
|
|
323
|
-
attributeName: "generated-from-href"
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const visitSrcset = ({
|
|
329
|
-
type,
|
|
330
|
-
node
|
|
331
|
-
}) => {
|
|
332
|
-
const srcsetAttribute = getHtmlNodeAttributeByName(node, "srcset");
|
|
333
|
-
const srcset = srcsetAttribute ? srcsetAttribute.value : undefined;
|
|
334
|
-
|
|
335
|
-
if (srcset) {
|
|
336
|
-
const srcCandidates = htmlAttributeSrcSet.parse(srcset);
|
|
337
|
-
srcCandidates.forEach(srcCandidate => {
|
|
338
|
-
addDependency({
|
|
339
|
-
type,
|
|
340
|
-
node,
|
|
341
|
-
attribute: srcsetAttribute,
|
|
342
|
-
specifier: srcCandidate.specifier
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
visitHtmlAst(htmlAst, node => {
|
|
349
|
-
const visitor = visitors[node.nodeName];
|
|
350
|
-
|
|
351
|
-
if (visitor) {
|
|
352
|
-
visitor(node);
|
|
353
|
-
}
|
|
354
346
|
});
|
|
355
347
|
};
|
|
356
348
|
|
|
357
|
-
const crossOriginCompatibleTagNames = ["script", "link", "img", "source"];
|
|
358
|
-
const integrityCompatibleTagNames = ["script", "link", "img", "source"];
|
|
359
|
-
|
|
360
|
-
const readFetchMetas = node => {
|
|
361
|
-
const meta = {};
|
|
362
|
-
|
|
363
|
-
if (crossOriginCompatibleTagNames.includes(node.nodeName)) {
|
|
364
|
-
const crossoriginAttribute = getHtmlNodeAttributeByName(node, "crossorigin");
|
|
365
|
-
meta.crossorigin = crossoriginAttribute ? crossoriginAttribute.value : undefined;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (integrityCompatibleTagNames.includes(node.nodeName)) {
|
|
369
|
-
const integrityAttribute = getHtmlNodeAttributeByName(node, "integrity");
|
|
370
|
-
meta.integrity = integrityAttribute ? integrityAttribute.value : undefined;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return meta;
|
|
374
|
-
};
|
|
375
|
-
|
|
376
349
|
/*
|
|
377
350
|
* https://github.com/parcel-bundler/parcel/blob/v2/packages/transformers/css/src/CSSTransformer.js
|
|
378
351
|
*/
|
|
@@ -547,7 +520,8 @@ const parseAndTransformWebmanifestUrls = async (urlInfo, context) => {
|
|
|
547
520
|
|
|
548
521
|
const jsenvPluginUrlAnalysis = ({
|
|
549
522
|
rootDirectoryUrl,
|
|
550
|
-
include
|
|
523
|
+
include,
|
|
524
|
+
supportedProtocols = ["file:", "data:", "virtual:", "http:", "https:"]
|
|
551
525
|
}) => {
|
|
552
526
|
let getIncludeInfo = () => undefined;
|
|
553
527
|
|
|
@@ -592,12 +566,12 @@ const jsenvPluginUrlAnalysis = ({
|
|
|
592
566
|
return;
|
|
593
567
|
}
|
|
594
568
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
569
|
+
const {
|
|
570
|
+
protocol
|
|
571
|
+
} = new URL(reference.url);
|
|
572
|
+
const protocolIsSupported = supportedProtocols.some(supportedProtocol => protocol === supportedProtocol);
|
|
599
573
|
|
|
600
|
-
if (
|
|
574
|
+
if (protocolIsSupported) {
|
|
601
575
|
reference.shouldHandle = true;
|
|
602
576
|
return;
|
|
603
577
|
}
|
|
@@ -748,14 +722,14 @@ const jsenvPluginImportmap = () => {
|
|
|
748
722
|
transformUrlContent: {
|
|
749
723
|
html: async (htmlUrlInfo, context) => {
|
|
750
724
|
const htmlAst = parseHtmlString(htmlUrlInfo.content);
|
|
751
|
-
const importmap =
|
|
725
|
+
const importmap = findHtmlNode(htmlAst, node => {
|
|
752
726
|
if (node.nodeName !== "script") {
|
|
753
727
|
return false;
|
|
754
728
|
}
|
|
755
729
|
|
|
756
|
-
const
|
|
730
|
+
const type = getHtmlNodeAttribute(node, "type");
|
|
757
731
|
|
|
758
|
-
if (
|
|
732
|
+
if (type === undefined || type !== "importmap") {
|
|
759
733
|
return false;
|
|
760
734
|
}
|
|
761
735
|
|
|
@@ -774,7 +748,7 @@ const jsenvPluginImportmap = () => {
|
|
|
774
748
|
lineEnd,
|
|
775
749
|
columnEnd,
|
|
776
750
|
isOriginal
|
|
777
|
-
} =
|
|
751
|
+
} = getHtmlNodePosition(importmap, {
|
|
778
752
|
preferOriginal: true
|
|
779
753
|
});
|
|
780
754
|
const inlineImportmapUrl = generateInlineContentUrl({
|
|
@@ -797,9 +771,9 @@ const jsenvPluginImportmap = () => {
|
|
|
797
771
|
await context.cook(inlineImportmapUrlInfo, {
|
|
798
772
|
reference: inlineImportmapReference
|
|
799
773
|
});
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
774
|
+
setHtmlNodeText(importmap, inlineImportmapUrlInfo.content);
|
|
775
|
+
setHtmlNodeAttributes(importmap, {
|
|
776
|
+
"generated-by": "jsenv:importmap"
|
|
803
777
|
});
|
|
804
778
|
onHtmlImportmapParsed(JSON.parse(inlineImportmapUrlInfo.content), htmlUrlInfo.url);
|
|
805
779
|
};
|
|
@@ -816,11 +790,11 @@ const jsenvPluginImportmap = () => {
|
|
|
816
790
|
reference: importmapReference
|
|
817
791
|
});
|
|
818
792
|
onHtmlImportmapParsed(JSON.parse(importmapUrlInfo.content), htmlUrlInfo.url);
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
793
|
+
setHtmlNodeText(importmap, importmapUrlInfo.content);
|
|
794
|
+
setHtmlNodeAttributes(importmap, {
|
|
795
|
+
"src": undefined,
|
|
796
|
+
"generated-by": "jsenv:importmap",
|
|
797
|
+
"generated-from-src": src
|
|
824
798
|
});
|
|
825
799
|
const {
|
|
826
800
|
line,
|
|
@@ -828,7 +802,7 @@ const jsenvPluginImportmap = () => {
|
|
|
828
802
|
lineEnd,
|
|
829
803
|
columnEnd,
|
|
830
804
|
isOriginal
|
|
831
|
-
} =
|
|
805
|
+
} = getHtmlNodePosition(importmap, {
|
|
832
806
|
preferOriginal: true
|
|
833
807
|
});
|
|
834
808
|
const inlineImportmapUrl = generateInlineContentUrl({
|
|
@@ -849,16 +823,15 @@ const jsenvPluginImportmap = () => {
|
|
|
849
823
|
});
|
|
850
824
|
};
|
|
851
825
|
|
|
852
|
-
const
|
|
853
|
-
const src = srcAttribute ? srcAttribute.value : undefined;
|
|
826
|
+
const src = getHtmlNodeAttribute(importmap, "src");
|
|
854
827
|
|
|
855
828
|
if (src) {
|
|
856
829
|
await handleImportmapWithSrc(importmap, src);
|
|
857
830
|
} else {
|
|
858
|
-
const
|
|
831
|
+
const htmlNodeText = getHtmlNodeText(importmap);
|
|
859
832
|
|
|
860
|
-
if (
|
|
861
|
-
await handleInlineImportmap(importmap,
|
|
833
|
+
if (htmlNodeText) {
|
|
834
|
+
await handleInlineImportmap(importmap, htmlNodeText);
|
|
862
835
|
}
|
|
863
836
|
} // once this plugin knows the importmap, it will use it
|
|
864
837
|
// to map imports. These import specifiers will be normalized
|
|
@@ -1107,7 +1080,7 @@ const jsenvPluginUrlVersion = () => {
|
|
|
1107
1080
|
const jsenvPluginFileUrls = ({
|
|
1108
1081
|
magicExtensions = ["inherit", ".js"],
|
|
1109
1082
|
magicDirectoryIndex = true,
|
|
1110
|
-
|
|
1083
|
+
preserveSymlinks = false,
|
|
1111
1084
|
directoryReferenceAllowed = false
|
|
1112
1085
|
}) => {
|
|
1113
1086
|
return [{
|
|
@@ -1162,7 +1135,7 @@ const jsenvPluginFileUrls = ({
|
|
|
1162
1135
|
if (foundADirectory && directoryReferenceAllowed) {
|
|
1163
1136
|
reference.data.foundADirectory = true;
|
|
1164
1137
|
const directoryFacadeUrl = urlObject.href;
|
|
1165
|
-
const directoryUrlRaw =
|
|
1138
|
+
const directoryUrlRaw = preserveSymlinks ? directoryFacadeUrl : resolveSymlink(directoryFacadeUrl);
|
|
1166
1139
|
const directoryUrl = `${directoryUrlRaw}${search}${hash}`;
|
|
1167
1140
|
return directoryUrl;
|
|
1168
1141
|
}
|
|
@@ -1181,7 +1154,7 @@ const jsenvPluginFileUrls = ({
|
|
|
1181
1154
|
|
|
1182
1155
|
reference.data.foundADirectory = filesystemResolution.isDirectory;
|
|
1183
1156
|
const fileFacadeUrl = filesystemResolution.url;
|
|
1184
|
-
const fileUrlRaw =
|
|
1157
|
+
const fileUrlRaw = preserveSymlinks ? fileFacadeUrl : resolveSymlink(fileFacadeUrl);
|
|
1185
1158
|
const fileUrl = `${fileUrlRaw}${search}${hash}`;
|
|
1186
1159
|
return fileUrl;
|
|
1187
1160
|
}
|
|
@@ -1279,13 +1252,14 @@ const resolveSymlink = fileUrl => {
|
|
|
1279
1252
|
const jsenvPluginHttpUrls = () => {
|
|
1280
1253
|
return {
|
|
1281
1254
|
name: "jsenv:http_urls",
|
|
1282
|
-
appliesDuring: "*"
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1255
|
+
appliesDuring: "*",
|
|
1256
|
+
redirectUrl: reference => {
|
|
1257
|
+
if (reference.url.startsWith("http:") || reference.url.startsWith("https:")) {
|
|
1258
|
+
reference.shouldHandle = false;
|
|
1259
|
+
} // TODO: according to some pattern matching jsenv could be allowed
|
|
1260
|
+
// to fetch and transform http urls
|
|
1288
1261
|
|
|
1262
|
+
}
|
|
1289
1263
|
};
|
|
1290
1264
|
};
|
|
1291
1265
|
|
|
@@ -1301,13 +1275,9 @@ const jsenvPluginHtmlInlineContent = ({
|
|
|
1301
1275
|
const actions = [];
|
|
1302
1276
|
|
|
1303
1277
|
const handleInlineStyle = node => {
|
|
1304
|
-
|
|
1305
|
-
return;
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
const textNode = getHtmlNodeTextNode(node);
|
|
1278
|
+
const htmlNodeText = getHtmlNodeText(node);
|
|
1309
1279
|
|
|
1310
|
-
if (!
|
|
1280
|
+
if (!htmlNodeText) {
|
|
1311
1281
|
return;
|
|
1312
1282
|
}
|
|
1313
1283
|
|
|
@@ -1318,7 +1288,7 @@ const jsenvPluginHtmlInlineContent = ({
|
|
|
1318
1288
|
lineEnd,
|
|
1319
1289
|
columnEnd,
|
|
1320
1290
|
isOriginal
|
|
1321
|
-
} =
|
|
1291
|
+
} = getHtmlNodePosition(node, {
|
|
1322
1292
|
preferOriginal: true
|
|
1323
1293
|
});
|
|
1324
1294
|
const inlineStyleUrl = generateInlineContentUrl({
|
|
@@ -1340,55 +1310,47 @@ const jsenvPluginHtmlInlineContent = ({
|
|
|
1340
1310
|
specifierColumn: column,
|
|
1341
1311
|
specifier: inlineStyleUrl,
|
|
1342
1312
|
contentType: "text/css",
|
|
1343
|
-
content:
|
|
1313
|
+
content: htmlNodeText
|
|
1344
1314
|
});
|
|
1345
1315
|
await context.cook(inlineStyleUrlInfo, {
|
|
1346
1316
|
reference: inlineStyleReference
|
|
1347
1317
|
});
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1318
|
+
setHtmlNodeText(node, inlineStyleUrlInfo.content);
|
|
1319
|
+
setHtmlNodeAttributes(node, {
|
|
1320
|
+
"generated-by": "jsenv:html_inline_content"
|
|
1351
1321
|
});
|
|
1352
1322
|
});
|
|
1353
1323
|
};
|
|
1354
1324
|
|
|
1355
1325
|
const handleInlineScript = node => {
|
|
1356
|
-
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
const textNode = getHtmlNodeTextNode(node);
|
|
1326
|
+
const htmlNodeText = getHtmlNodeText(node);
|
|
1361
1327
|
|
|
1362
|
-
if (!
|
|
1328
|
+
if (!htmlNodeText) {
|
|
1363
1329
|
return;
|
|
1364
1330
|
} // If the inline script was already handled by an other plugin, ignore it
|
|
1365
1331
|
// - we want to preserve inline scripts generated by html supervisor during dev
|
|
1366
1332
|
// - we want to avoid cooking twice a script during build
|
|
1367
1333
|
|
|
1368
1334
|
|
|
1369
|
-
const generatedBy =
|
|
1335
|
+
const generatedBy = getHtmlNodeAttribute(node, "generated-by");
|
|
1370
1336
|
|
|
1371
|
-
if (generatedBy) {
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1337
|
+
if (generatedBy === "jsenv:as_js_classic_html" && !analyzeConvertedScripts) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1377
1340
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
}
|
|
1341
|
+
if (generatedBy === "jsenv:html_supervisor") {
|
|
1342
|
+
return;
|
|
1381
1343
|
}
|
|
1382
1344
|
|
|
1383
1345
|
actions.push(async () => {
|
|
1384
|
-
const scriptCategory =
|
|
1346
|
+
const scriptCategory = analyzeScriptNode(node);
|
|
1385
1347
|
const {
|
|
1386
1348
|
line,
|
|
1387
1349
|
column,
|
|
1388
1350
|
lineEnd,
|
|
1389
1351
|
columnEnd,
|
|
1390
1352
|
isOriginal
|
|
1391
|
-
} =
|
|
1353
|
+
} = getHtmlNodePosition(node, {
|
|
1392
1354
|
preferOriginal: true
|
|
1393
1355
|
}); // from MDN about [type] attribute:
|
|
1394
1356
|
// "Any other value: The embedded content is treated as a data block
|
|
@@ -1424,21 +1386,25 @@ const jsenvPluginHtmlInlineContent = ({
|
|
|
1424
1386
|
isOriginalPosition: isOriginal,
|
|
1425
1387
|
specifier: inlineScriptUrl,
|
|
1426
1388
|
contentType,
|
|
1427
|
-
content:
|
|
1389
|
+
content: htmlNodeText
|
|
1428
1390
|
});
|
|
1429
1391
|
await context.cook(inlineScriptUrlInfo, {
|
|
1430
1392
|
reference: inlineScriptReference
|
|
1431
1393
|
});
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1394
|
+
setHtmlNodeText(node, inlineScriptUrlInfo.content);
|
|
1395
|
+
setHtmlNodeAttributes(node, {
|
|
1396
|
+
"generated-by": "jsenv:html_inline_content"
|
|
1435
1397
|
});
|
|
1436
1398
|
});
|
|
1437
1399
|
};
|
|
1438
1400
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1401
|
+
visitHtmlNodes(htmlAst, {
|
|
1402
|
+
style: node => {
|
|
1403
|
+
handleInlineStyle(node);
|
|
1404
|
+
},
|
|
1405
|
+
script: node => {
|
|
1406
|
+
handleInlineScript(node);
|
|
1407
|
+
}
|
|
1442
1408
|
});
|
|
1443
1409
|
|
|
1444
1410
|
if (actions.length === 0) {
|
|
@@ -1978,15 +1944,15 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
1978
1944
|
const htmlAst = parseHtmlString(content);
|
|
1979
1945
|
const scriptsToSupervise = [];
|
|
1980
1946
|
|
|
1981
|
-
const handleInlineScript = (node,
|
|
1982
|
-
const scriptCategory =
|
|
1947
|
+
const handleInlineScript = (node, htmlNodeText) => {
|
|
1948
|
+
const scriptCategory = analyzeScriptNode(node);
|
|
1983
1949
|
const {
|
|
1984
1950
|
line,
|
|
1985
1951
|
column,
|
|
1986
1952
|
lineEnd,
|
|
1987
1953
|
columnEnd,
|
|
1988
1954
|
isOriginal
|
|
1989
|
-
} =
|
|
1955
|
+
} = getHtmlNodePosition(node, {
|
|
1990
1956
|
preferOriginal: true
|
|
1991
1957
|
});
|
|
1992
1958
|
let inlineScriptUrl = generateInlineContentUrl({
|
|
@@ -2008,7 +1974,7 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2008
1974
|
specifierColumn: column,
|
|
2009
1975
|
specifier: inlineScriptUrl,
|
|
2010
1976
|
contentType: "text/javascript",
|
|
2011
|
-
content:
|
|
1977
|
+
content: htmlNodeText
|
|
2012
1978
|
});
|
|
2013
1979
|
removeHtmlNodeText(node);
|
|
2014
1980
|
scriptsToSupervise.push({
|
|
@@ -2019,21 +1985,19 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2019
1985
|
});
|
|
2020
1986
|
};
|
|
2021
1987
|
|
|
2022
|
-
const handleScriptWithSrc = (node,
|
|
2023
|
-
const scriptCategory =
|
|
2024
|
-
const
|
|
2025
|
-
const
|
|
2026
|
-
const
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
const async = asyncAttribute ? asyncAttribute.value : undefined;
|
|
2032
|
-
removeHtmlNodeAttributeByName(node, "src");
|
|
1988
|
+
const handleScriptWithSrc = (node, src) => {
|
|
1989
|
+
const scriptCategory = analyzeScriptNode(node);
|
|
1990
|
+
const integrity = getHtmlNodeAttribute(node, "integrity");
|
|
1991
|
+
const crossorigin = getHtmlNodeAttribute(node, "crossorigin") !== undefined;
|
|
1992
|
+
const defer = getHtmlNodeAttribute(node, "defer") !== undefined;
|
|
1993
|
+
const async = getHtmlNodeAttribute(node, "async") !== undefined;
|
|
1994
|
+
setHtmlNodeAttributes(node, {
|
|
1995
|
+
src: undefined
|
|
1996
|
+
});
|
|
2033
1997
|
scriptsToSupervise.push({
|
|
2034
1998
|
node,
|
|
2035
1999
|
type: scriptCategory,
|
|
2036
|
-
src
|
|
2000
|
+
src,
|
|
2037
2001
|
defer,
|
|
2038
2002
|
async,
|
|
2039
2003
|
integrity,
|
|
@@ -2041,41 +2005,39 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2041
2005
|
});
|
|
2042
2006
|
};
|
|
2043
2007
|
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
}
|
|
2048
|
-
|
|
2049
|
-
const scriptCategory = parseScriptNode(node);
|
|
2008
|
+
visitHtmlNodes(htmlAst, {
|
|
2009
|
+
script: node => {
|
|
2010
|
+
const scriptCategory = analyzeScriptNode(node);
|
|
2050
2011
|
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2012
|
+
if (scriptCategory !== "classic" && scriptCategory !== "module") {
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2054
2015
|
|
|
2055
|
-
|
|
2016
|
+
const injectedBy = getHtmlNodeAttribute(node, "injected-by");
|
|
2056
2017
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2018
|
+
if (injectedBy !== undefined) {
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2060
2021
|
|
|
2061
|
-
|
|
2022
|
+
const noHtmlSupervisor = getHtmlNodeAttribute(node, "no-html-supervisor");
|
|
2062
2023
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2024
|
+
if (noHtmlSupervisor !== undefined) {
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
2066
2027
|
|
|
2067
|
-
|
|
2028
|
+
const htmlNodeText = getHtmlNodeText(node);
|
|
2068
2029
|
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2030
|
+
if (htmlNodeText) {
|
|
2031
|
+
handleInlineScript(node, htmlNodeText);
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
2073
2034
|
|
|
2074
|
-
|
|
2035
|
+
const src = getHtmlNodeAttribute(node, "src");
|
|
2075
2036
|
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2037
|
+
if (src) {
|
|
2038
|
+
handleScriptWithSrc(node, src);
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2079
2041
|
}
|
|
2080
2042
|
});
|
|
2081
2043
|
const [htmlSupervisorInstallerFileReference] = referenceUtils.inject({
|
|
@@ -2083,7 +2045,7 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2083
2045
|
expectedType: "js_module",
|
|
2084
2046
|
specifier: htmlSupervisorInstallerFileUrl
|
|
2085
2047
|
});
|
|
2086
|
-
|
|
2048
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
2087
2049
|
"tagName": "script",
|
|
2088
2050
|
"type": "module",
|
|
2089
2051
|
"textContent": `
|
|
@@ -2099,7 +2061,7 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2099
2061
|
expectedType: "js_classic",
|
|
2100
2062
|
specifier: htmlSupervisorSetupFileUrl
|
|
2101
2063
|
});
|
|
2102
|
-
|
|
2064
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
2103
2065
|
"tagName": "script",
|
|
2104
2066
|
"src": htmlSupervisorSetupFileReference.generatedSpecifier,
|
|
2105
2067
|
"injected-by": "jsenv:html_supervisor"
|
|
@@ -2114,20 +2076,24 @@ const jsenvPluginHtmlSupervisor = ({
|
|
|
2114
2076
|
integrity,
|
|
2115
2077
|
crossorigin
|
|
2116
2078
|
}) => {
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2079
|
+
setHtmlNodeText(node, generateCodeToSuperviseScript({
|
|
2080
|
+
type,
|
|
2081
|
+
src,
|
|
2082
|
+
isInline,
|
|
2083
|
+
defer,
|
|
2084
|
+
async,
|
|
2085
|
+
integrity,
|
|
2086
|
+
crossorigin,
|
|
2087
|
+
htmlSupervisorInstallerSpecifier: htmlSupervisorInstallerFileReference.generatedSpecifier
|
|
2088
|
+
}));
|
|
2089
|
+
setHtmlNodeAttributes(node, {
|
|
2090
|
+
"generated-by": "jsenv:html_supervisor",
|
|
2091
|
+
...(src ? {
|
|
2092
|
+
"generated-from-src": src
|
|
2093
|
+
} : {}),
|
|
2094
|
+
...(isInline ? {
|
|
2095
|
+
"generated-from-inline-content": ""
|
|
2096
|
+
} : {})
|
|
2131
2097
|
});
|
|
2132
2098
|
});
|
|
2133
2099
|
const htmlModified = stringifyHtmlAst(htmlAst);
|
|
@@ -2742,12 +2708,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2742
2708
|
const classicScriptNodes = [];
|
|
2743
2709
|
|
|
2744
2710
|
const visitLinkNodes = node => {
|
|
2745
|
-
|
|
2746
|
-
return;
|
|
2747
|
-
}
|
|
2748
|
-
|
|
2749
|
-
const relAttribute = getHtmlNodeAttributeByName(node, "rel");
|
|
2750
|
-
const rel = relAttribute ? relAttribute.value : undefined;
|
|
2711
|
+
const rel = getHtmlNodeAttribute(node, "rel");
|
|
2751
2712
|
|
|
2752
2713
|
if (rel === "modulepreload") {
|
|
2753
2714
|
modulePreloadNodes.push(node);
|
|
@@ -2755,8 +2716,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2755
2716
|
}
|
|
2756
2717
|
|
|
2757
2718
|
if (rel === "preload") {
|
|
2758
|
-
const
|
|
2759
|
-
const asValue = asAttribute ? asAttribute.value : undefined;
|
|
2719
|
+
const asValue = getHtmlNodeAttribute(node, "as");
|
|
2760
2720
|
|
|
2761
2721
|
if (asValue === "script") {
|
|
2762
2722
|
preloadAsScriptNodes.push(node);
|
|
@@ -2767,12 +2727,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2767
2727
|
};
|
|
2768
2728
|
|
|
2769
2729
|
const visitScriptNodes = node => {
|
|
2770
|
-
|
|
2771
|
-
return;
|
|
2772
|
-
}
|
|
2773
|
-
|
|
2774
|
-
const typeAttribute = getHtmlNodeAttributeByName(node, "type");
|
|
2775
|
-
const type = typeAttribute ? typeAttribute.value : undefined;
|
|
2730
|
+
const type = getHtmlNodeAttribute(node, "type");
|
|
2776
2731
|
|
|
2777
2732
|
if (type === "module") {
|
|
2778
2733
|
moduleScriptNodes.push(node);
|
|
@@ -2785,9 +2740,13 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2785
2740
|
}
|
|
2786
2741
|
};
|
|
2787
2742
|
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2743
|
+
visitHtmlNodes(htmlAst, {
|
|
2744
|
+
link: node => {
|
|
2745
|
+
visitLinkNodes(node);
|
|
2746
|
+
},
|
|
2747
|
+
script: node => {
|
|
2748
|
+
visitScriptNodes(node);
|
|
2749
|
+
}
|
|
2791
2750
|
});
|
|
2792
2751
|
const actions = [];
|
|
2793
2752
|
const jsModuleUrls = [];
|
|
@@ -2829,10 +2788,10 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2829
2788
|
};
|
|
2830
2789
|
|
|
2831
2790
|
classicScriptNodes.forEach(classicScriptNode => {
|
|
2832
|
-
const
|
|
2791
|
+
const src = getHtmlNodeAttribute(classicScriptNode, "src");
|
|
2833
2792
|
|
|
2834
|
-
if (
|
|
2835
|
-
const reference = urlInfo.references.find(ref => ref.generatedSpecifier ===
|
|
2793
|
+
if (src !== undefined) {
|
|
2794
|
+
const reference = urlInfo.references.find(ref => ref.generatedSpecifier === src && ref.type === "script_src");
|
|
2836
2795
|
const urlObject = new URL(reference.url);
|
|
2837
2796
|
|
|
2838
2797
|
if (urlObject.searchParams.has("as_js_classic")) {
|
|
@@ -2851,10 +2810,10 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2851
2810
|
}
|
|
2852
2811
|
});
|
|
2853
2812
|
moduleScriptNodes.forEach(moduleScriptNode => {
|
|
2854
|
-
const
|
|
2813
|
+
const src = getHtmlNodeAttribute(moduleScriptNode, "src");
|
|
2855
2814
|
|
|
2856
|
-
if (
|
|
2857
|
-
const reference = urlInfo.references.find(ref => ref.generatedSpecifier ===
|
|
2815
|
+
if (src !== undefined) {
|
|
2816
|
+
const reference = urlInfo.references.find(ref => ref.generatedSpecifier === src && ref.type === "script_src" && ref.expectedType === "js_module");
|
|
2858
2817
|
jsModuleUrls.push(reference.url);
|
|
2859
2818
|
|
|
2860
2819
|
if (shouldTransformScriptTypeModule) {
|
|
@@ -2862,8 +2821,10 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2862
2821
|
const [newReference] = await getReferenceAsJsClassic(reference, {
|
|
2863
2822
|
cookIt: true
|
|
2864
2823
|
});
|
|
2865
|
-
|
|
2866
|
-
|
|
2824
|
+
setHtmlNodeAttributes(moduleScriptNode, {
|
|
2825
|
+
type: undefined,
|
|
2826
|
+
src: newReference.generatedSpecifier
|
|
2827
|
+
});
|
|
2867
2828
|
});
|
|
2868
2829
|
}
|
|
2869
2830
|
|
|
@@ -2871,7 +2832,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2871
2832
|
}
|
|
2872
2833
|
|
|
2873
2834
|
if (shouldTransformScriptTypeModule) {
|
|
2874
|
-
const
|
|
2835
|
+
const htmlNodeText = getHtmlNodeText(moduleScriptNode);
|
|
2875
2836
|
actions.push(async () => {
|
|
2876
2837
|
const {
|
|
2877
2838
|
line,
|
|
@@ -2879,7 +2840,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2879
2840
|
lineEnd,
|
|
2880
2841
|
columnEnd,
|
|
2881
2842
|
isOriginal
|
|
2882
|
-
} =
|
|
2843
|
+
} = getHtmlNodePosition(moduleScriptNode, {
|
|
2883
2844
|
preferOriginal: true
|
|
2884
2845
|
});
|
|
2885
2846
|
let inlineScriptUrl = generateInlineContentUrl({
|
|
@@ -2902,15 +2863,15 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2902
2863
|
specifierColumn: column,
|
|
2903
2864
|
specifier: inlineScriptUrl,
|
|
2904
2865
|
contentType: "text/javascript",
|
|
2905
|
-
content:
|
|
2866
|
+
content: htmlNodeText
|
|
2906
2867
|
});
|
|
2907
2868
|
const [, newUrlInfo] = await getReferenceAsJsClassic(inlineReference, {
|
|
2908
2869
|
cookIt: true
|
|
2909
2870
|
});
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2871
|
+
setHtmlNodeText(moduleScriptNode, newUrlInfo.content);
|
|
2872
|
+
setHtmlNodeAttributes(moduleScriptNode, {
|
|
2873
|
+
"type": undefined,
|
|
2874
|
+
"generated-by": "jsenv:as_js_classic_html"
|
|
2914
2875
|
});
|
|
2915
2876
|
});
|
|
2916
2877
|
}
|
|
@@ -2918,8 +2879,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2918
2879
|
|
|
2919
2880
|
if (shouldTransformScriptTypeModule) {
|
|
2920
2881
|
preloadAsScriptNodes.forEach(preloadAsScriptNode => {
|
|
2921
|
-
const
|
|
2922
|
-
const href = hrefAttribute.value;
|
|
2882
|
+
const href = getHtmlNodeAttribute(preloadAsScriptNode, "href");
|
|
2923
2883
|
const reference = urlInfo.references.find(ref => ref.generatedSpecifier === href && ref.type === "link_href" && ref.expectedType === undefined);
|
|
2924
2884
|
const expectedScriptType = jsModuleUrls.includes(reference.url) ? "module" : "classic";
|
|
2925
2885
|
|
|
@@ -2934,16 +2894,15 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2934
2894
|
[newReference] = await getReferenceAsJsClassic(reference);
|
|
2935
2895
|
}
|
|
2936
2896
|
|
|
2937
|
-
|
|
2938
|
-
href: newReference.generatedSpecifier
|
|
2897
|
+
setHtmlNodeAttributes(preloadAsScriptNode, {
|
|
2898
|
+
href: newReference.generatedSpecifier,
|
|
2899
|
+
crossorigin: undefined
|
|
2939
2900
|
});
|
|
2940
|
-
removeHtmlNodeAttributeByName(preloadAsScriptNode, "crossorigin");
|
|
2941
2901
|
});
|
|
2942
2902
|
}
|
|
2943
2903
|
});
|
|
2944
2904
|
modulePreloadNodes.forEach(modulePreloadNode => {
|
|
2945
|
-
const
|
|
2946
|
-
const href = hrefAttribute.value;
|
|
2905
|
+
const href = getHtmlNodeAttribute(modulePreloadNode, "href");
|
|
2947
2906
|
const reference = urlInfo.references.find(ref => ref.generatedSpecifier === href && ref.type === "link_href" && ref.expectedType === "js_module");
|
|
2948
2907
|
actions.push(async () => {
|
|
2949
2908
|
let newReference;
|
|
@@ -2954,7 +2913,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2954
2913
|
[newReference] = await getReferenceAsJsClassic(reference);
|
|
2955
2914
|
}
|
|
2956
2915
|
|
|
2957
|
-
|
|
2916
|
+
setHtmlNodeAttributes(modulePreloadNode, {
|
|
2958
2917
|
rel: "preload",
|
|
2959
2918
|
as: "script",
|
|
2960
2919
|
href: newReference.generatedSpecifier
|
|
@@ -2978,7 +2937,7 @@ const jsenvPluginAsJsClassicHtml = ({
|
|
|
2978
2937
|
expectedType: "js_classic",
|
|
2979
2938
|
specifier: systemJsClientFileUrl
|
|
2980
2939
|
});
|
|
2981
|
-
|
|
2940
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
2982
2941
|
"tagName": "script",
|
|
2983
2942
|
"src": systemJsReference.generatedSpecifier,
|
|
2984
2943
|
"injected-by": "jsenv:as_js_classic_html"
|
|
@@ -4057,7 +4016,7 @@ const babelPluginBabelHelpersAsJsenvImports = (babel, {
|
|
|
4057
4016
|
}
|
|
4058
4017
|
|
|
4059
4018
|
const babelHelperImportSpecifier = getBabelHelperFileUrl(name);
|
|
4060
|
-
const helper =
|
|
4019
|
+
const helper = injectJsImport({
|
|
4061
4020
|
programPath: file.path,
|
|
4062
4021
|
from: getImportSpecifier(babelHelperImportSpecifier),
|
|
4063
4022
|
nameHint: `_${name}`,
|
|
@@ -4160,7 +4119,7 @@ const babelPluginNewStylesheetAsJsenvImport = (babel, {
|
|
|
4160
4119
|
});
|
|
4161
4120
|
|
|
4162
4121
|
if (usesNewStylesheet) {
|
|
4163
|
-
|
|
4122
|
+
injectJsImport({
|
|
4164
4123
|
programPath,
|
|
4165
4124
|
from: getImportSpecifier(newStylesheetClientFileUrl),
|
|
4166
4125
|
sideEffect: true
|
|
@@ -4225,7 +4184,7 @@ const babelPluginGlobalThisAsJsenvImport = (babel, {
|
|
|
4225
4184
|
} = path; // we should do this once, tree shaking will remote it but still
|
|
4226
4185
|
|
|
4227
4186
|
if (node.name === "globalThis") {
|
|
4228
|
-
|
|
4187
|
+
injectJsImport({
|
|
4229
4188
|
programPath: path.scope.getProgramParent().path,
|
|
4230
4189
|
from: getImportSpecifier(globalThisClientFileUrl),
|
|
4231
4190
|
sideEffect: true
|
|
@@ -4259,7 +4218,7 @@ const babelPluginRegeneratorRuntimeAsJsenvImport = (babel, {
|
|
|
4259
4218
|
} = path;
|
|
4260
4219
|
|
|
4261
4220
|
if (node.name === "regeneratorRuntime") {
|
|
4262
|
-
|
|
4221
|
+
injectJsImport({
|
|
4263
4222
|
programPath: path.scope.getProgramParent().path,
|
|
4264
4223
|
from: getImportSpecifier(regeneratorRuntimeClientFileUrl),
|
|
4265
4224
|
sideEffect: true
|
|
@@ -4503,6 +4462,39 @@ const jsenvPluginNodeRuntime = ({
|
|
|
4503
4462
|
};
|
|
4504
4463
|
};
|
|
4505
4464
|
|
|
4465
|
+
const sortByDependencies = nodes => {
|
|
4466
|
+
const visited = [];
|
|
4467
|
+
const sorted = [];
|
|
4468
|
+
const circular = [];
|
|
4469
|
+
|
|
4470
|
+
const visit = url => {
|
|
4471
|
+
const isSorted = sorted.includes(url);
|
|
4472
|
+
|
|
4473
|
+
if (isSorted) {
|
|
4474
|
+
return;
|
|
4475
|
+
}
|
|
4476
|
+
|
|
4477
|
+
const isVisited = visited.includes(url);
|
|
4478
|
+
|
|
4479
|
+
if (isVisited) {
|
|
4480
|
+
circular.push(url);
|
|
4481
|
+
sorted.push(url);
|
|
4482
|
+
} else {
|
|
4483
|
+
visited.push(url);
|
|
4484
|
+
nodes[url].dependencies.forEach(dependencyUrl => {
|
|
4485
|
+
visit(dependencyUrl);
|
|
4486
|
+
});
|
|
4487
|
+
sorted.push(url);
|
|
4488
|
+
}
|
|
4489
|
+
};
|
|
4490
|
+
|
|
4491
|
+
Object.keys(nodes).forEach(url => {
|
|
4492
|
+
visit(url);
|
|
4493
|
+
});
|
|
4494
|
+
sorted.circular = circular;
|
|
4495
|
+
return sorted;
|
|
4496
|
+
};
|
|
4497
|
+
|
|
4506
4498
|
/*
|
|
4507
4499
|
* Each @import found in css is replaced by the file content
|
|
4508
4500
|
* - There is no need to worry about urls (such as background-image: url())
|
|
@@ -4720,71 +4712,6 @@ const bundleJsModule = async ({
|
|
|
4720
4712
|
});
|
|
4721
4713
|
return jsModuleBundleUrlInfos;
|
|
4722
4714
|
};
|
|
4723
|
-
const buildWithRollup = async ({
|
|
4724
|
-
signal,
|
|
4725
|
-
logger,
|
|
4726
|
-
rootDirectoryUrl,
|
|
4727
|
-
buildDirectoryUrl,
|
|
4728
|
-
urlGraph,
|
|
4729
|
-
jsModuleUrlInfos,
|
|
4730
|
-
runtimeCompat,
|
|
4731
|
-
sourcemaps,
|
|
4732
|
-
include,
|
|
4733
|
-
babelHelpersChunk
|
|
4734
|
-
}) => {
|
|
4735
|
-
const resultRef = {
|
|
4736
|
-
current: null
|
|
4737
|
-
};
|
|
4738
|
-
|
|
4739
|
-
try {
|
|
4740
|
-
await applyRollupPlugins({
|
|
4741
|
-
rollupPlugins: [rollupPluginJsenv({
|
|
4742
|
-
signal,
|
|
4743
|
-
logger,
|
|
4744
|
-
rootDirectoryUrl,
|
|
4745
|
-
buildDirectoryUrl,
|
|
4746
|
-
urlGraph,
|
|
4747
|
-
jsModuleUrlInfos,
|
|
4748
|
-
runtimeCompat,
|
|
4749
|
-
sourcemaps,
|
|
4750
|
-
include,
|
|
4751
|
-
babelHelpersChunk,
|
|
4752
|
-
resultRef
|
|
4753
|
-
})],
|
|
4754
|
-
inputOptions: {
|
|
4755
|
-
input: [],
|
|
4756
|
-
onwarn: warning => {
|
|
4757
|
-
if (warning.code === "CIRCULAR_DEPENDENCY") {
|
|
4758
|
-
return;
|
|
4759
|
-
}
|
|
4760
|
-
|
|
4761
|
-
if (warning.code === "THIS_IS_UNDEFINED" && pathToFileURL(warning.id).href === globalThisClientFileUrl) {
|
|
4762
|
-
return;
|
|
4763
|
-
}
|
|
4764
|
-
|
|
4765
|
-
if (warning.code === "EVAL") {
|
|
4766
|
-
// ideally we should disable only for jsenv files
|
|
4767
|
-
return;
|
|
4768
|
-
}
|
|
4769
|
-
|
|
4770
|
-
logger.warn(String(warning));
|
|
4771
|
-
}
|
|
4772
|
-
}
|
|
4773
|
-
});
|
|
4774
|
-
return resultRef.current;
|
|
4775
|
-
} catch (e) {
|
|
4776
|
-
if (e.code === "MISSING_EXPORT") {
|
|
4777
|
-
const detailedMessage = createDetailedMessage(e.message, {
|
|
4778
|
-
frame: e.frame
|
|
4779
|
-
});
|
|
4780
|
-
throw new Error(detailedMessage, {
|
|
4781
|
-
cause: e
|
|
4782
|
-
});
|
|
4783
|
-
}
|
|
4784
|
-
|
|
4785
|
-
throw e;
|
|
4786
|
-
}
|
|
4787
|
-
};
|
|
4788
4715
|
|
|
4789
4716
|
const rollupPluginJsenv = ({
|
|
4790
4717
|
// logger,
|
|
@@ -5010,6 +4937,91 @@ const rollupPluginJsenv = ({
|
|
|
5010
4937
|
};
|
|
5011
4938
|
};
|
|
5012
4939
|
|
|
4940
|
+
const buildWithRollup = async ({
|
|
4941
|
+
signal,
|
|
4942
|
+
logger,
|
|
4943
|
+
rootDirectoryUrl,
|
|
4944
|
+
buildDirectoryUrl,
|
|
4945
|
+
urlGraph,
|
|
4946
|
+
jsModuleUrlInfos,
|
|
4947
|
+
runtimeCompat,
|
|
4948
|
+
sourcemaps,
|
|
4949
|
+
include,
|
|
4950
|
+
babelHelpersChunk
|
|
4951
|
+
}) => {
|
|
4952
|
+
const resultRef = {
|
|
4953
|
+
current: null
|
|
4954
|
+
};
|
|
4955
|
+
|
|
4956
|
+
try {
|
|
4957
|
+
await applyRollupPlugins({
|
|
4958
|
+
rollupPlugins: [rollupPluginJsenv({
|
|
4959
|
+
signal,
|
|
4960
|
+
logger,
|
|
4961
|
+
rootDirectoryUrl,
|
|
4962
|
+
buildDirectoryUrl,
|
|
4963
|
+
urlGraph,
|
|
4964
|
+
jsModuleUrlInfos,
|
|
4965
|
+
runtimeCompat,
|
|
4966
|
+
sourcemaps,
|
|
4967
|
+
include,
|
|
4968
|
+
babelHelpersChunk,
|
|
4969
|
+
resultRef
|
|
4970
|
+
})],
|
|
4971
|
+
inputOptions: {
|
|
4972
|
+
input: [],
|
|
4973
|
+
onwarn: warning => {
|
|
4974
|
+
if (warning.code === "CIRCULAR_DEPENDENCY") {
|
|
4975
|
+
return;
|
|
4976
|
+
}
|
|
4977
|
+
|
|
4978
|
+
if (warning.code === "THIS_IS_UNDEFINED" && pathToFileURL(warning.id).href === globalThisClientFileUrl) {
|
|
4979
|
+
return;
|
|
4980
|
+
}
|
|
4981
|
+
|
|
4982
|
+
if (warning.code === "EVAL") {
|
|
4983
|
+
// ideally we should disable only for jsenv files
|
|
4984
|
+
return;
|
|
4985
|
+
}
|
|
4986
|
+
|
|
4987
|
+
logger.warn(String(warning));
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
});
|
|
4991
|
+
return resultRef.current;
|
|
4992
|
+
} catch (e) {
|
|
4993
|
+
if (e.code === "MISSING_EXPORT") {
|
|
4994
|
+
const detailedMessage = createDetailedMessage(e.message, {
|
|
4995
|
+
frame: e.frame
|
|
4996
|
+
});
|
|
4997
|
+
throw new Error(detailedMessage, {
|
|
4998
|
+
cause: e
|
|
4999
|
+
});
|
|
5000
|
+
}
|
|
5001
|
+
|
|
5002
|
+
throw e;
|
|
5003
|
+
}
|
|
5004
|
+
};
|
|
5005
|
+
|
|
5006
|
+
const applyRollupPlugins = async ({
|
|
5007
|
+
rollupPlugins,
|
|
5008
|
+
inputOptions = {},
|
|
5009
|
+
outputOptions = {}
|
|
5010
|
+
}) => {
|
|
5011
|
+
const {
|
|
5012
|
+
rollup
|
|
5013
|
+
} = await import("rollup");
|
|
5014
|
+
const {
|
|
5015
|
+
importAssertions
|
|
5016
|
+
} = await import("acorn-import-assertions");
|
|
5017
|
+
const rollupReturnValue = await rollup({ ...inputOptions,
|
|
5018
|
+
plugins: rollupPlugins,
|
|
5019
|
+
acornInjectPlugins: [importAssertions, ...(inputOptions.acornInjectPlugins || [])]
|
|
5020
|
+
});
|
|
5021
|
+
const rollupOutputArray = await rollupReturnValue.generate(outputOptions);
|
|
5022
|
+
return rollupOutputArray;
|
|
5023
|
+
};
|
|
5024
|
+
|
|
5013
5025
|
const willBeInsideJsDirectory = ({
|
|
5014
5026
|
chunkInfo,
|
|
5015
5027
|
fileUrlConverter,
|
|
@@ -5252,8 +5264,7 @@ const collectHotDataFromHtmlAst = htmlAst => {
|
|
|
5252
5264
|
attributeName,
|
|
5253
5265
|
hotAccepted
|
|
5254
5266
|
}) => {
|
|
5255
|
-
const
|
|
5256
|
-
const value = attribute ? attribute.value : undefined;
|
|
5267
|
+
const value = getHtmlNodeAttribute(node, attributeName);
|
|
5257
5268
|
|
|
5258
5269
|
if (value) {
|
|
5259
5270
|
onSpecifier({
|
|
@@ -5300,11 +5311,10 @@ const collectHotDataFromHtmlAst = htmlAst => {
|
|
|
5300
5311
|
}
|
|
5301
5312
|
|
|
5302
5313
|
if (nodeNamesWithSrcset.includes(node.nodeName)) {
|
|
5303
|
-
const
|
|
5304
|
-
const srcset = srcsetAttribute ? srcsetAttribute.value : undefined;
|
|
5314
|
+
const srcset = getHtmlNodeAttribute(node, "srcset");
|
|
5305
5315
|
|
|
5306
5316
|
if (srcset) {
|
|
5307
|
-
const srcCandidates =
|
|
5317
|
+
const srcCandidates = parseSrcSet(srcset);
|
|
5308
5318
|
srcCandidates.forEach(srcCandidate => {
|
|
5309
5319
|
onSpecifier({
|
|
5310
5320
|
node,
|
|
@@ -5345,15 +5355,15 @@ const nodeNamesWithSrcset = ["img", "source"];
|
|
|
5345
5355
|
|
|
5346
5356
|
const getNodeContext = node => {
|
|
5347
5357
|
const context = {};
|
|
5348
|
-
const
|
|
5358
|
+
const hotAccept = getHtmlNodeAttribute(node, "hot-accept");
|
|
5349
5359
|
|
|
5350
|
-
if (
|
|
5360
|
+
if (hotAccept !== undefined) {
|
|
5351
5361
|
context.hotAccepted = true;
|
|
5352
5362
|
}
|
|
5353
5363
|
|
|
5354
|
-
const
|
|
5364
|
+
const hotDecline = getHtmlNodeAttribute(node, "hot-decline");
|
|
5355
5365
|
|
|
5356
|
-
if (
|
|
5366
|
+
if (hotDecline !== undefined) {
|
|
5357
5367
|
context.hotAccepted = false;
|
|
5358
5368
|
}
|
|
5359
5369
|
|
|
@@ -5366,7 +5376,7 @@ const htmlNodeCanHotReload = node => {
|
|
|
5366
5376
|
isStylesheet,
|
|
5367
5377
|
isRessourceHint,
|
|
5368
5378
|
rel
|
|
5369
|
-
} =
|
|
5379
|
+
} = analyzeLinkNode(node);
|
|
5370
5380
|
|
|
5371
5381
|
if (isStylesheet) {
|
|
5372
5382
|
// stylesheets can be hot replaced by default
|
|
@@ -5666,7 +5676,7 @@ const jsenvPluginDevSSEClient = () => {
|
|
|
5666
5676
|
expectedType: "js_module",
|
|
5667
5677
|
specifier: eventSourceClientFileUrl
|
|
5668
5678
|
});
|
|
5669
|
-
|
|
5679
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
5670
5680
|
"tagName": "script",
|
|
5671
5681
|
"type": "module",
|
|
5672
5682
|
"src": eventSourceClientReference.generatedSpecifier,
|
|
@@ -6706,13 +6716,27 @@ const createUrlInfoTransformer = ({
|
|
|
6706
6716
|
const sourcemapsEnabled = sourcemaps === "inline" || sourcemaps === "file" || sourcemaps === "programmatic";
|
|
6707
6717
|
|
|
6708
6718
|
const normalizeSourcemap = (urlInfo, sourcemap) => {
|
|
6719
|
+
let {
|
|
6720
|
+
sources
|
|
6721
|
+
} = sourcemap;
|
|
6722
|
+
|
|
6723
|
+
if (sources) {
|
|
6724
|
+
sources = sources.map(source => {
|
|
6725
|
+
if (source && isFileSystemPath(source)) {
|
|
6726
|
+
return String(pathToFileURL(source));
|
|
6727
|
+
}
|
|
6728
|
+
|
|
6729
|
+
return source;
|
|
6730
|
+
});
|
|
6731
|
+
}
|
|
6732
|
+
|
|
6709
6733
|
const wantSourcesContent = // for inline content (<script> insdide html)
|
|
6710
6734
|
// chrome won't be able to fetch the file as it does not exists
|
|
6711
6735
|
// so sourcemap must contain sources
|
|
6712
|
-
sourcemapsSourcesContent || urlInfo.isInline ||
|
|
6736
|
+
sourcemapsSourcesContent || urlInfo.isInline || sources && sources.some(source => !source || !source.startsWith("file:"));
|
|
6713
6737
|
|
|
6714
|
-
if (
|
|
6715
|
-
sourcemap.sources =
|
|
6738
|
+
if (sources && sources.length > 1) {
|
|
6739
|
+
sourcemap.sources = sources.map(source => new URL(source, urlInfo.originalUrl).href);
|
|
6716
6740
|
|
|
6717
6741
|
if (!wantSourcesContent) {
|
|
6718
6742
|
sourcemap.sourcesContent = undefined;
|
|
@@ -6748,7 +6772,7 @@ const createUrlInfoTransformer = ({
|
|
|
6748
6772
|
// but otherwise it's generatedUrl to be inside .jsenv/ directory
|
|
6749
6773
|
|
|
6750
6774
|
|
|
6751
|
-
urlInfo.sourcemapGeneratedUrl =
|
|
6775
|
+
urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(urlInfo.generatedUrl);
|
|
6752
6776
|
const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder({
|
|
6753
6777
|
urlInfo,
|
|
6754
6778
|
specifier: urlInfo.sourcemapGeneratedUrl
|
|
@@ -6854,7 +6878,7 @@ const createUrlInfoTransformer = ({
|
|
|
6854
6878
|
sourcemapUrlInfo.content = JSON.stringify(sourcemap, null, " ");
|
|
6855
6879
|
|
|
6856
6880
|
if (sourcemaps === "inline") {
|
|
6857
|
-
sourcemapReference.generatedSpecifier =
|
|
6881
|
+
sourcemapReference.generatedSpecifier = generateSourcemapDataUrl(sourcemap);
|
|
6858
6882
|
}
|
|
6859
6883
|
|
|
6860
6884
|
if (sourcemaps === "file" || sourcemaps === "inline") {
|
|
@@ -7759,6 +7783,8 @@ const memoizeCook = cook => {
|
|
|
7759
7783
|
const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
|
|
7760
7784
|
if (reference.shouldHandle) {
|
|
7761
7785
|
urlInfo.shouldHandle = true;
|
|
7786
|
+
} else {
|
|
7787
|
+
urlInfo.shouldHandle = false;
|
|
7762
7788
|
}
|
|
7763
7789
|
|
|
7764
7790
|
urlInfo.originalUrl = urlInfo.originalUrl || reference.url;
|
|
@@ -8368,7 +8394,7 @@ const jsenvPluginExplorer = ({
|
|
|
8368
8394
|
meta
|
|
8369
8395
|
}));
|
|
8370
8396
|
let html = String(readFileSync(new URL(htmlClientFileUrl)));
|
|
8371
|
-
html = html.replace("
|
|
8397
|
+
html = html.replace("ignore:FAVICON_HREF", DATA_URL.stringify({
|
|
8372
8398
|
contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
|
|
8373
8399
|
base64Flag: true,
|
|
8374
8400
|
data: readFileSync(new URL(faviconClientFileUrl)).toString("base64")
|
|
@@ -8521,7 +8547,12 @@ const startDevServer = async ({
|
|
|
8521
8547
|
stopWatchingDevServerFiles();
|
|
8522
8548
|
reloadableWorker.terminate();
|
|
8523
8549
|
});
|
|
8524
|
-
await reloadableWorker.load();
|
|
8550
|
+
const worker = await reloadableWorker.load();
|
|
8551
|
+
|
|
8552
|
+
if (!keepProcessAlive) {
|
|
8553
|
+
worker.unref();
|
|
8554
|
+
}
|
|
8555
|
+
|
|
8525
8556
|
return {
|
|
8526
8557
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
8527
8558
|
stop: () => {
|
|
@@ -9051,7 +9082,7 @@ const normalizeFileByFileCoveragePaths = (fileByFileCoverage, rootDirectoryUrl)
|
|
|
9051
9082
|
const {
|
|
9052
9083
|
path
|
|
9053
9084
|
} = fileCoverage;
|
|
9054
|
-
const url = isFileSystemPath(path) ? fileSystemPathToUrl(path) :
|
|
9085
|
+
const url = isFileSystemPath(path) ? fileSystemPathToUrl(path) : new URL(path, rootDirectoryUrl).href;
|
|
9055
9086
|
const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl);
|
|
9056
9087
|
fileByFileNormalized[`./${relativeUrl}`] = { ...fileCoverage,
|
|
9057
9088
|
path: `./${relativeUrl}`
|
|
@@ -12317,7 +12348,7 @@ const injectors = {
|
|
|
12317
12348
|
const htmlAst = parseHtmlString(urlInfo.content, {
|
|
12318
12349
|
storeOriginalPositions: false
|
|
12319
12350
|
});
|
|
12320
|
-
|
|
12351
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
12321
12352
|
"tagName": "script",
|
|
12322
12353
|
"textContent": generateClientCodeForVersionMappings(versionMappings, {
|
|
12323
12354
|
globalName: "window"
|
|
@@ -12348,6 +12379,60 @@ ${globalName}.__v__ = function (specifier) {
|
|
|
12348
12379
|
`;
|
|
12349
12380
|
};
|
|
12350
12381
|
|
|
12382
|
+
// https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
|
|
12383
|
+
|
|
12384
|
+
const createVersionGenerator = () => {
|
|
12385
|
+
const hash = createHash("sha256");
|
|
12386
|
+
|
|
12387
|
+
const augmentWithContent = ({
|
|
12388
|
+
content,
|
|
12389
|
+
contentType = "application/octet-stream",
|
|
12390
|
+
lineBreakNormalization = false
|
|
12391
|
+
}) => {
|
|
12392
|
+
hash.update(lineBreakNormalization && CONTENT_TYPE.isTextual(contentType) ? normalizeLineBreaks(content) : content);
|
|
12393
|
+
};
|
|
12394
|
+
|
|
12395
|
+
const augmentWithDependencyVersion = version => {
|
|
12396
|
+
hash.update(version);
|
|
12397
|
+
};
|
|
12398
|
+
|
|
12399
|
+
return {
|
|
12400
|
+
augmentWithContent,
|
|
12401
|
+
augmentWithDependencyVersion,
|
|
12402
|
+
generate: () => {
|
|
12403
|
+
return hash.digest("hex").slice(0, 8);
|
|
12404
|
+
}
|
|
12405
|
+
};
|
|
12406
|
+
};
|
|
12407
|
+
|
|
12408
|
+
const normalizeLineBreaks = stringOrBuffer => {
|
|
12409
|
+
if (typeof stringOrBuffer === "string") {
|
|
12410
|
+
const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n");
|
|
12411
|
+
return stringWithLinuxBreaks;
|
|
12412
|
+
}
|
|
12413
|
+
|
|
12414
|
+
return normalizeLineBreaksForBuffer(stringOrBuffer);
|
|
12415
|
+
}; // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
|
|
12416
|
+
|
|
12417
|
+
|
|
12418
|
+
const normalizeLineBreaksForBuffer = buffer => {
|
|
12419
|
+
const int32Array = new Int32Array(buffer, 0, buffer.length);
|
|
12420
|
+
const int32ArrayWithLineBreaksNormalized = int32Array.filter((element, index, typedArray) => {
|
|
12421
|
+
if (element === 0x0d) {
|
|
12422
|
+
if (typedArray[index + 1] === 0x0a) {
|
|
12423
|
+
// Windows -> Unix
|
|
12424
|
+
return false;
|
|
12425
|
+
} // Mac OS -> Unix
|
|
12426
|
+
|
|
12427
|
+
|
|
12428
|
+
typedArray[index] = 0x0a;
|
|
12429
|
+
}
|
|
12430
|
+
|
|
12431
|
+
return true;
|
|
12432
|
+
});
|
|
12433
|
+
return Buffer.from(int32ArrayWithLineBreaksNormalized);
|
|
12434
|
+
};
|
|
12435
|
+
|
|
12351
12436
|
const injectServiceWorkerUrls = async ({
|
|
12352
12437
|
finalGraph,
|
|
12353
12438
|
finalGraphKitchen,
|
|
@@ -12445,15 +12530,12 @@ const resyncRessourceHints = async ({
|
|
|
12445
12530
|
});
|
|
12446
12531
|
const actions = [];
|
|
12447
12532
|
|
|
12448
|
-
const visitLinkWithHref = (linkNode,
|
|
12449
|
-
const href = hrefAttribute.value;
|
|
12450
|
-
|
|
12533
|
+
const visitLinkWithHref = (linkNode, href) => {
|
|
12451
12534
|
if (!href || href.startsWith("data:")) {
|
|
12452
12535
|
return;
|
|
12453
12536
|
}
|
|
12454
12537
|
|
|
12455
|
-
const
|
|
12456
|
-
const rel = relAttribute ? relAttribute.value : undefined;
|
|
12538
|
+
const rel = getHtmlNodeAttribute(linkNode, "rel");
|
|
12457
12539
|
const isRessourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(rel);
|
|
12458
12540
|
|
|
12459
12541
|
if (!isRessourceHint) {
|
|
@@ -12497,22 +12579,20 @@ const resyncRessourceHints = async ({
|
|
|
12497
12579
|
}
|
|
12498
12580
|
|
|
12499
12581
|
actions.push(() => {
|
|
12500
|
-
|
|
12582
|
+
setHtmlNodeAttributes(linkNode, {
|
|
12583
|
+
href: urlInfo.data.buildUrlSpecifier
|
|
12584
|
+
});
|
|
12501
12585
|
});
|
|
12502
12586
|
};
|
|
12503
12587
|
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
}
|
|
12508
|
-
|
|
12509
|
-
const hrefAttribute = getHtmlNodeAttributeByName(node, "href");
|
|
12588
|
+
visitHtmlNodes(htmlAst, {
|
|
12589
|
+
link: node => {
|
|
12590
|
+
const href = getHtmlNodeAttribute(node, "href");
|
|
12510
12591
|
|
|
12511
|
-
|
|
12512
|
-
|
|
12592
|
+
if (href !== undefined) {
|
|
12593
|
+
visitLinkWithHref(node, href);
|
|
12594
|
+
}
|
|
12513
12595
|
}
|
|
12514
|
-
|
|
12515
|
-
visitLinkWithHref(node, hrefAttribute);
|
|
12516
12596
|
});
|
|
12517
12597
|
|
|
12518
12598
|
if (actions.length) {
|
|
@@ -13077,7 +13157,7 @@ build ${entryPointKeys.length} entry points`);
|
|
|
13077
13157
|
|
|
13078
13158
|
if (reference.type === "sourcemap_comment") {
|
|
13079
13159
|
// inherit parent build url
|
|
13080
|
-
return
|
|
13160
|
+
return generateSourcemapFileUrl(reference.parentUrl);
|
|
13081
13161
|
} // files generated during the final graph:
|
|
13082
13162
|
// - sourcemaps
|
|
13083
13163
|
// const finalUrlInfo = finalGraph.getUrlInfo(url)
|
|
@@ -13803,6 +13883,7 @@ const startBuildServer = async ({
|
|
|
13803
13883
|
ip,
|
|
13804
13884
|
port = 9779,
|
|
13805
13885
|
services = {},
|
|
13886
|
+
keepProcessAlive = true,
|
|
13806
13887
|
rootDirectoryUrl,
|
|
13807
13888
|
buildDirectoryUrl,
|
|
13808
13889
|
mainBuildFileUrl = "/index.html",
|
|
@@ -13892,7 +13973,12 @@ const startBuildServer = async ({
|
|
|
13892
13973
|
stopWatchingBuildServerFiles();
|
|
13893
13974
|
reloadableWorker.terminate();
|
|
13894
13975
|
});
|
|
13895
|
-
await reloadableWorker.load();
|
|
13976
|
+
const worker = await reloadableWorker.load();
|
|
13977
|
+
|
|
13978
|
+
if (!keepProcessAlive) {
|
|
13979
|
+
worker.unref();
|
|
13980
|
+
}
|
|
13981
|
+
|
|
13896
13982
|
return {
|
|
13897
13983
|
origin: `${protocol}://127.0.0.1:${port}`,
|
|
13898
13984
|
stop: () => {
|
|
@@ -14150,7 +14236,7 @@ const globalInjectorOnHtml = async (urlInfo, globals) => {
|
|
|
14150
14236
|
globals,
|
|
14151
14237
|
isWebWorker: false
|
|
14152
14238
|
});
|
|
14153
|
-
|
|
14239
|
+
injectScriptNodeAsEarlyAsPossible(htmlAst, createHtmlNode({
|
|
14154
14240
|
"tagName": "script",
|
|
14155
14241
|
"textContent": clientCode,
|
|
14156
14242
|
"injected-by": "jsenv:inject_globals"
|