@jsenv/plugin-bundling 2.8.4 → 2.8.6

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/plugin-bundling",
3
- "version": "2.8.4",
3
+ "version": "2.8.6",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,9 +23,9 @@
23
23
  "sideEffects": false,
24
24
  "dependencies": {
25
25
  "@jsenv/humanize": "1.3.1",
26
- "@jsenv/url-meta": "8.5.5",
27
- "@jsenv/urls": "2.6.3",
28
- "@jsenv/sourcemap": "1.3.2",
26
+ "@jsenv/url-meta": "8.5.6",
27
+ "@jsenv/urls": "2.7.0",
28
+ "@jsenv/sourcemap": "1.3.3",
29
29
  "lightningcss": "1.29.2",
30
30
  "rollup": "4.35.0"
31
31
  },
@@ -1,10 +1,13 @@
1
1
  import { lookupPackageDirectory, readPackageAtOrNull } from "@jsenv/filesystem";
2
2
  import { createDetailedMessage } from "@jsenv/humanize";
3
- import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
4
3
  import { isSpecifierForNodeBuiltin } from "@jsenv/node-esm-resolution/src/node_builtin_specifiers.js";
5
4
  import { sourcemapConverter } from "@jsenv/sourcemap";
6
5
  import { URL_META } from "@jsenv/url-meta";
7
- import { isFileSystemPath } from "@jsenv/urls";
6
+ import {
7
+ injectQueryParams,
8
+ isFileSystemPath,
9
+ urlToBasename,
10
+ } from "@jsenv/urls";
8
11
  import { readFileSync } from "node:fs";
9
12
  import { fileUrlConverter } from "../file_url_converter.js";
10
13
 
