@jsenv/core 39.3.12 → 39.4.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "39.3.12",
3
+ "version": "39.4.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -38,6 +38,7 @@
38
38
  },
39
39
  "workspaces": [
40
40
  "./packages/independent/*",
41
+ "./packages/independent/workflow/*",
41
42
  "./packages/internal/*",
42
43
  "./packages/related/*",
43
44
  "./packages/related/cli/*"
@@ -52,7 +53,7 @@
52
53
  "monorepo:publish": "node ./scripts/monorepo/publish_packages.mjs",
53
54
  "monorepo:upgrade_versions": "node ./scripts/monorepo/upgrade_external_versions.mjs",
54
55
  "monorepo:node_modules_clear": "npx @jsenv/filesystem clear **/node_modules/",
55
- "md:build": "node ./md/build.js",
56
+ "md:build": "node ./docs/build.js",
56
57
  "performances": "node --expose-gc ./scripts/performance/generate_performance_report.mjs --log --once",
57
58
  "build:file_size": "node ./scripts/build/build_file_size.mjs --log",
58
59
  "prettier": "prettier --write .",
@@ -62,23 +63,23 @@
62
63
  "workspace:test:ci": "CI=1 npm run workspace:test",
63
64
  "dev": "node --conditions=development ./scripts/dev/dev.mjs",
64
65
  "playwright:install": "npx playwright install-deps && npx playwright install",
65
- "certificate:install": "node ./scripts/dev/install_certificate_authority.mjs",
66
+ "https:setup": "npx @jsenv/https-local setup",
66
67
  "prepublishOnly": "npm run build"
67
68
  },
68
69
  "dependencies": {
69
70
  "@financial-times/polyfill-useragent-normaliser": "1.10.2",
70
71
  "@jsenv/abort": "4.3.0",
71
- "@jsenv/ast": "6.2.16",
72
+ "@jsenv/ast": "6.2.17",
72
73
  "@jsenv/filesystem": "4.10.2",
73
74
  "@jsenv/humanize": "1.2.8",
74
75
  "@jsenv/importmap": "1.2.1",
75
76
  "@jsenv/integrity": "0.0.2",
76
- "@jsenv/js-module-fallback": "1.3.37",
77
+ "@jsenv/js-module-fallback": "1.3.38",
77
78
  "@jsenv/node-esm-resolution": "1.0.6",
78
79
  "@jsenv/plugin-bundling": "2.7.7",
79
80
  "@jsenv/plugin-minification": "1.5.5",
80
- "@jsenv/plugin-supervisor": "1.5.18",
81
- "@jsenv/plugin-transpilation": "1.4.21",
81
+ "@jsenv/plugin-supervisor": "1.5.19",
82
+ "@jsenv/plugin-transpilation": "1.4.22",
82
83
  "@jsenv/runtime-compat": "1.3.1",
83
84
  "@jsenv/server": "15.3.0",
84
85
  "@jsenv/sourcemap": "1.2.23",
@@ -88,26 +89,25 @@
88
89
  "anchor-markdown-header": "0.7.0"
89
90
  },
