@quilted/rollup 0.2.3 → 0.2.5

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/esm/app.mjs +151 -113
  3. package/build/esm/features/node.mjs +57 -0
  4. package/build/esm/features/react.mjs +22 -0
  5. package/build/esm/features/typescript.mjs +2 -2
  6. package/build/esm/index.mjs +1 -1
  7. package/build/esm/module.mjs +26 -27
  8. package/build/esm/package.mjs +36 -79
  9. package/build/esm/server.mjs +22 -25
  10. package/build/esm/shared/browserslist.mjs +2 -1
  11. package/build/esm/shared/project.mjs +100 -0
  12. package/build/esm/shared/rollup.mjs +4 -1
  13. package/build/tsconfig.tsbuildinfo +1 -1
  14. package/build/typescript/app.d.ts +64 -14
  15. package/build/typescript/app.d.ts.map +1 -1
  16. package/build/typescript/features/node.d.ts +4 -0
  17. package/build/typescript/features/node.d.ts.map +1 -0
  18. package/build/typescript/features/react.d.ts +28 -0
  19. package/build/typescript/features/react.d.ts.map +1 -0
  20. package/build/typescript/features/typescript.d.ts +1 -1
  21. package/build/typescript/features/typescript.d.ts.map +1 -1
  22. package/build/typescript/index.d.ts +1 -1
  23. package/build/typescript/index.d.ts.map +1 -1
  24. package/build/typescript/module.d.ts +3 -4
  25. package/build/typescript/module.d.ts.map +1 -1
  26. package/build/typescript/package.d.ts +3 -5
  27. package/build/typescript/package.d.ts.map +1 -1
  28. package/build/typescript/server.d.ts +4 -3
  29. package/build/typescript/server.d.ts.map +1 -1
  30. package/build/typescript/shared/browserslist.d.ts.map +1 -1
  31. package/build/typescript/shared/project.d.ts +33 -0
  32. package/build/typescript/shared/project.d.ts.map +1 -0
  33. package/build/typescript/shared/rollup.d.ts +2 -1
  34. package/build/typescript/shared/rollup.d.ts.map +1 -1
  35. package/package.json +19 -1
  36. package/source/app.ts +200 -141
  37. package/source/features/node.ts +74 -0
  38. package/source/features/react.ts +26 -0
  39. package/source/features/typescript.ts +1 -1
  40. package/source/index.ts +3 -1
  41. package/source/module.ts +27 -35
  42. package/source/package.ts +37 -109
  43. package/source/server.ts +25 -31
  44. package/source/shared/browserslist.ts +3 -1
  45. package/source/shared/project.ts +150 -0
  46. package/source/shared/rollup.ts +5 -1
  47. package/build/esm/shared/package-json.mjs +0 -16
  48. package/build/esm/shared/path.mjs +0 -7
  49. package/source/shared/package-json.ts +0 -20
  50. package/source/shared/path.ts +0 -5
package/source/app.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import * as path from 'path';
2
2
  import * as fs from 'fs/promises';
3
- import {glob} from 'glob';
4
3
  import {createRequire} from 'module';
5
4
 
6
- import type {Plugin, RollupOptions, GetManualChunk} from 'rollup';
5
+ import type {
6
+ Plugin,
7
+ RollupOptions,
8
+ InputPluginOption,
9
+ GetManualChunk,
10
+ } from 'rollup';
7
11
  import type {AssetsBuildManifest} from '@quilted/assets';
8
12
 