@@ -15,7 +18,8 @@ export const bundleJsModules = async (
15
18
  include,
16
19
  chunks = {},
17
20
  strictExports = false,
18
- preserveDynamicImport = false,
21
+ isolateDynamicImports = undefined,
22
+ preserveDynamicImports = false,
19
23
  augmentDynamicImportUrlSearchParams = () => {},
20
24
  rollup,
21
25
  rollupInput = {},
@@ -31,160 +35,199 @@ export const bundleJsModules = async (
31
35
  sourcemaps,
32
36
  isSupportedOnCurrentClients,
33
37
  getPluginMeta,
38
+ kitchen,
34
39
  } = jsModuleUrlInfos[0].context;
35
40
  const graph = jsModuleUrlInfos[0].graph;
36
41
  if (buildDirectoryUrl === undefined) {
37
42
  buildDirectoryUrl = jsModuleUrlInfos[0].context.buildDirectoryUrl;
38
43
  }
44
+ const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
45
+ if (isolateDynamicImports === undefined && nodeRuntimeEnabled) {
46
+ isolateDynamicImports = true;
47
+ }
39
48
 
40
- let manualChunks;
41
- if (chunks) {
42
- let workspaces;
43
- let packageName;
44
- const packageDirectoryUrl = lookupPackageDirectory(rootDirectoryUrl);
45
- if (packageDirectoryUrl) {
46
- const packageJSON = readPackageAtOrNull(packageDirectoryUrl);
47
- if (packageJSON) {
48
- packageName = packageJSON.name;
49
- workspaces = packageJSON.workspaces;
50
- }
51
- }
52
- let nodeModuleChunkName = "node_modules";
53
- let packagesChunkName = "packages";
49
+ const PATH_AND_URL_CONVERTER = {
50
+ asFileUrl: fileUrlConverter.asFileUrl,
51
+ asFilePath: fileUrlConverter.asFilePath,
52
+ };
54
53
 
55
- if (packageName) {
56
- let packageNameAsFilename = packageName
57
- .replaceAll("@", "")
58
- .replaceAll("-", "_")
59
- .replaceAll("/", "_");
60
- nodeModuleChunkName = `${packageNameAsFilename}_node_modules`;
61
- packagesChunkName = `${packageNameAsFilename}_packages`;
62
- }
63
- chunks[nodeModuleChunkName] = {
64
- "file:///**/node_modules/": true,
65
- ...chunks.vendors,
66
- };
67
- if (workspaces) {
68
- const workspacePatterns = {};
69
- for (const workspace of workspaces) {
70
- const workspacePattern = new URL(
71
- workspace.endsWith("/*") ? workspace.slice(0, -1) : workspace,
72
- packageDirectoryUrl,
73
- ).href;
74
- workspacePatterns[workspacePattern] = true;
54
+ if (isolateDynamicImports) {
55
+ PATH_AND_URL_CONVERTER.asFileUrl = (path, stripDynamicImportId) => {
56
+ const fileUrl = fileUrlConverter.asFileUrl(path);
57
+ if (!stripDynamicImportId) {
58
+ return fileUrl;
75
59
  }
76
- chunks[packagesChunkName] = {
77
- ...workspacePatterns,
78
- ...chunks.workspaces,
79
- };
80
- }
60
+ if (!fileUrl.includes("dynamic_import_id")) {
61
+ return fileUrl;
62
+ }
63
+ return injectQueryParams(fileUrl, {
64
+ dynamic_import_id: undefined,
65
+ });
66
+ };
67
+ }
81
68
 
82
- const associations = URL_META.resolveAssociations(chunks, rootDirectoryUrl);
83
- manualChunks = (id, manualChunksApi) => {
84
- if (rollupOutput.manualChunks) {
85
- const manualChunkName = rollupOutput.manualChunks(id, manualChunksApi);
86
- if (manualChunkName) {
87
- return manualChunkName;
69
+ const generateBundleWithRollup = async () => {
70
+ let manualChunks;
71
+ if (chunks) {
72
+ let workspaces;
73
+ let packageName;
74
+ const packageDirectoryUrl = lookupPackageDirectory(rootDirectoryUrl);
75
+ if (packageDirectoryUrl) {
76
+ const packageJSON = readPackageAtOrNull(packageDirectoryUrl);
77
+ if (packageJSON) {
78
+ packageName = packageJSON.name;
79
+ workspaces = packageJSON.workspaces;
88
80
  }
89
81
  }
90
- const moduleInfo = manualChunksApi.getModuleInfo(id);
91
- if (moduleInfo.isEntry || moduleInfo.dynamicImporters.length) {
92
- return null;
82
+ let nodeModuleChunkName = "node_modules";
83
+ let packagesChunkName = "packages";
84
+
85
+ if (packageName) {
86
+ let packageNameAsFilename = packageName
87
+ .replaceAll("@", "")
88
+ .replaceAll("-", "_")
89
+ .replaceAll("/", "_");
90
+ nodeModuleChunkName = `${packageNameAsFilename}_node_modules`;
91
+ packagesChunkName = `${packageNameAsFilename}_packages`;
93
92
  }
94
- const url = fileUrlConverter.asFileUrl(id);
95
- const urlObject = new URL(url);
96
- urlObject.search = "";
97
- const urlWithoutSearch = urlObject.href;
98
- const meta = URL_META.applyAssociations({
99
- url: urlWithoutSearch,
100
- associations,
101
- });
102
- for (const chunkNameCandidate of Object.keys(meta)) {
103
- if (meta[chunkNameCandidate]) {
104
- return chunkNameCandidate;
93
+ chunks[nodeModuleChunkName] = {
94
+ "file:///**/node_modules/": true,
95
+ ...chunks.vendors,
96
+ };
97
+ if (workspaces) {
98
+ const workspacePatterns = {};
99
+ for (const workspace of workspaces) {
100
+ const workspacePattern = new URL(
101
+ workspace.endsWith("/*") ? workspace.slice(0, -1) : workspace,
102
+ packageDirectoryUrl,
103
+ ).href;
104
+ workspacePatterns[workspacePattern] = true;
105
105
  }
106
+ chunks[packagesChunkName] = {
107
+ ...workspacePatterns,
108
+ ...chunks.workspaces,
109
+ };
106
110
  }
107
- return undefined;
108
- };
109
- }
110
111
 
111
- const resultRef = { current: null };
112
- const willMinifyJsModule = Boolean(getPluginMeta("willMinifyJsModule"));
113
- try {
114
- await applyRollupPlugins({
115
- rollup,
116
- rollupPlugins: [
117
- ...rollupPlugins,
118
- rollupPluginJsenv({
119
- signal,
120
- logger,
121
- rootDirectoryUrl,
122
- buildDirectoryUrl,
123
- graph,
124
- jsModuleUrlInfos,
125
-
126
- runtimeCompat,
127
- sourcemaps,
128
- include,
129
- preserveDynamicImport,
130
- augmentDynamicImportUrlSearchParams,
131
- strictExports,
132
- resultRef,
133
- }),
134
- ],
135
- rollupInput: {
136
- input: [],
137
- onwarn: (warning) => {
138
- if (warning.code === "CIRCULAR_DEPENDENCY") {
139
- return;
140
- }
141
- if (warning.code === "EVAL") {
142
- // ideally we should disable only for jsenv files
143
- return;
144
- }
145
- if (
146
- warning.code === "INVALID_ANNOTATION" &&
147
- warning.loc.file.includes("/node_modules/")
148
- ) {
149
- return;
112
+ const associations = URL_META.resolveAssociations(
113
+ chunks,
114
+ rootDirectoryUrl,
115
+ );
116
+ manualChunks = (id, manualChunksApi) => {
117
+ if (rollupOutput.manualChunks) {
118
+ const manualChunkName = rollupOutput.manualChunks(
119
+ id,
120
+ manualChunksApi,
121
+ );
122
+ if (manualChunkName) {
123
+ return manualChunkName;
150
124
  }
151
- if (
152
- warning.code === "EMPTY_BUNDLE" &&
153
- (warning.names.join("").endsWith("node_modules") ||
154
- warning.names.join("").endsWith("packages"))
155
- ) {
156
- return;
125
+ }
126
+ const moduleInfo = manualChunksApi.getModuleInfo(id);
127
+ if (moduleInfo.isEntry || moduleInfo.dynamicImporters.length) {
128
+ return null;
129
+ }
130
+ const url = PATH_AND_URL_CONVERTER.asFileUrl(id);
131
+ const urlObject = new URL(url);
132
+ urlObject.search = "";
133
+ const urlWithoutSearch = urlObject.href;
134
+ const meta = URL_META.applyAssociations({
135
+ url: urlWithoutSearch,
136
+ associations,
137
+ });
138
+ for (const chunkNameCandidate of Object.keys(meta)) {
139
+ if (meta[chunkNameCandidate]) {
140
+ return chunkNameCandidate;
157
141
  }
158
- logger.warn(String(warning));
142
+ }
143
+ return undefined;
144
+ };
145
+ }
146
+
147
+ const resultRef = { current: null };
148
+ const willMinifyJsModule = Boolean(getPluginMeta("willMinifyJsModule"));
149
+ try {
150
+ await applyRollupPlugins({
151
+ rollup,
152
+ rollupPlugins: [
153
+ ...rollupPlugins,
154
+ rollupPluginJsenv({
155
+ signal,
156
+ logger,
157
+ rootDirectoryUrl,
158
+ buildDirectoryUrl,
159
+ graph,
160
+ jsModuleUrlInfos,
161
+ PATH_AND_URL_CONVERTER,
162
+ kitchen,
163
+
164
+ runtimeCompat,
165
+ sourcemaps,
166
+ include,
167
+ preserveDynamicImports,
168
+ augmentDynamicImportUrlSearchParams,
169
+ isolateDynamicImports,
170
+ strictExports,
171
+ resultRef,
172
+ }),
173
+ ],
174
+ rollupInput: {
175
+ input: [],
176
+ onwarn: (warning) => {
177
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
178
+ return;
179
+ }
180
+ if (warning.code === "EVAL") {
181
+ // ideally we should disable only for jsenv files
182
+ return;
183
+ }
184
+ if (
185
+ warning.code === "INVALID_ANNOTATION" &&
186
+ warning.loc.file.includes("/node_modules/")
187
+ ) {
188
+ return;
189
+ }
190
+ if (
191
+ warning.code === "EMPTY_BUNDLE" &&
192
+ (warning.names.join("").endsWith("node_modules") ||
193
+ warning.names.join("").endsWith("packages"))
194
+ ) {
195
+ return;
196
+ }
197
+ logger.warn(String(warning));
198
+ },
199
+ ...rollupInput,
159
200
  },
160
- ...rollupInput,
161
- },
162
- rollupOutput: {
163
- compact: willMinifyJsModule,
164
- minifyInternalExports: willMinifyJsModule,
165
- generatedCode: {
166
- arrowFunctions: isSupportedOnCurrentClients("arrow_function"),
167
- constBindings: isSupportedOnCurrentClients("const_bindings"),
168
- objectShorthand: isSupportedOnCurrentClients(
169
- "object_properties_shorthand",
170
- ),
171
- reservedNamesAsProps: isSupportedOnCurrentClients("reserved_words"),
172
- symbols: isSupportedOnCurrentClients("symbols"),
201
+ rollupOutput: {
202
+ compact: willMinifyJsModule,
203
+ minifyInternalExports: willMinifyJsModule,
204
+ generatedCode: {
205
+ arrowFunctions: isSupportedOnCurrentClients("arrow_function"),
206
+ constBindings: isSupportedOnCurrentClients("const_bindings"),
207
+ objectShorthand: isSupportedOnCurrentClients(
208
+ "object_properties_shorthand",
209
+ ),
210
+ reservedNamesAsProps: isSupportedOnCurrentClients("reserved_words"),
211
+ symbols: isSupportedOnCurrentClients("symbols"),
212
+ },
213
+ ...rollupOutput,
214
+ manualChunks,
173
215
  },
174
- ...rollupOutput,
175
- manualChunks,
176
- },
177
- });
178
- return resultRef.current.jsModuleBundleUrlInfos;
179
- } catch (e) {
180
- if (e.code === "MISSING_EXPORT") {
181
- const detailedMessage = createDetailedMessage(e.message, {
182
- frame: e.frame,
183
216
  });
184
- throw new Error(detailedMessage, { cause: e });
217
+ return resultRef.current.jsModuleBundleUrlInfos;
218
+ } catch (e) {
219
+ if (e.code === "MISSING_EXPORT") {
220
+ const detailedMessage = createDetailedMessage(e.message, {
221
+ frame: e.frame,
222
+ });
223
+ throw new Error(detailedMessage, { cause: e });
224
+ }
225
+ throw e;
185
226
  }
186
- throw e;
187
- }
227
+ };
228
+
229
+ const jsModuleBundleUrlInfos = await generateBundleWithRollup();
230
+ return jsModuleBundleUrlInfos;
188
231
  };
189
232
 
190
233
  const rollupPluginJsenv = ({
@@ -193,11 +236,13 @@ const rollupPluginJsenv = ({
193
236
  buildDirectoryUrl,
194
237
  graph,
195
238
  jsModuleUrlInfos,
239
+ PATH_AND_URL_CONVERTER,
196
240
 
197
- runtimeCompat,
241
+ kitchen,
198
242
  sourcemaps,
199
243
  include,
200
- preserveDynamicImport,
244
+ preserveDynamicImports,
245
+ isolateDynamicImports,
201
246
  augmentDynamicImportUrlSearchParams,
202
247
  strictExports,
203
248
 
@@ -228,7 +273,7 @@ const rollupPluginJsenv = ({
228
273
  };
229
274
  }
230
275
 
231
- const getOriginalUrl = (rollupFileInfo) => {
276
+ const getOriginalUrl = (rollupFileInfo, stripDynamicImportId) => {
232
277
  if (
233
278
  // - explicitely emitted by emitChunk
234
279
  // - import.meta.resolve("")
@@ -238,13 +283,19 @@ const rollupPluginJsenv = ({
238
283
  ) {
239
284
  const { facadeModuleId } = rollupFileInfo;
240
285
  if (facadeModuleId) {
241
- return fileUrlConverter.asFileUrl(facadeModuleId);
286
+ return PATH_AND_URL_CONVERTER.asFileUrl(
287
+ facadeModuleId,
288
+ stripDynamicImportId,
289
+ );
242
290
  }
243
291
  }
244
292
  if (rollupFileInfo.isDynamicEntry) {
245
293
  const { moduleIds } = rollupFileInfo;
246
294
  const lastModuleId = moduleIds[moduleIds.length - 1];
247
- return fileUrlConverter.asFileUrl(lastModuleId);
295
+ return PATH_AND_URL_CONVERTER.asFileUrl(
296
+ lastModuleId,
297
+ stripDynamicImportId,
298
+ );
248
299
  }
249
300
  return new URL(rollupFileInfo.fileName, buildDirectoryUrl).href;
250
301
  };
@@ -265,34 +316,39 @@ const rollupPluginJsenv = ({
265
316
  "utf8",
266
317
  );
267
318
  const packageJSON = JSON.parse(packageFileContent);
268
- const value = packageJSON.sideEffects;
269
- if (Array.isArray(value)) {
270
- const sideEffectPatterns = {};
271
- for (const v of value) {
272
- sideEffectPatterns[v] = true;
273
- }
274
- const associations = URL_META.resolveAssociations(
275
- { sideEffects: sideEffectPatterns },
276
- packageDirectoryUrl,
277
- );
278
- const isMatching = (url) => {
279
- const meta = URL_META.applyAssociations({ url, associations });
280
- return meta.sideEffects || false;
281
- };
282
- packageSideEffectsCacheMap.set(packageDirectoryUrl, {
283
- value: isMatching,
284
- });
285
- } else {
286
- packageSideEffectsCacheMap.set(packageDirectoryUrl, { value });
287
- }
288
- return value;
319
+ return storePackageSideEffect(packageDirectoryUrl, packageJSON);
289
320
  } catch {
321
+ return storePackageSideEffect(packageDirectoryUrl, null);
322
+ }
323
+ };
324
+ const storePackageSideEffect = (packageDirectoryUrl, packageJson) => {
325
+ if (!packageJson) {
290
326
  packageSideEffectsCacheMap.set(packageDirectoryUrl, { value: undefined });
291
327
  return undefined;
292
328
  }
329
+ const value = packageJson.sideEffects;
330
+ if (Array.isArray(value)) {
331
+ const sideEffectPatterns = {};
332
+ for (const v of value) {
333
+ sideEffectPatterns[v] = true;
334
+ }
335
+ const associations = URL_META.resolveAssociations(
336
+ { sideEffects: sideEffectPatterns },
337
+ packageDirectoryUrl,
338
+ );
339
+ const isMatching = (url) => {
340
+ const meta = URL_META.applyAssociations({ url, associations });
341
+ return meta.sideEffects || false;
342
+ };
343
+ packageSideEffectsCacheMap.set(packageDirectoryUrl, {
344
+ value: isMatching,
345
+ });
346
+ return isMatching;
347
+ }
348
+ packageSideEffectsCacheMap.set(packageDirectoryUrl, { value });
349
+ return value;
293
350
  };
294
- const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node");
295
- const packageConditions = [nodeRuntimeEnabled ? "node" : "browser", "import"];
351
+
296
352
  const inferSideEffectsFromResolvedUrl = (url) => {
297
353
  if (url.startsWith("ignore:")) {
298
354
  // console.log(`may have side effect: ${url}`);
@@ -326,17 +382,43 @@ const rollupPluginJsenv = ({
326
382
  return inferSideEffectsFromResolvedUrl(url);
327
383
  }
328
384
  try {
329
- const result = applyNodeEsmResolution({
330
- conditions: packageConditions,
331
- parentUrl: importer,
332
- specifier: url,
333
- });
334
- return inferSideEffectsFromResolvedUrl(result.url);
385
+ const result = kitchen.resolve(url, importer);
386
+ if (result.packageDirectoryUrl) {
387
+ storePackageSideEffect(result.packageDirectoryUrl, result.packageJson);
388
+ }
389
+ return inferSideEffectsFromResolvedUrl(url);
335
390
  } catch {
336
391
  return null;
337
392
  }
338
393
  };
339
394
 
395
+ const resolveImport = (specifier, importer) => {
396
+ if (specifier[0] === "/") {
397
+ return new URL(specifier.slice(1), rootDirectoryUrl);
398
+ }
399
+ return new URL(specifier, importer);
400
+ };
401
+
402
+ const dynamicImportIdSet = new Set();
403
+ const assignDynamicImportId = (urlImportedDynamically) => {
404
+ const urlInfo = jsModuleUrlInfos[0].context.kitchen.graph.getUrlInfo(
405
+ urlImportedDynamically,
406
+ );
407
+ let dynamicImportIdBase =
408
+ urlInfo && urlInfo.filenameHint
409
+ ? filenameWithoutExtension(urlInfo.filenameHint)
410
+ : urlToBasename(urlImportedDynamically);
411
+ let dynamicImportIdCandidate = dynamicImportIdBase;
412
+ let positiveInteger = 1;
413
+ while (dynamicImportIdSet.has(dynamicImportIdCandidate)) {
414
+ dynamicImportIdCandidate = `${dynamicImportIdBase}_${positiveInteger}`;
415
+ positiveInteger++;
416
+ }
417
+ const dynamicImportId = dynamicImportIdCandidate;
418
+ dynamicImportIdSet.add(dynamicImportId);
419
+ return dynamicImportId;
420
+ };
421
+
340
422
  return {
341
423
  name: "jsenv",
342
424
  async buildStart() {
@@ -391,7 +473,7 @@ const rollupPluginJsenv = ({
391
473
  const createBundledFileInfo = (rollupFileInfo) => {
392
474
  const originalUrl = getOriginalUrl(rollupFileInfo);
393
475
  const sourceUrls = Object.keys(rollupFileInfo.modules).map((id) =>
394
- fileUrlConverter.asFileUrl(id),
476
+ PATH_AND_URL_CONVERTER.asFileUrl(id),
395
477
  );
396
478
 
397
479
  const specifierToUrlMap = new Map();
@@ -456,7 +538,7 @@ const rollupPluginJsenv = ({
456
538
  specifierToUrlMap.size > 0
457
539
  ? (reference) => {
458
540
  if (
459
- preserveDynamicImport &&
541
+ preserveDynamicImports &&
460
542
  reference.subtype === "dynamic_import"
461
543
  ) {
462
544
  // when dynamic import are preserved, no need to remap them
@@ -513,7 +595,7 @@ const rollupPluginJsenv = ({
513
595
  // const sourcemapFile = buildDirectoryUrl
514
596
  Object.assign(outputOptions, {
515
597
  format,
516
- dir: fileUrlConverter.asFilePath(rootDirectoryUrl),
598
+ dir: PATH_AND_URL_CONVERTER.asFilePath(rootDirectoryUrl),
517
599
  sourcemap: sourcemaps === "file" || sourcemaps === "inline",
518
600
  // sourcemapFile,
519
601
  sourcemapPathTransform: (relativePath) => {
@@ -524,7 +606,7 @@ const rollupPluginJsenv = ({
524
606
  },
525
607
  chunkFileNames: (chunkInfo) => {
526
608
  if (chunkInfo.isEntry) {
527
- const originalFileUrl = getOriginalUrl(chunkInfo);
609
+ const originalFileUrl = getOriginalUrl(chunkInfo, true);
528
610
  const jsModuleUrlInfo = jsModuleUrlInfos.find(
529
611
  (candidate) => candidate.url === originalFileUrl,
530
612
  );
@@ -532,87 +614,111 @@ const rollupPluginJsenv = ({
532
614
  return jsModuleUrlInfo.filenameHint;
533
615
  }
534
616
  }
617
+ if (chunkInfo.isDynamicEntry) {
618
+ const originalFileUrl = getOriginalUrl(chunkInfo, true);
619
+ const urlInfo =
620
+ jsModuleUrlInfos[0].context.kitchen.graph.getUrlInfo(
621
+ originalFileUrl,
622
+ );
623
+ if (urlInfo && urlInfo.filenameHint) {
624
+ return urlInfo.filenameHint;
625
+ }
626
+ }
535
627
  return `${chunkInfo.name}.js`;
536
628
  },
537
629
  });
538
630
  },
539
631
  // https://rollupjs.org/guide/en/#resolvedynamicimport
540
632
  resolveDynamicImport: (specifier, importer) => {
541
- if (!preserveDynamicImport) {
633
+ if (typeof specifier !== "string") {
634
+ // Receiving an ASTNode (specifier is dynamic)
542
635
  return null;
543
636
  }
544
- let urlObject;
545
- if (specifier[0] === "/") {
546
- urlObject = new URL(specifier.slice(1), rootDirectoryUrl);
547
- } else {
637
+ if (preserveDynamicImports) {
548
638
  if (isFileSystemPath(importer)) {
549
- importer = fileUrlConverter.asFileUrl(importer);
639
+ importer = PATH_AND_URL_CONVERTER.asFileUrl(importer);
550
640
  }
551
- urlObject = new URL(specifier, importer);
641
+ const urlObject = resolveImport(specifier, importer);
642
+ if (!urlObject.href.startsWith("file:")) {
643
+ return { id: specifier, external: true };
644
+ }
645
+ const searchParamsToAdd =
646
+ augmentDynamicImportUrlSearchParams(urlObject);
647
+ if (searchParamsToAdd) {
648
+ injectQueryParams(urlObject, searchParamsToAdd);
649
+ }
650
+ const id = urlObject.href;
651
+ return { id, external: true };
552
652
  }
553
- const searchParamsToAdd = augmentDynamicImportUrlSearchParams(urlObject);
554
- if (searchParamsToAdd) {
555
- Object.keys(searchParamsToAdd).forEach((key) => {
556
- const value = searchParamsToAdd[key];
557
- if (value === undefined) {
558
- urlObject.searchParams.delete(key);
559
- } else {
560
- urlObject.searchParams.set(key, value);
561
- }
653
+ if (isolateDynamicImports) {
654
+ if (isFileSystemPath(importer)) {
655
+ importer = PATH_AND_URL_CONVERTER.asFileUrl(importer);
656
+ }
657
+ const urlObject = resolveImport(specifier, importer);
658
+ if (!urlObject.href.startsWith("file:")) {
659
+ return { id: specifier, external: true };
660
+ }
661
+ const importId = assignDynamicImportId(urlObject.href);
662
+ injectQueryParams(urlObject, {
663
+ dynamic_import_id: importId,
562
664
  });
665
+ const url = urlObject.href;
666
+ const filePath = PATH_AND_URL_CONVERTER.asFilePath(url);
667
+ return { id: filePath };
563
668
  }
564
- return { external: true, id: urlObject.href };
669
+ return null;
565
670
  },
566
671
  resolveId: (specifier, importer = rootDirectoryUrl) => {
567
672
  if (isFileSystemPath(importer)) {
568
- importer = fileUrlConverter.asFileUrl(importer);
569
- }
570
- let url;
571
- if (specifier[0] === "/") {
572
- url = new URL(specifier.slice(1), rootDirectoryUrl).href;
573
- } else {
574
- url = new URL(specifier, importer).href;
673
+ importer = PATH_AND_URL_CONVERTER.asFileUrl(importer);
575
674
  }
576
-
577
- if (!url.startsWith("file:")) {
675
+ const resolvedUrlObject = resolveImport(specifier, importer);
676
+ const resolvedUrl = resolvedUrlObject.href;
677
+ if (!resolvedUrl.startsWith("file:")) {
578
678
  return {
579
- id: url,
679
+ id: resolvedUrl,
580
680
  external: true,
581
- moduleSideEffects: getModuleSideEffects(url, importer),
681
+ moduleSideEffects: getModuleSideEffects(resolvedUrl, importer),
582
682
  };
583
683
  }
584
- if (!importCanBeBundled(url)) {
684
+ if (!importCanBeBundled(resolvedUrl)) {
585
685
  return {
586
- id: url,
686
+ id: resolvedUrl,
587
687
  external: true,
588
- moduleSideEffects: getModuleSideEffects(url, importer),
688
+ moduleSideEffects: getModuleSideEffects(resolvedUrl, importer),
589
689
  };
590
690
  }
591
- const urlInfo = graph.getUrlInfo(url);
592
- if (!urlInfo) {
593
- // happen when excluded by referenceAnalysis.include
691
+ if (resolvedUrl.startsWith("ignore:")) {
594
692
  return {
595
- id: url,
693
+ id: resolvedUrl,
596
694
  external: true,
597
- moduleSideEffects: getModuleSideEffects(url, importer),
695
+ moduleSideEffects: getModuleSideEffects(resolvedUrl, importer),
598
696
  };
599
697
  }
600
- if (url.startsWith("ignore:")) {
601
- return {
602
- id: url,
603
- external: true,
604
- moduleSideEffects: getModuleSideEffects(url, importer),
605
- };
698
+ if (importer.includes("dynamic_import_id")) {
699
+ const importerUrlObject = new URL(importer);
700
+ const dynamicImportId =
701
+ importerUrlObject.searchParams.get("dynamic_import_id");
702
+ if (dynamicImportId) {
703
+ injectQueryParams(resolvedUrlObject, {
704
+ dynamic_import_id: dynamicImportId,
705
+ });
706
+ const isolatedResolvedUrl = resolvedUrlObject.href;
707
+ return {
708
+ id: PATH_AND_URL_CONVERTER.asFilePath(isolatedResolvedUrl),
709
+ external: false,
710
+ moduleSideEffects: getModuleSideEffects(resolvedUrl, importer),
711
+ };
712
+ }
606
713
  }
607
- const filePath = fileUrlConverter.asFilePath(url);
608
714
  return {
609
- id: filePath,
715
+ id: PATH_AND_URL_CONVERTER.asFilePath(resolvedUrl),
610
716
  external: false,
611
- moduleSideEffects: getModuleSideEffects(url, importer),
717
+ moduleSideEffects: getModuleSideEffects(resolvedUrl, importer),
612
718
  };
613
719
  },
614
720
  async load(rollupId) {
615
- const fileUrl = fileUrlConverter.asFileUrl(rollupId);
721
+ const fileUrl = PATH_AND_URL_CONVERTER.asFileUrl(rollupId, true);
616
722
  const urlInfo = graph.getUrlInfo(fileUrl);
617
723
  return {
618
724
  code: urlInfo.content,
@@ -647,3 +753,11 @@ const applyRollupPlugins = async ({
647
753
  const rollupOutputArray = await rollupReturnValue.generate(rollupOutput);
648
754
  return rollupOutputArray;
649
755
  };
756
+
757
+ const filenameWithoutExtension = (filename) => {
758
+ const dotLastIndex = filename.lastIndexOf(".");
759
+ if (dotLastIndex === -1) {
760
+ return filename;
761
+ }
762
+ return filename.slice(0, dotLastIndex);
763
+ };