90
91
  "devDependencies": {
91
- "@babel/eslint-parser": "7.25.1",
92
92
  "@babel/plugin-syntax-import-attributes": "7.24.7",
93
93
  "@babel/plugin-syntax-optional-chaining-assign": "7.24.7",
94
94
  "@eslint/compat": "1.1.1",
95
- "@jsenv/assert": "./packages/independent/assert/",
96
- "@jsenv/cli": "./packages/related/cli/",
95
+ "@jsenv/assert": "workspace:*",
96
+ "@jsenv/cli": "workspace:*",
97
97
  "@jsenv/core": "./",
98
- "@jsenv/eslint-config": "./packages/independent/eslint-config/",
99
- "@jsenv/file-size-impact": "14.2.0",
100
- "@jsenv/https-local": "3.0.7",
101
- "@jsenv/monorepo": "0.0.6",
102
- "@jsenv/performance-impact": "4.3.0",
103
- "@jsenv/plugin-as-js-classic": "./packages/related/plugin-as-js-classic/",
104
- "@jsenv/snapshot": "./packages/independent/snapshot/",
105
- "@jsenv/test": "./packages/related/test/",
98
+ "@jsenv/eslint-config-relax": "workspace:*",
99
+ "@jsenv/file-size-impact": "workspace:*",
100
+ "@jsenv/https-local": "workspace:*",
101
+ "@jsenv/monorepo": "workspace:*",
102
+ "@jsenv/performance-impact": "workspace:*",
103
+ "@jsenv/plugin-as-js-classic": "workspace:*",
104
+ "@jsenv/snapshot": "workspace:*",
105
+ "@jsenv/test": "workspace:*",
106
106
  "@playwright/browser-chromium": "1.46.0",
107
107
  "@playwright/browser-firefox": "1.46.0",
108
108
  "@playwright/browser-webkit": "1.46.0",
109
109
  "babel-plugin-transform-async-to-promises": "0.8.18",
110
- "eslint": "9.8.0",
110
+ "eslint": "9.9.0",
111
111
  "marked": "14.0.0",
112
112
  "open": "10.1.0",
113
113
  "playwright": "1.46.0",
@@ -93,6 +93,10 @@ export const build = async ({
93
93
  signal = new AbortController().signal,
94
94
  handleSIGINT = true,
95
95
  logLevel = "info",
96
+ logs = {
97
+ disabled: false,
98
+ animation: true,
99
+ },
96
100
  sourceDirectoryUrl,
97
101
  buildDirectoryUrl,
98
102
  entryPoints = {},
@@ -121,6 +125,7 @@ export const build = async ({
121
125
  sourceFilesConfig = {},
122
126
  cooldownBetweenFileEvents,
123
127
  watch = false,
128
+ http = false,
124
129
 
125
130
  directoryToClean,
126
131
  sourcemaps = "none",
@@ -231,8 +236,9 @@ export const build = async ({
231
236
  const logger = createLogger({ logLevel });
232
237
  const createBuildTask = (label) => {
233
238
  return createTaskLog(label, {
234
- disabled: !logger.levels.debug && !logger.levels.info,
235
- animated: !logger.levels.debug,
239
+ disabled:
240
+ logs.disabled || (!logger.levels.debug && !logger.levels.info),
241
+ animated: logs.animation && !logger.levels.debug,
236
242
  });
237
243
  };
238
244
 
@@ -307,6 +313,7 @@ build ${entryPointKeys.length} entry points`);
307
313
  jsModuleFallback: false,
308
314
  },
309
315
  inlining: false,
316
+ http,
310
317
  scenarioPlaceholders,
311
318
  }),
312
319
  ],
@@ -187,6 +187,42 @@ export const createBuildSpecifierManager = ({
187
187
  const url = new URL(reference.specifier, parentUrl).href;
188
188
  return url;
189
189
  },
190
+ redirectReference: (reference) => {
191
+ let referenceBeforeInlining = reference;
192
+ if (
193
+ referenceBeforeInlining.isInline &&
194
+ referenceBeforeInlining.prev &&
195
+ !referenceBeforeInlining.prev.isInline
196
+ ) {
197
+ referenceBeforeInlining = referenceBeforeInlining.prev;
198
+ }
199
+ const rawUrl = referenceBeforeInlining.url;
200
+ const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
201
+ if (rawUrlInfo) {
202
+ reference.filenameHint = rawUrlInfo.filenameHint;
203
+ return null;
204
+ }
205
+ if (referenceBeforeInlining.injected) {
206
+ return null;
207
+ }
208
+ if (
209
+ referenceBeforeInlining.isInline &&
210
+ referenceBeforeInlining.ownerUrlInfo.url ===
211
+ referenceBeforeInlining.ownerUrlInfo.originalUrl
212
+ ) {
213
+ const rawUrlInfo = findRawUrlInfoWhenInline(
214
+ referenceBeforeInlining,
215
+ rawKitchen,
216
+ );
217
+ if (rawUrlInfo) {
218
+ reference.rawUrl = rawUrlInfo.url;
219
+ reference.filenameHint = rawUrlInfo.filenameHint;
220
+ return null;
221
+ }
222
+ }
223
+ reference.filenameHint = referenceBeforeInlining.filenameHint;
224
+ return null;
225
+ },
190
226
  transformReferenceSearchParams: () => {
191
227
  // those search params are reflected into the build file name
192
228
  // moreover it create cleaner output
@@ -231,13 +267,10 @@ export const createBuildSpecifierManager = ({
231
267
  ) {
232
268
  firstReference = firstReference.prev;
233
269
  }
234
- const rawUrl = firstReference.url;
270
+ const rawUrl = firstReference.rawUrl || firstReference.url;
235
271
  const rawUrlInfo = rawKitchen.graph.getUrlInfo(rawUrl);
236
272
  const bundleInfo = bundleInfoMap.get(rawUrl);
237
273
  if (bundleInfo) {
238
- if (rawUrlInfo && !finalUrlInfo.filenameHint) {
239
- finalUrlInfo.filenameHint = rawUrlInfo.filenameHint;
240
- }
241
274
  finalUrlInfo.remapReference = bundleInfo.remapReference;
242
275
  return {
243
276
  // url: bundleInfo.url,
@@ -250,9 +283,6 @@ export const createBuildSpecifierManager = ({
250
283
  };
251
284
  }
252
285
  if (rawUrlInfo) {
253
- if (rawUrlInfo && !finalUrlInfo.filenameHint) {
254
- finalUrlInfo.filenameHint = rawUrlInfo.filenameHint;
255
- }
256
286
  return rawUrlInfo;
257
287
  }
258
288
  // reference injected during "shape":
@@ -274,9 +304,6 @@ export const createBuildSpecifierManager = ({
274
304
  content: reference.content,
275
305
  contentType: reference.contentType,
276
306
  });
277
- if (!finalUrlInfo.filenameHint) {
278
- finalUrlInfo.filenameHint = reference.filenameHint;
279
- }
280
307
  const rawUrlInfo = rawReference.urlInfo;
281
308
  await rawUrlInfo.cook();
282
309
  return {
@@ -293,48 +320,17 @@ export const createBuildSpecifierManager = ({
293
320
  firstReference.ownerUrlInfo.url ===
294
321
  firstReference.ownerUrlInfo.originalUrl
295
322
  ) {
296
- const rawUrlInfo = GRAPH_VISITOR.find(
297
- rawKitchen.graph,
298
- (rawUrlInfoCandidate) => {
299
- const { inlineUrlSite } = rawUrlInfoCandidate;
300
- if (!inlineUrlSite) {
301
- return false;
302
- }
303
- if (
304
- inlineUrlSite.url === firstReference.ownerUrlInfo.url &&
305
- inlineUrlSite.line === firstReference.specifierLine &&
306
- inlineUrlSite.column === firstReference.specifierColumn
307
- ) {
308
- return true;
309
- }
310
- if (rawUrlInfoCandidate.content === firstReference.content) {
311
- return true;
312
- }
313
- if (
314
- rawUrlInfoCandidate.originalContent === firstReference.content
315
- ) {
316
- return true;
317
- }
318
- return false;
319
- },
320
- );
321
323
  if (rawUrlInfo) {
322
- if (!finalUrlInfo.filenameHint) {
323
- finalUrlInfo.filenameHint = rawUrlInfo.filenameHint;
324
- }
325
324
  return rawUrlInfo;
326
325
  }
327
326
  }
328
- if (!finalUrlInfo.filenameHint) {
329
- finalUrlInfo.filenameHint = firstReference.filenameHint;
330
- }
331
327
  return {
332
328
  originalContent: finalUrlInfo.originalContent,
333
329
  content: firstReference.content,
334
330
  contentType: firstReference.contentType,
335
331
  };
336
332
  }
337
- throw new Error(createDetailedMessage(`Cannot fetch ${rawUrl}`));
333
+ throw new Error(createDetailedMessage(`${rawUrl} not found in graph`));
338
334
  },
339
335
  };
340
336
 
@@ -764,10 +760,15 @@ export const createBuildSpecifierManager = ({
764
760
  if (urlInfo.isEntryPoint) {
765
761
  generateReplacement(urlInfo.firstReference);
766
762
  }
767
- if (urlInfo.isInline) {
768
- generateReplacement(urlInfo.firstReference);
769
- }
770
763
  if (urlInfo.type === "sourcemap") {
764
+ const { referenceFromOthersSet } = urlInfo;
765
+ let lastRef;
766
+ for (const ref of referenceFromOthersSet) {
767
+ lastRef = ref;
768
+ }
769
+ generateReplacement(lastRef);
770
+ }
771
+ if (urlInfo.isInline) {
771
772
  generateReplacement(urlInfo.firstReference);
772
773
  }
773
774
  if (urlInfo.firstReference.type === "side_effect_file") {
@@ -1004,10 +1005,10 @@ export const createBuildSpecifierManager = ({
1004
1005
  GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
1005
1006
  finalKitchen.graph.rootUrlInfo,
1006
1007
  (urlInfo) => {
1007
- if (!urlInfo.url.startsWith("file:")) {
1008
+ const buildUrl = urlInfoToBuildUrlMap.get(urlInfo);
1009
+ if (!buildUrl) {
1008
1010
  return;
1009
1011
  }
1010
- const buildUrl = urlInfoToBuildUrlMap.get(urlInfo);
1011
1012
  const buildSpecifier = buildUrlToBuildSpecifierMap.get(buildUrl);
1012
1013
  const buildSpecifierVersioned = versioning
1013
1014
  ? buildSpecifierToBuildSpecifierVersionedMap.get(buildSpecifier)
@@ -1059,6 +1060,33 @@ export const createBuildSpecifierManager = ({
1059
1060
  };
1060
1061
  };
1061
1062
 
1063
+ const findRawUrlInfoWhenInline = (reference, rawKitchen) => {
1064
+ const rawUrlInfo = GRAPH_VISITOR.find(
1065
+ rawKitchen.graph,
1066
+ (rawUrlInfoCandidate) => {
1067
+ const { inlineUrlSite } = rawUrlInfoCandidate;
1068
+ if (!inlineUrlSite) {
1069
+ return false;
1070
+ }
1071
+ if (
1072
+ inlineUrlSite.url === reference.ownerUrlInfo.url &&
1073
+ inlineUrlSite.line === reference.specifierLine &&
1074
+ inlineUrlSite.column === reference.specifierColumn
1075
+ ) {
1076
+ return true;
1077
+ }
1078
+ if (rawUrlInfoCandidate.content === reference.content) {
1079
+ return true;
1080
+ }
1081
+ if (rawUrlInfoCandidate.originalContent === reference.content) {
1082
+ return true;
1083
+ }
1084
+ return false;
1085
+ },
1086
+ );
1087
+ return rawUrlInfo;
1088
+ };
1089
+
1062
1090
  // see https://github.com/rollup/rollup/blob/ce453507ab8457dd1ea3909d8dd7b117b2d14fab/src/utils/hashPlaceholders.ts#L1
1063
1091
  // see also "New hashing algorithm that "fixes (nearly) everything"
1064
1092
  // at https://github.com/rollup/rollup/pull/4543
@@ -1,13 +1,7 @@
1
- import { ensureWindowsDriveLetter } from "@jsenv/filesystem";
2
1
  import { ANSI, createDetailedMessage, createLogger } from "@jsenv/humanize";
3
2
  import { RUNTIME_COMPAT } from "@jsenv/runtime-compat";
4
3
  import { URL_META } from "@jsenv/url-meta";
5
- import {
6
- moveUrl,
7
- normalizeUrl,
8
- setUrlFilename,
9
- urlIsInsideOf,
10
- } from "@jsenv/urls";
4
+ import { normalizeUrl } from "@jsenv/urls";
11
5
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
12
6
  import { jsenvPluginHtmlSyntaxErrorFallback } from "../plugins/html_syntax_error_fallback/jsenv_plugin_html_syntax_error_fallback.js";
13
7
  import { createPluginController } from "../plugins/plugin_controller.js";
@@ -19,6 +13,10 @@ import {
19
13
  defineNonEnumerableProperties,
20
14
  } from "./errors.js";
21
15
  import { assertFetchedContentCompliance } from "./fetched_content_compliance.js";
16
+ import {
17
+ determineFileUrlForOutDirectory,
18
+ determineSourcemapFileUrl,
19
+ } from "./out_directory_url.js";
22
20
  import { createUrlGraph } from "./url_graph/url_graph.js";
23
21
  import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js";
24
22
  import { urlSpecifierEncoding } from "./url_graph/url_specifier_encoding.js";
@@ -153,7 +151,11 @@ export const createKitchen = ({
153
151
  reference.type !== "js_import"
154
152
  ) {
155
153
  referenceUrl = `ignore:${referenceUrl}`;
156
- } else if (isIgnored(referenceUrl)) {
154
+ } else if (
155
+ reference.url && reference.original
156
+ ? isIgnored(reference.original.url)
157
+ : isIgnored(referenceUrl)
158
+ ) {
157
159
  referenceUrl = `ignore:${referenceUrl}`;
158
160
  }
159
161
 
@@ -245,13 +247,16 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
245
247
  kitchenContext.resolveReference = resolveReference;
246
248
 
247
249
  const finalizeReference = (reference) => {
250
+ const urlInfo = reference.urlInfo;
251
+ urlInfo.generatedUrl = determineFileUrlForOutDirectory(urlInfo);
252
+ urlInfo.sourcemapGeneratedUrl = determineSourcemapFileUrl(urlInfo);
253
+
248
254
  if (reference.isImplicit && reference.isWeak) {
249
255
  // not needed for implicit references that are not rendered anywhere
250
256
  // this condition excludes:
251
257
  // - side_effect_file references injected in entry points or at the top of files
252
258
  return;
253
259
  }
254
-
255
260
  transform_search_params: {
256
261
  // This hook must touch reference.generatedUrl, NOT reference.url
257
262
  // And this is because this hook inject query params used to:
@@ -358,7 +363,9 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
358
363
  urlInfo.subtypeHint ||
359
364
  "";
360
365
  // during build urls info are reused and load returns originalUrl/originalContent
361
- urlInfo.originalUrl = originalUrl || urlInfo.originalUrl;
366
+ urlInfo.originalUrl = originalUrl
367
+ ? String(originalUrl)
368
+ : urlInfo.originalUrl;
362
369
  if (data) {
363
370
  Object.assign(urlInfo.data, data);
364
371
  }
@@ -369,7 +376,6 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
369
376
  urlInfo,
370
377
  content,
371
378
  });
372
- urlInfo.generatedUrl = determineFileUrlForOutDirectory(urlInfo);
373
379
 
374
380
  // we wait here to read .contentAst and .originalContentAst
375
381
  // so that we don't trigger lazy getters
@@ -705,27 +711,3 @@ const inferUrlInfoType = (urlInfo) => {
705
711
  }
706
712
  return "other";
707
713
  };
708
-
709
- const determineFileUrlForOutDirectory = (urlInfo) => {
710
- if (!urlInfo.context.outDirectoryUrl) {
711
- return urlInfo.url;
712
- }
713
- if (!urlInfo.url.startsWith("file:")) {
714
- return urlInfo.url;
715
- }
716
- let url = urlInfo.url;
717
- if (!urlIsInsideOf(urlInfo.url, urlInfo.context.rootDirectoryUrl)) {
718
- const fsRootUrl = ensureWindowsDriveLetter("file:///", urlInfo.url);
719
- url = `${urlInfo.context.rootDirectoryUrl}@fs/${url.slice(
720
- fsRootUrl.length,
721
- )}`;
722
- }
723
- if (urlInfo.filenameHint) {
724
- url = setUrlFilename(url, urlInfo.filenameHint);
725
- }
726
- return moveUrl({
727
- url,
728
- from: urlInfo.context.rootDirectoryUrl,
729
- to: urlInfo.context.outDirectoryUrl,
730
- });
731
- };
@@ -0,0 +1,45 @@
1
+ import { ensureWindowsDriveLetter } from "@jsenv/filesystem";
2
+ import { generateSourcemapFileUrl } from "@jsenv/sourcemap";
3
+ import { moveUrl, setUrlFilename, urlIsInsideOf } from "@jsenv/urls";
4
+
5
+ export const determineFileUrlForOutDirectory = (urlInfo) => {
6
+ let { url, filenameHint } = urlInfo;
7
+ const { rootDirectoryUrl, outDirectoryUrl } = urlInfo.context;
8
+ if (!outDirectoryUrl) {
9
+ return url;
10
+ }
11
+ if (!url.startsWith("file:")) {
12
+ return url;
13
+ }
14
+ if (!urlIsInsideOf(url, rootDirectoryUrl)) {
15
+ const fsRootUrl = ensureWindowsDriveLetter("file:///", url);
16
+ url = `${rootDirectoryUrl}@fs/${url.slice(fsRootUrl.length)}`;
17
+ }
18
+ if (filenameHint) {
19
+ url = setUrlFilename(url, filenameHint);
20
+ }
21
+ return moveUrl({
22
+ url,
23
+ from: rootDirectoryUrl,
24
+ to: outDirectoryUrl,
25
+ });
26
+ };
27
+
28
+ export const determineSourcemapFileUrl = (urlInfo) => {
29
+ // sourcemap is a special kind of reference:
30
+ // It's a reference to a content generated dynamically the content itself.
31
+ // when jsenv is done cooking the file
32
+ // during build it's urlInfo.url to be inside the build
33
+ // but otherwise it's generatedUrl to be inside .jsenv/ directory
34
+ const generatedUrlObject = new URL(urlInfo.generatedUrl);
35
+ generatedUrlObject.searchParams.delete("js_module_fallback");
36
+ generatedUrlObject.searchParams.delete("as_js_module");
37
+ generatedUrlObject.searchParams.delete("as_js_classic");
38
+ generatedUrlObject.searchParams.delete("as_css_module");
39
+ generatedUrlObject.searchParams.delete("as_json_module");
40
+ generatedUrlObject.searchParams.delete("as_text_module");
41
+ generatedUrlObject.searchParams.delete("dynamic_import");
42
+ generatedUrlObject.searchParams.delete("cjs_as_js_module");
43
+ const urlForSourcemap = generatedUrlObject.href;
44
+ return generateSourcemapFileUrl(urlForSourcemap);
45
+ };
@@ -310,7 +310,9 @@ const createReference = ({
310
310
  if (specifier instanceof URL) {
311
311
  specifier = specifier.href;
312
312
  } else {
313
- throw new TypeError(`"specifier" must be a string, got ${specifier}`);
313
+ throw new TypeError(
314
+ `"specifier" must be a string, got ${specifier} in ${ownerUrlInfo.url}`,
315
+ );
314
316
  }
315
317
  }
316
318
  const reference = {
@@ -715,7 +717,7 @@ const applyReferenceEffectsOnUrlInfo = (reference) => {
715
717
  }
716
718
  referencedUrlInfo.firstReference = reference;
717
719
  referencedUrlInfo.originalUrl =
718
- referencedUrlInfo.originalUrl || reference.url;
720
+ referencedUrlInfo.originalUrl || (reference.original || reference).url;
719
721
 
720
722
  if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
721
723
  referencedUrlInfo.isEntryPoint = true;
@@ -2,7 +2,6 @@ import { writeFileSync } from "@jsenv/filesystem";
2
2
  import {
3
3
  composeTwoSourcemaps,
4
4
  generateSourcemapDataUrl,
5
- generateSourcemapFileUrl,
6
5
  SOURCEMAP,
7
6
  } from "@jsenv/sourcemap";
8
7
  import { isFileSystemPath, urlToRelativeUrl } from "@jsenv/urls";
@@ -136,22 +135,6 @@ export const createUrlInfoTransformer = ({
136
135
  if (!may || !shouldHandle) {
137
136
  return;
138
137
  }
139
- // sourcemap is a special kind of reference:
140
- // It's a reference to a content generated dynamically the content itself.
141
- // when jsenv is done cooking the file
142
- // during build it's urlInfo.url to be inside the build
143
- // but otherwise it's generatedUrl to be inside .jsenv/ directory
144
- const generatedUrlObject = new URL(urlInfo.generatedUrl);
145
- generatedUrlObject.searchParams.delete("js_module_fallback");
146
- generatedUrlObject.searchParams.delete("as_js_module");
147
- generatedUrlObject.searchParams.delete("as_js_classic");
148
- generatedUrlObject.searchParams.delete("as_css_module");
149
- generatedUrlObject.searchParams.delete("as_json_module");
150
- generatedUrlObject.searchParams.delete("as_text_module");
151
- generatedUrlObject.searchParams.delete("dynamic_import");
152
- generatedUrlObject.searchParams.delete("cjs_as_js_module");
153
- const urlForSourcemap = generatedUrlObject.href;
154
- urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(urlForSourcemap);
155
138
 
156
139
  // case #1: already loaded during "load" hook
157
140
  // - happens during build
@@ -37,6 +37,7 @@ export const getCorePlugins = ({
37
37
  injections,
38
38
  transpilation = true,
39
39
  inlining = true,
40
+ http = false,
40
41
 
41
42
  clientAutoreload,
42
43
  cacheControl,
@@ -52,6 +53,12 @@ export const getCorePlugins = ({
52
53
  if (ribbon === true) {
53
54
  ribbon = {};
54
55
  }
56
+ if (http === true) {
57
+ http = { include: true };
58
+ }
59
+ if (http === false) {
60
+ http = { include: false };
61
+ }
55
62
 
56
63
  return [
57
64
  jsenvPluginReferenceAnalysis(referenceAnalysis),
@@ -66,11 +73,12 @@ export const getCorePlugins = ({
66
73
  - reference inside a js module -> resolved by node esm
67
74
  - All the rest uses web standard url resolution
68
75
  */
76
+ jsenvPluginProtocolHttp(http),
69
77
  jsenvPluginProtocolFile({
70
78
  magicExtensions,
71
79
  magicDirectoryIndex,
72
80
  }),
73
- jsenvPluginProtocolHttp(),
81
+
74
82
  ...(nodeEsmResolution
75
83
  ? [jsenvPluginNodeEsmResolution(nodeEsmResolution)]
76
84
  : []),
@@ -74,10 +74,18 @@ export const jsenvPluginFsRedirection = ({
74
74
  if (!stat) {
75
75
  return null;
76
76
  }
77
- const urlRaw = preserveSymlinks
78
- ? urlObject.href
79
- : resolveSymlink(urlObject.href);
80
- const resolvedUrl = `${urlRaw}${search}${hash}`;
77
+ const urlBeforeSymlinkResolution = urlObject.href;
78
+ if (preserveSymlinks) {
79
+ return `${urlBeforeSymlinkResolution}${search}${hash}`;
80
+ }
81
+ const urlAfterSymlinkResolution = resolveSymlink(
82
+ urlBeforeSymlinkResolution,
83
+ );
84
+ if (urlAfterSymlinkResolution !== urlBeforeSymlinkResolution) {
85
+ reference.leadsToASymlink = true;
86
+ // reference.baseUrl = urlBeforeSymlinkResolution;
87
+ }
88
+ const resolvedUrl = `${urlAfterSymlinkResolution}${search}${hash}`;
81
89
  return resolvedUrl;
82
90
  },
83
91
  };
@@ -61,17 +61,17 @@ export const jsenvPluginProtocolFile = ({
61
61
  return null;
62
62
  },
63
63
  formatReference: (reference) => {
64
- if (!reference.generatedUrl.startsWith("file:")) {
64
+ const { generatedUrl } = reference;
65
+ if (!generatedUrl.startsWith("file:")) {
65
66
  return null;
66
67
  }
67
68
  const { rootDirectoryUrl } = reference.ownerUrlInfo.context;
68
- if (urlIsInsideOf(reference.generatedUrl, rootDirectoryUrl)) {
69
- return `/${urlToRelativeUrl(
70
- reference.generatedUrl,
71
- rootDirectoryUrl,
72
- )}`;
69
+ if (urlIsInsideOf(generatedUrl, rootDirectoryUrl)) {
70
+ const result = `/${urlToRelativeUrl(generatedUrl, rootDirectoryUrl)}`;
71
+ return result;
73
72
  }
74
- return `/@fs/${reference.generatedUrl.slice("file:///".length)}`;
73
+ const result = `/@fs/${generatedUrl.slice("file:///".length)}`;
74
+ return result;
75
75
  },
76
76
  },
77
77
  {