9
13
  import {
@@ -18,6 +22,7 @@ import {multiline} from './shared/strings.ts';
18
22
  import {
19
23
  getNodePlugins,
20
24
  removeBuildFiles,
25
+ normalizeRollupInput,
21
26
  type RollupNodePluginOptions,
22
27
  } from './shared/rollup.ts';
23
28
  import {createMagicModulePlugin} from './shared/magic-module.ts';
@@ -29,8 +34,7 @@ import {
29
34
  rollupGenerateOptionsForBrowsers,
30
35
  type BrowserGroupTargetSelection,
31
36
  } from './shared/browserslist.ts';
32
- import {loadPackageJSON, type PackageJSON} from './shared/package-json.ts';
33
- import {resolveRoot} from './shared/path.ts';
37
+ import {Project} from './shared/project.ts';
34
38
 
35
39
  export interface AppBaseOptions {
36
40
  /**
@@ -218,10 +222,17 @@ export interface AppServerOutputOptions
218
222
  format?: 'esmodules' | 'esm' | 'es' | 'commonjs' | 'cjs';
219
223
  }
220
224
 
225
+ export {
226
+ MAGIC_MODULE_ENTRY,
227
+ MAGIC_MODULE_APP_COMPONENT,
228
+ MAGIC_MODULE_BROWSER_ASSETS,
229
+ MAGIC_MODULE_REQUEST_ROUTER,
230
+ };
231
+
221
232
  const require = createRequire(import.meta.url);
222
233
 
223
- export async function quiltApp({
224
- root: rootPath = process.cwd(),
234
+ export async function quiltAppOptions({
235
+ root = process.cwd(),
225
236
  app,
226
237
  env,
227
238
  graphql,
@@ -229,9 +240,9 @@ export async function quiltApp({
229
240
  browser: browserOptions,
230
241
  server: serverOptions,
231
242
  }: AppOptions = {}) {
232
- const root = resolveRoot(rootPath);
243
+ const project = Project.load(root);
233
244
 
234
- const browserGroups = await getBrowserGroups({root});
245
+ const browserGroups = await getBrowserGroups({root: project.root});
235
246
  const browserGroupEntries = Object.entries(browserGroups);
236
247
  const hasMultipleBrowserGroups = browserGroupEntries.length > 1;
237
248
 
@@ -239,8 +250,8 @@ export async function quiltApp({
239
250
 
240
251
  browserGroupEntries.forEach(([name, browsers], index) => {
241
252
  optionPromises.push(
242
- quiltAppBrowser({
243
- root,
253
+ quiltAppBrowserOptions({
254
+ root: project.root,
244
255
  app,
245
256
  graphql,
246
257
  ...browserOptions,
@@ -262,12 +273,15 @@ export async function quiltApp({
262
273
  });
263
274
 
264
275
  optionPromises.push(
265
- quiltAppServer({
266
- root,
276
+ quiltAppServerOptions({
277
+ root: project.root,
267
278
  app,
268
279
  graphql,
269
280
  ...serverOptions,
270
- env: {...resolveEnvOption(env), ...resolveEnvOption(serverOptions?.env)},
281
+ env: {
282
+ ...resolveEnvOption(env),
283
+ ...resolveEnvOption(serverOptions?.env),
284
+ },
271
285
  assets: {...assets, ...serverOptions?.assets},
272
286
  }),
273
287
  );
@@ -275,8 +289,39 @@ export async function quiltApp({
275
289
  return Promise.all(optionPromises);
276
290
  }
277
291
 
292
+ export async function quiltAppBrowserOptions(options: AppBrowserOptions = {}) {
293
+ const {root = process.cwd(), assets} = options;
294
+ const project = Project.load(root);
295
+
296
+ const [plugins, browserGroup] = await Promise.all([
297
+ quiltAppBrowser(options),
298
+ getBrowserGroupTargetDetails(assets?.targets, {
299
+ root: project.root,
300
+ }),
301
+ ]);
302
+
303
+ const targetFilenamePart = browserGroup.name ? `.${browserGroup.name}` : '';
304
+ const [isESM, generatedCode] = await Promise.all([
305
+ targetsSupportModules(browserGroup.browsers),
306
+ rollupGenerateOptionsForBrowsers(browserGroup.browsers),
307
+ ]);
308
+
309
+ return {
310
+ plugins,
311
+ output: {
312
+ format: isESM ? 'esm' : 'systemjs',
313
+ dir: project.resolve(`build/assets`),
314
+ entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
315
+ assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
316
+ chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
317
+ manualChunks: createManualChunksSorter(),
318
+ generatedCode,
319
+ },
320
+ } satisfies RollupOptions;
321
+ }
322
+
278
323
  export async function quiltAppBrowser({
279
- root: rootPath = process.cwd(),
324
+ root = process.cwd(),
280
325
  app,
281
326
  entry,
282
327
  env,
@@ -284,14 +329,14 @@ export async function quiltAppBrowser({
284
329
  module,
285
330
  graphql = true,
286
331
  }: AppBrowserOptions = {}) {
287
- const root = resolveRoot(rootPath);
332
+ const project = Project.load(root);
288
333
  const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
289
334
  const minify = assets?.minify ?? mode === 'production';
290
335
  const baseURL = assets?.baseURL ?? '/assets/';
291
336
  const assetsInline = assets?.inline ?? true;
292
337
 
293
338
  const browserGroup = await getBrowserGroupTargetDetails(assets?.targets, {
294
- root,
339
+ root: project.root,
295
340
  });
296
341
  const targetFilenamePart = browserGroup.name ? `.${browserGroup.name}` : '';
297
342
 
@@ -299,7 +344,9 @@ export async function quiltAppBrowser({
299
344
  {visualizer},
300
345
  {magicModuleEnv, replaceProcessEnv},
301
346
  {sourceCode},
302
- {createTSConfigAliasPlugin},
347
+ {tsconfigAliases},
348
+ {monorepoPackageAliases},
349
+ {react},
303
350
  {css},
304
351
  {assetManifest, rawAssets, staticAssets},
305
352
  {asyncModules},
@@ -307,12 +354,13 @@ export async function quiltAppBrowser({
307
354
  {workers},
308
355
  {esnext},
309
356
  nodePlugins,
310
- packageJSON,
311
357
  ] = await Promise.all([
312
358
  import('rollup-plugin-visualizer'),
313
359
  import('./features/env.ts'),
314
360
  import('./features/source-code.ts'),
315
361
  import('./features/typescript.ts'),
362
+ import('./features/node.ts'),
363
+ import('./features/react.ts'),
316
364
  import('./features/css.ts'),
317
365
  import('./features/assets.ts'),
318
366
  import('./features/async.ts'),
@@ -320,10 +368,10 @@ export async function quiltAppBrowser({
320
368
  import('./features/workers.ts'),
321
369
  import('./features/esnext.ts'),
322
370
  getNodePlugins({bundle: true}),
323
- loadPackageJSON(root),
324
371
  ]);
325
372
 
326
- const plugins: Plugin[] = [
373
+ const plugins: InputPluginOption[] = [
374
+ quiltAppBrowserInput({root: project.root, entry}),
327
375
  ...nodePlugins,
328
376
  systemJS({minify}),
329
377
  replaceProcessEnv({mode}),
@@ -345,11 +393,12 @@ export async function quiltAppBrowser({
345
393
  },
346
394
  },
347
395
  }),
396
+ react(),
397
+ css({minify, emit: true}),
348
398
  esnext({
349
399
  mode,
350
400
  targets: browserGroup.browsers,
351
401
  }),
352
- css({minify, emit: true}),
353
402
  rawAssets(),
354
403
  staticAssets({
355
404
  baseURL,
@@ -363,36 +412,32 @@ export async function quiltAppBrowser({
363
412
  asyncModules({
364
413
  baseURL,
365
414
  preload: true,
366
- moduleID: ({imported}) => path.relative(root, imported),
415
+ moduleID: ({imported}) => path.relative(project.root, imported),
367
416
  }),
368
417
  workers({
369
418
  baseURL,
370
419
  outputOptions: {
371
420
  format: 'iife',
372
421
  inlineDynamicImports: true,
373
- dir: path.resolve(root, `build/assets`),
422
+ dir: project.resolve(`build/assets`),
374
423
  entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
375
424
  assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
376
425
  chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
377
426
  },
378
427
  }),
428
+ tsconfigAliases({root: project.root}),
429
+ monorepoPackageAliases({root: project.root}),
379
430
  ];
380
431
 
381
432
  if (assets?.clean ?? true) {
382
433
  plugins.push(
383
434
  removeBuildFiles(['build/assets', 'build/manifests', 'build/reports'], {
384
- root,
435
+ root: project.root,
385
436
  }),
386
437
  );
387
438
  }
388
439
 
389
- const tsconfigAliases = await createTSConfigAliasPlugin();
390
-
391
- if (tsconfigAliases) {
392
- plugins.push(tsconfigAliases);
393
- }
394
-
395
- const appEntry = await resolveAppEntry(app, {root, packageJSON});
440
+ const appEntry = await resolveAppEntry(app, project);
396
441
 
397
442
  if (appEntry) {
398
443
  plugins.push(magicModuleAppComponent({entry: appEntry}));
@@ -405,8 +450,7 @@ export async function quiltAppBrowser({
405
450
 
406
451
  plugins.push(
407
452
  graphql({
408
- manifest: path.resolve(
409
- root,
453
+ manifest: project.resolve(
410
454
  `build/manifests/graphql${targetFilenamePart}.json`,
411
455
  ),
412
456
  }),
@@ -428,67 +472,83 @@ export async function quiltAppBrowser({
428
472
  assetManifest({
429
473
  baseURL,
430
474
  cacheKey,
431
- file: path.resolve(
432
- root,
433
- `build/manifests/assets${targetFilenamePart}.json`,
434
- ),
475
+ file: project.resolve(`build/manifests/assets${targetFilenamePart}.json`),
435
476
  priority: assets?.priority,
436
477
  }),
437
478
  visualizer({
438
479
  template: 'treemap',
439
480
  open: false,
440
481
  brotliSize: true,
441
- filename: path.resolve(
442
- root,
482
+ filename: project.resolve(
443
483
  `build/reports/bundle-visualizer${targetFilenamePart}.html`,
444
484
  ),
445
485
  }),
446
486
  );
447
487
 
448
- const finalEntry = entry
449
- ? path.resolve(root, entry)
450
- : (await glob('{browser,client,web}.{ts,tsx,mjs,js,jsx}', {
451
- cwd: root,
452
- nodir: true,
453
- absolute: true,
454
- }).then((files) => files[0])) ?? MAGIC_MODULE_ENTRY;
488
+ return plugins;
489
+ }
455
490
 
456
- const isESM = await targetsSupportModules(browserGroup.browsers);
491
+ export function quiltAppBrowserInput({
492
+ root = process.cwd(),
493
+ entry,
494
+ }: Pick<AppBrowserOptions, 'root' | 'entry'> = {}) {
495
+ const project = Project.load(root);
457
496
 
458
497
  return {
459
- // If we are using the "magic entry", give it an explicit name of `browser`.
460
- // Otherwise, Rollup will use the file name as the output name.
461
- input:
462
- finalEntry === MAGIC_MODULE_ENTRY ? {browser: finalEntry} : finalEntry,
463
- plugins,
464
- onwarn(warning, defaultWarn) {
465
- // Removes annoying warnings for React-focused libraries that
466
- // include 'use client' directives.
467
- if (
468
- warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
469
- /['"]use client['"]/.test(warning.message)
470
- ) {
471
- return;
472
- }
473
-
474
- defaultWarn(warning);
498
+ name: '@quilted/app-browser/input',
499
+ async options(options) {
500
+ const finalEntry =
501
+ normalizeRollupInput(options.input) ??
502
+ (entry
503
+ ? project.resolve(entry)
504
+ : await project
505
+ .glob('{browser,client,web}.{ts,tsx,mjs,js,jsx}', {
506
+ nodir: true,
507
+ absolute: true,
508
+ })
509
+ .then((files) => files[0])) ??
510
+ MAGIC_MODULE_ENTRY;
511
+
512
+ return {
513
+ ...options,
514
+ // If we are using the "magic entry", give it an explicit name of `browser`.
515
+ // Otherwise, Rollup will use the file name as the output name.
516
+ input:
517
+ finalEntry === MAGIC_MODULE_ENTRY
518
+ ? {browser: finalEntry}
519
+ : finalEntry,
520
+ };
475
521
  },
522
+ } satisfies Plugin;
523
+ }
524
+
525
+ export async function quiltAppServerOptions(options: AppServerOptions = {}) {
526
+ const {root = process.cwd(), output} = options;
527
+
528
+ const project = Project.load(root);
529
+ const hash = output?.hash ?? 'async-only';
530
+ const outputFormat = output?.format ?? 'esmodules';
531
+
532
+ const plugins = await quiltAppServer(options);
533
+
534
+ return {
535
+ plugins,
476
536
  output: {
477
- format: isESM ? 'esm' : 'systemjs',
478
- dir: path.resolve(root, `build/assets`),
479
- entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
480
- assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
481
- chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
482
- manualChunks: createManualChunksSorter(),
483
- generatedCode: await rollupGenerateOptionsForBrowsers(
484
- browserGroup.browsers,
485
- ),
537
+ format:
538
+ outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
539
+ dir: project.resolve(`build/server`),
540
+ entryFileNames: `[name]${hash === true ? `.[hash]` : ''}.js`,
541
+ chunkFileNames: `[name]${
542
+ hash === true || hash === 'async-only' ? `.[hash]` : ''
543
+ }.js`,
544
+ assetFileNames: `[name]${hash === true ? `.[hash]` : ''}.[ext]`,
545
+ generatedCode: 'es2015',
486
546
  },
487
547
  } satisfies RollupOptions;
488
548
  }
489
549
 
490
550
  export async function quiltAppServer({
491
- root: rootPath = process.cwd(),
551
+ root = process.cwd(),
492
552
  app,
493
553
  env,
494
554
  entry,
@@ -497,7 +557,7 @@ export async function quiltAppServer({
497
557
  assets,
498
558
  output,
499
559
  }: AppServerOptions = {}) {
500
- const root = resolveRoot(rootPath);
560
+ const project = Project.load(root);
501
561
  const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
502
562
 
503
563
  const baseURL = assets?.baseURL ?? '/assets/';
@@ -505,34 +565,35 @@ export async function quiltAppServer({
505
565
 
506
566
  const bundle = output?.bundle;
507
567
  const minify = output?.minify ?? false;
508
- const hash = output?.hash ?? 'async-only';
509
- const outputFormat = output?.format ?? 'esmodules';
510
568
 
511
569
  const [
512
570
  {visualizer},
513
571
  {magicModuleEnv, replaceProcessEnv},
514
572
  {sourceCode},
515
- {createTSConfigAliasPlugin},
573
+ {react},
574
+ {tsconfigAliases},
575
+ {monorepoPackageAliases},
516
576
  {css},
517
577
  {rawAssets, staticAssets},
518
578
  {asyncModules},
519
579
  {esnext},
520
580
  nodePlugins,
521
- packageJSON,
522
581
  ] = await Promise.all([
523
582
  import('rollup-plugin-visualizer'),
524
583
  import('./features/env.ts'),
525
584
  import('./features/source-code.ts'),
585
+ import('./features/react.ts'),
526
586
  import('./features/typescript.ts'),
587
+ import('./features/node.ts'),
527
588
  import('./features/css.ts'),
528
589
  import('./features/assets.ts'),
529
590
  import('./features/async.ts'),
530
591
  import('./features/esnext.ts'),
531
592
  getNodePlugins({bundle}),
532
- loadPackageJSON(root),
533
593
  ]);
534
594
 
535
- const plugins: Plugin[] = [
595
+ const plugins: InputPluginOption[] = [
596
+ quiltAppServerInput({root: project.root, entry, format}),
536
597
  ...nodePlugins,
537
598
  replaceProcessEnv({mode}),
538
599
  magicModuleEnv({...resolveEnvOption(env), mode}),
@@ -552,6 +613,7 @@ export async function quiltAppServer({
552
613
  },
553
614
  },
554
615
  }),
616
+ react(),
555
617
  esnext({
556
618
  mode,
557
619
  targets: ['current node'],
@@ -570,35 +632,27 @@ export async function quiltAppServer({
570
632
  asyncModules({
571
633
  baseURL,
572
634
  preload: false,
573
- moduleID: ({imported}) => path.relative(root, imported),
635
+ moduleID: ({imported}) => path.relative(project.root, imported),
574
636
  }),
575
- removeBuildFiles(['build/server'], {root}),
637
+ removeBuildFiles(['build/server'], {root: project.root}),
638
+ tsconfigAliases({root: project.root}),
639
+ monorepoPackageAliases({root: project.root}),
576
640
  ];
577
641
 
578
- const tsconfigAliases = await createTSConfigAliasPlugin();
579
-
580
- if (tsconfigAliases) {
581
- plugins.push(tsconfigAliases);
582
- }
583
-
584
- const appEntry = await resolveAppEntry(app, {root, packageJSON});
642
+ const appEntry = await resolveAppEntry(app, project);
585
643
 
586
644
  if (appEntry) {
587
645
  plugins.push(magicModuleAppComponent({entry: appEntry}));
588
646
  }
589
647
 
590
648
  const serverEntry = entry
591
- ? path.resolve(root, entry)
592
- : await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
593
- cwd: root,
594
- nodir: true,
595
- absolute: true,
596
- }).then((files) => files[0]);
597
-
598
- const finalEntry =
599
- format === 'request-router'
600
- ? MAGIC_MODULE_ENTRY
601
- : serverEntry ?? MAGIC_MODULE_ENTRY;
649
+ ? project.resolve(entry)
650
+ : await project
651
+ .glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
652
+ nodir: true,
653
+ absolute: true,
654
+ })
655
+ .then((files) => files[0]);
602
656
 
603
657
  plugins.push(
604
658
  magicModuleAppServerEntry({
@@ -623,43 +677,50 @@ export async function quiltAppServer({
623
677
  template: 'treemap',
624
678
  open: false,
625
679
  brotliSize: false,
626
- filename: path.resolve(
627
- root,
628
- `build/reports/bundle-visualizer.server.html`,
629
- ),
680
+ filename: project.resolve(`build/reports/bundle-visualizer.server.html`),
630
681
  }),
631
682
  );
632
683
 
684
+ return plugins;
685
+ }
686
+
687
+ export function quiltAppServerInput({
688
+ root = process.cwd(),
689
+ entry,
690
+ format = 'request-router',
691
+ }: Pick<AppServerOptions, 'root' | 'entry' | 'format'> = {}) {
692
+ const project = Project.load(root);
693
+
633
694
  return {
634
- // If we are using the "magic entry", give it an explicit name of `server`.
635
- // Otherwise, Rollup will use the file name as the output name.
636
- input:
637
- finalEntry === MAGIC_MODULE_ENTRY ? {server: finalEntry} : finalEntry,
638
- plugins,
639
- onwarn(warning, defaultWarn) {
640
- // Removes annoying warnings for React-focused libraries that
641
- // include 'use client' directives.
642
- if (
643
- warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
644
- /['"]use client['"]/.test(warning.message)
645
- ) {
646
- return;
695
+ name: '@quilted/app-server/input',
696
+ async options(options) {
697
+ let finalEntry = normalizeRollupInput(options.input);
698
+
699
+ if (!finalEntry) {
700
+ const serverEntry = entry
701
+ ? project.resolve(entry)
702
+ : await project
703
+ .glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
704
+ nodir: true,
705
+ absolute: true,
706
+ })
707
+ .then((files) => files[0]);
708
+
709
+ finalEntry =
710
+ format === 'request-router'
711
+ ? MAGIC_MODULE_ENTRY
712
+ : serverEntry ?? MAGIC_MODULE_ENTRY;
647
713
  }
648
714
 
649
- defaultWarn(warning);
650
- },
651
- output: {
652
- format:
653
- outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
654
- dir: path.resolve(root, `build/server`),
655
- entryFileNames: `[name]${hash === true ? `.[hash]` : ''}.js`,
656
- chunkFileNames: `[name]${
657
- hash === true || hash === 'async-only' ? `.[hash]` : ''
658
- }.js`,
659
- assetFileNames: `[name]${hash === true ? `.[hash]` : ''}.[ext]`,
660
- generatedCode: 'es2015',
715
+ return {
716
+ ...options,
717
+ // If we are using the "magic entry", give it an explicit name of `server`.
718
+ // Otherwise, Rollup will use the file name as the output name.
719
+ input:
720
+ finalEntry === MAGIC_MODULE_ENTRY ? {server: finalEntry} : finalEntry,
721
+ };
661
722
  },
662
- } satisfies RollupOptions;
723
+ } satisfies Plugin;
663
724
  }
664
725
 
665
726
  export function magicModuleAppComponent({entry}: {entry: string}) {
@@ -981,26 +1042,24 @@ function createManualChunksSorter(): GetManualChunk {
981
1042
  };
982
1043
  }
983
1044
 
984
- async function resolveAppEntry(
985
- entry: string | undefined,
986
- {root, packageJSON}: {root: string; packageJSON: PackageJSON},
987
- ) {
1045
+ async function resolveAppEntry(entry: string | undefined, project: Project) {
988
1046
  if (entry) {
989
- return path.resolve(root, entry);
1047
+ return project.resolve(entry);
990
1048
  }
991
1049
 
992
- if (typeof packageJSON.main === 'string') {
993
- return path.resolve(root, packageJSON.main);
1050
+ const {packageJSON} = project;
1051
+
1052
+ if (typeof packageJSON.raw.main === 'string') {
1053
+ return project.resolve(packageJSON.raw.main);
994
1054
  }
995
1055
 
996
- const rootEntry = (packageJSON.exports as any)?.['.'];
1056
+ const rootEntry = (packageJSON.raw.exports as any)?.['.'];
997
1057
 
998
1058
  if (typeof rootEntry === 'string') {
999
- return path.resolve(root, rootEntry);
1059
+ return project.resolve(rootEntry);
1000
1060
  }
1001
1061
 
1002
- const globbed = await glob('{App,app,index}.{ts,tsx,mjs,js,jsx}', {
1003
- cwd: root,
1062
+ const globbed = await project.glob('{App,app,index}.{ts,tsx,mjs,js,jsx}', {
1004
1063
  nodir: true,
1005
1064
  absolute: true,
1006
1065
  });
@@ -0,0 +1,74 @@
1
+ import {realpathSync} from 'fs';
2
+
3
+ import {Project, sourceEntriesForProject} from '../shared/project.ts';
4
+
5
+ export async function monorepoPackageAliases({
6
+ root = process.cwd(),
7
+ }: {root?: string} = {}) {
8
+ const project = Project.load(root);
9
+ const seenDependencies = new Set<string>();
10
+ const seenProjects = new Set<Project>();
11
+
12
+ function processProject(project: Project) {
13
+ const {dependencies, devDependencies} = project.packageJSON.raw;
14
+
15
+ for (const pkg of Object.keys({...dependencies, ...devDependencies})) {
16
+ if (seenDependencies.has(pkg)) continue;
17
+
18
+ seenDependencies.add(pkg);
19
+
20
+ let packageRoot: string | undefined;
21
+
22
+ try {
23
+ packageRoot = realpathSync(project.resolve('node_modules', pkg));
24
+ } catch {
25
+ // intentional noop
26
+ }
27
+
28
+ if (
29
+ packageRoot == null ||
30
+ packageRoot.includes('node_modules') ||
31
+ packageRoot === root
32
+ ) {
33
+ continue;
34
+ }
35
+
36
+ const packageProject = Project.load(packageRoot);
37
+ if (seenProjects.has(packageProject)) continue;
38
+
39
+ seenProjects.add(packageProject);
40
+ processProject(packageProject);
41
+ }
42
+ }
43
+
44
+ processProject(project);
45
+
46
+ const [{default: alias}, projectsWithEntries] = await Promise.all([
47
+ import('@rollup/plugin-alias'),
48
+ Promise.all(
49
+ Array.from(seenProjects, async (project) => {
50
+ const entries = await sourceEntriesForProject(project);
51
+ return {project, entries};
52
+ }),
53
+ ),
54
+ ]);
55
+
56
+ const aliases: import('@rollup/plugin-alias').Alias[] = [];
57
+
58
+ for (const {project, entries} of projectsWithEntries) {
59
+ const {name} = project;
60
+
61
+ for (const [entry, source] of Object.entries(entries)) {
62
+ const entryName = entry === '.' ? name : `${name}/${entry}`;
63
+
64
+ aliases.push({
65
+ find: new RegExp(`^${entryName}$`),
66
+ replacement: source,
67
+ });
68
+ }
69
+ }
70
+
71
+ return alias({
72
+ entries: aliases,
73
+ });
74
+ }