@quilted/rollup 0.2.4 → 0.2.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/esm/app.mjs +130 -125
  3. package/build/esm/features/node.mjs +57 -0
  4. package/build/esm/module.mjs +21 -22
  5. package/build/esm/package.mjs +36 -79
  6. package/build/esm/server.mjs +16 -25
  7. package/build/esm/shared/magic-module.mjs +5 -3
  8. package/build/esm/shared/project.mjs +100 -0
  9. package/build/tsconfig.tsbuildinfo +1 -1
  10. package/build/typescript/app.d.ts +23 -18
  11. package/build/typescript/app.d.ts.map +1 -1
  12. package/build/typescript/features/env.d.ts +3 -5
  13. package/build/typescript/features/env.d.ts.map +1 -1
  14. package/build/typescript/features/node.d.ts +4 -0
  15. package/build/typescript/features/node.d.ts.map +1 -0
  16. package/build/typescript/features/request-router.d.ts +2 -2
  17. package/build/typescript/module.d.ts +1 -1
  18. package/build/typescript/module.d.ts.map +1 -1
  19. package/build/typescript/package.d.ts +3 -5
  20. package/build/typescript/package.d.ts.map +1 -1
  21. package/build/typescript/server.d.ts +0 -1
  22. package/build/typescript/server.d.ts.map +1 -1
  23. package/build/typescript/shared/magic-module.d.ts +3 -3
  24. package/build/typescript/shared/magic-module.d.ts.map +1 -1
  25. package/build/typescript/shared/project.d.ts +33 -0
  26. package/build/typescript/shared/project.d.ts.map +1 -0
  27. package/package.json +19 -1
  28. package/source/app.ts +158 -154
  29. package/source/features/node.ts +74 -0
  30. package/source/module.ts +20 -22
  31. package/source/package.ts +37 -109
  32. package/source/server.ts +16 -30
  33. package/source/shared/magic-module.ts +10 -4
  34. package/source/shared/project.ts +150 -0
  35. package/build/esm/shared/package-json.mjs +0 -16
  36. package/build/esm/shared/path.mjs +0 -7
  37. package/source/shared/package-json.ts +0 -20
  38. package/source/shared/path.ts +0 -5
package/source/app.ts CHANGED
@@ -1,6 +1,5 @@
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
5
  import type {
@@ -35,8 +34,7 @@ import {
35
34
  rollupGenerateOptionsForBrowsers,
36
35
  type BrowserGroupTargetSelection,
37
36
  } from './shared/browserslist.ts';
38
- import {loadPackageJSON, type PackageJSON} from './shared/package-json.ts';
39
- import {resolveRoot} from './shared/path.ts';
37
+ import {Project} from './shared/project.ts';
40
38
 
41
39
  export interface AppBaseOptions {
42
40
  /**
@@ -234,7 +232,7 @@ export {
234
232
  const require = createRequire(import.meta.url);
235
233
 
236
234
  export async function quiltAppOptions({
237
- root: rootPath = process.cwd(),
235
+ root = process.cwd(),
238
236
  app,
239
237
  env,
240
238
  graphql,
@@ -242,9 +240,9 @@ export async function quiltAppOptions({
242
240
  browser: browserOptions,
243
241
  server: serverOptions,
244
242
  }: AppOptions = {}) {
245
- const root = resolveRoot(rootPath);
243
+ const project = Project.load(root);
246
244
 
247
- const browserGroups = await getBrowserGroups({root});
245
+ const browserGroups = await getBrowserGroups({root: project.root});
248
246
  const browserGroupEntries = Object.entries(browserGroups);
249
247
  const hasMultipleBrowserGroups = browserGroupEntries.length > 1;
250
248
 
@@ -253,7 +251,7 @@ export async function quiltAppOptions({
253
251
  browserGroupEntries.forEach(([name, browsers], index) => {
254
252
  optionPromises.push(
255
253
  quiltAppBrowserOptions({
256
- root,
254
+ root: project.root,
257
255
  app,
258
256
  graphql,
259
257
  ...browserOptions,
@@ -276,7 +274,7 @@ export async function quiltAppOptions({
276
274
 
277
275
  optionPromises.push(
278
276
  quiltAppServerOptions({
279
- root,
277
+ root: project.root,
280
278
  app,
281
279
  graphql,
282
280
  ...serverOptions,
@@ -292,13 +290,13 @@ export async function quiltAppOptions({
292
290
  }
293
291
 
294
292
  export async function quiltAppBrowserOptions(options: AppBrowserOptions = {}) {
295
- const {root: rootPath = process.cwd(), assets} = options;
296
- const root = resolveRoot(rootPath);
293
+ const {root = process.cwd(), assets} = options;
294
+ const project = Project.load(root);
297
295
 
298
296
  const [plugins, browserGroup] = await Promise.all([
299
297
  quiltAppBrowser(options),
300
298
  getBrowserGroupTargetDetails(assets?.targets, {
301
- root,
299
+ root: project.root,
302
300
  }),
303
301
  ]);
304
302
 
@@ -312,7 +310,7 @@ export async function quiltAppBrowserOptions(options: AppBrowserOptions = {}) {
312
310
  plugins,
313
311
  output: {
314
312
  format: isESM ? 'esm' : 'systemjs',
315
- dir: path.resolve(root, `build/assets`),
313
+ dir: project.resolve(`build/assets`),
316
314
  entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
317
315
  assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
318
316
  chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
@@ -323,7 +321,7 @@ export async function quiltAppBrowserOptions(options: AppBrowserOptions = {}) {
323
321
  }
324
322
 
325
323
  export async function quiltAppBrowser({
326
- root: rootPath = process.cwd(),
324
+ root = process.cwd(),
327
325
  app,
328
326
  entry,
329
327
  env,
@@ -331,14 +329,14 @@ export async function quiltAppBrowser({
331
329
  module,
332
330
  graphql = true,
333
331
  }: AppBrowserOptions = {}) {
334
- const root = resolveRoot(rootPath);
332
+ const project = Project.load(root);
335
333
  const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
336
334
  const minify = assets?.minify ?? mode === 'production';
337
335
  const baseURL = assets?.baseURL ?? '/assets/';
338
336
  const assetsInline = assets?.inline ?? true;
339
337
 
340
338
  const browserGroup = await getBrowserGroupTargetDetails(assets?.targets, {
341
- root,
339
+ root: project.root,
342
340
  });
343
341
  const targetFilenamePart = browserGroup.name ? `.${browserGroup.name}` : '';
344
342
 
@@ -347,6 +345,7 @@ export async function quiltAppBrowser({
347
345
  {magicModuleEnv, replaceProcessEnv},
348
346
  {sourceCode},
349
347
  {tsconfigAliases},
348
+ {monorepoPackageAliases},
350
349
  {react},
351
350
  {css},
352
351
  {assetManifest, rawAssets, staticAssets},
@@ -355,12 +354,12 @@ export async function quiltAppBrowser({
355
354
  {workers},
356
355
  {esnext},
357
356
  nodePlugins,
358
- packageJSON,
359
357
  ] = await Promise.all([
360
358
  import('rollup-plugin-visualizer'),
361
359
  import('./features/env.ts'),
362
360
  import('./features/source-code.ts'),
363
361
  import('./features/typescript.ts'),
362
+ import('./features/node.ts'),
364
363
  import('./features/react.ts'),
365
364
  import('./features/css.ts'),
366
365
  import('./features/assets.ts'),
@@ -369,15 +368,16 @@ export async function quiltAppBrowser({
369
368
  import('./features/workers.ts'),
370
369
  import('./features/esnext.ts'),
371
370
  getNodePlugins({bundle: true}),
372
- loadPackageJSON(root),
373
371
  ]);
374
372
 
375
373
  const plugins: InputPluginOption[] = [
376
- quiltAppBrowserInput({root, entry}),
374
+ quiltAppBrowserInput({root: project.root, entry}),
377
375
  ...nodePlugins,
378
376
  systemJS({minify}),
379
377
  replaceProcessEnv({mode}),
380
378
  magicModuleEnv({...resolveEnvOption(env), mode}),
379
+ magicModuleAppComponent({entry: app, root: project.root}),
380
+ magicModuleAppBrowserEntry(module),
381
381
  sourceCode({
382
382
  mode,
383
383
  targets: browserGroup.browsers,
@@ -414,45 +414,37 @@ export async function quiltAppBrowser({
414
414
  asyncModules({
415
415
  baseURL,
416
416
  preload: true,
417
- moduleID: ({imported}) => path.relative(root, imported),
417
+ moduleID: ({imported}) => path.relative(project.root, imported),
418
418
  }),
419
419
  workers({
420
420
  baseURL,
421
421
  outputOptions: {
422
422
  format: 'iife',
423
423
  inlineDynamicImports: true,
424
- dir: path.resolve(root, `build/assets`),
424
+ dir: project.resolve(`build/assets`),
425
425
  entryFileNames: `[name]${targetFilenamePart}.[hash].js`,
426
426
  assetFileNames: `[name]${targetFilenamePart}.[hash].[ext]`,
427
427
  chunkFileNames: `[name]${targetFilenamePart}.[hash].js`,
428
428
  },
429
429
  }),
430
- tsconfigAliases({root}),
430
+ tsconfigAliases({root: project.root}),
431
+ monorepoPackageAliases({root: project.root}),
431
432
  ];
432
433
 
433
434
  if (assets?.clean ?? true) {
434
435
  plugins.push(
435
436
  removeBuildFiles(['build/assets', 'build/manifests', 'build/reports'], {
436
- root,
437
+ root: project.root,
437
438
  }),
438
439
  );
439
440
  }
440
441
 
441
- const appEntry = await resolveAppEntry(app, {root, packageJSON});
442
-
443
- if (appEntry) {
444
- plugins.push(magicModuleAppComponent({entry: appEntry}));
445
- }
446
-
447
- plugins.push(magicModuleAppBrowserEntry(module));
448
-
449
442
  if (graphql) {
450
443
  const {graphql} = await import('./features/graphql.ts');
451
444
 
452
445
  plugins.push(
453
446
  graphql({
454
- manifest: path.resolve(
455
- root,
447
+ manifest: project.resolve(
456
448
  `build/manifests/graphql${targetFilenamePart}.json`,
457
449
  ),
458
450
  }),
@@ -474,18 +466,14 @@ export async function quiltAppBrowser({
474
466
  assetManifest({
475
467
  baseURL,
476
468
  cacheKey,
477
- file: path.resolve(
478
- root,
479
- `build/manifests/assets${targetFilenamePart}.json`,
480
- ),
469
+ file: project.resolve(`build/manifests/assets${targetFilenamePart}.json`),
481
470
  priority: assets?.priority,
482
471
  }),
483
472
  visualizer({
484
473
  template: 'treemap',
485
474
  open: false,
486
475
  brotliSize: true,
487
- filename: path.resolve(
488
- root,
476
+ filename: project.resolve(
489
477
  `build/reports/bundle-visualizer${targetFilenamePart}.html`,
490
478
  ),
491
479
  }),
@@ -495,23 +483,15 @@ export async function quiltAppBrowser({
495
483
  }
496
484
 
497
485
  export function quiltAppBrowserInput({
498
- root: rootPath = process.cwd(),
486
+ root,
499
487
  entry,
500
488
  }: Pick<AppBrowserOptions, 'root' | 'entry'> = {}) {
501
- const root = resolveRoot(rootPath);
502
-
503
489
  return {
504
490
  name: '@quilted/app-browser/input',
505
491
  async options(options) {
506
492
  const finalEntry =
507
493
  normalizeRollupInput(options.input) ??
508
- (entry
509
- ? path.resolve(root, entry)
510
- : await glob('{browser,client,web}.{ts,tsx,mjs,js,jsx}', {
511
- cwd: root,
512
- nodir: true,
513
- absolute: true,
514
- }).then((files) => files[0])) ??
494
+ (await sourceForAppBrowser({entry, root})) ??
515
495
  MAGIC_MODULE_ENTRY;
516
496
 
517
497
  return {
@@ -528,9 +508,9 @@ export function quiltAppBrowserInput({
528
508
  }
529
509
 
530
510
  export async function quiltAppServerOptions(options: AppServerOptions = {}) {
531
- const {root: rootPath = process.cwd(), output} = options;
511
+ const {root = process.cwd(), output} = options;
532
512
 
533
- const root = resolveRoot(rootPath);
513
+ const project = Project.load(root);
534
514
  const hash = output?.hash ?? 'async-only';
535
515
  const outputFormat = output?.format ?? 'esmodules';
536
516
 
@@ -541,7 +521,7 @@ export async function quiltAppServerOptions(options: AppServerOptions = {}) {
541
521
  output: {
542
522
  format:
543
523
  outputFormat === 'commonjs' || outputFormat === 'cjs' ? 'cjs' : 'esm',
544
- dir: path.resolve(root, `build/server`),
524
+ dir: project.resolve(`build/server`),
545
525
  entryFileNames: `[name]${hash === true ? `.[hash]` : ''}.js`,
546
526
  chunkFileNames: `[name]${
547
527
  hash === true || hash === 'async-only' ? `.[hash]` : ''
@@ -553,7 +533,7 @@ export async function quiltAppServerOptions(options: AppServerOptions = {}) {
553
533
  }
554
534
 
555
535
  export async function quiltAppServer({
556
- root: rootPath = process.cwd(),
536
+ root = process.cwd(),
557
537
  app,
558
538
  env,
559
539
  entry,
@@ -562,7 +542,7 @@ export async function quiltAppServer({
562
542
  assets,
563
543
  output,
564
544
  }: AppServerOptions = {}) {
565
- const root = resolveRoot(rootPath);
545
+ const project = Project.load(root);
566
546
  const mode = (typeof env === 'object' ? env?.mode : env) ?? 'production';
567
547
 
568
548
  const baseURL = assets?.baseURL ?? '/assets/';
@@ -577,31 +557,37 @@ export async function quiltAppServer({
577
557
  {sourceCode},
578
558
  {react},
579
559
  {tsconfigAliases},
560
+ {monorepoPackageAliases},
580
561
  {css},
581
562
  {rawAssets, staticAssets},
582
563
  {asyncModules},
583
564
  {esnext},
584
565
  nodePlugins,
585
- packageJSON,
586
566
  ] = await Promise.all([
587
567
  import('rollup-plugin-visualizer'),
588
568
  import('./features/env.ts'),
589
569
  import('./features/source-code.ts'),
590
570
  import('./features/react.ts'),
591
571
  import('./features/typescript.ts'),
572
+ import('./features/node.ts'),
592
573
  import('./features/css.ts'),
593
574
  import('./features/assets.ts'),
594
575
  import('./features/async.ts'),
595
576
  import('./features/esnext.ts'),
596
577
  getNodePlugins({bundle}),
597
- loadPackageJSON(root),
598
578
  ]);
599
579
 
600
580
  const plugins: InputPluginOption[] = [
601
- quiltAppServerInput({root, entry, format}),
581
+ quiltAppServerInput({root: project.root, entry, format}),
602
582
  ...nodePlugins,
603
583
  replaceProcessEnv({mode}),
604
584
  magicModuleEnv({...resolveEnvOption(env), mode}),
585
+ magicModuleAppComponent({entry: app, root: project.root}),
586
+ magicModuleAppServerEntry({
587
+ assets: {baseURL},
588
+ }),
589
+ magicModuleAppRequestRouter({entry, root: project.root}),
590
+ magicModuleAppAssetManifests(),
605
591
  sourceCode({
606
592
  mode,
607
593
  targets: ['current node'],
@@ -637,34 +623,13 @@ export async function quiltAppServer({
637
623
  asyncModules({
638
624
  baseURL,
639
625
  preload: false,
640
- moduleID: ({imported}) => path.relative(root, imported),
626
+ moduleID: ({imported}) => path.relative(project.root, imported),
641
627
  }),
642
- removeBuildFiles(['build/server'], {root}),
643
- tsconfigAliases({root}),
628
+ removeBuildFiles(['build/server'], {root: project.root}),
629
+ tsconfigAliases({root: project.root}),
630
+ monorepoPackageAliases({root: project.root}),
644
631
  ];
645
632
 
646
- const appEntry = await resolveAppEntry(app, {root, packageJSON});
647
-
648
- if (appEntry) {
649
- plugins.push(magicModuleAppComponent({entry: appEntry}));
650
- }
651
-
652
- const serverEntry = entry
653
- ? path.resolve(root, entry)
654
- : await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
655
- cwd: root,
656
- nodir: true,
657
- absolute: true,
658
- }).then((files) => files[0]);
659
-
660
- plugins.push(
661
- magicModuleAppServerEntry({
662
- assets: {baseURL},
663
- }),
664
- magicModuleAppRequestRouter({entry: serverEntry}),
665
- magicModuleAppAssetManifests(),
666
- );
667
-
668
633
  if (graphql) {
669
634
  const {graphql} = await import('./features/graphql.ts');
670
635
  plugins.push(graphql({manifest: false}));
@@ -680,10 +645,7 @@ export async function quiltAppServer({
680
645
  template: 'treemap',
681
646
  open: false,
682
647
  brotliSize: false,
683
- filename: path.resolve(
684
- root,
685
- `build/reports/bundle-visualizer.server.html`,
686
- ),
648
+ filename: project.resolve(`build/reports/bundle-visualizer.server.html`),
687
649
  }),
688
650
  );
689
651
 
@@ -691,11 +653,11 @@ export async function quiltAppServer({
691
653
  }
692
654
 
693
655
  export function quiltAppServerInput({
694
- root: rootPath = process.cwd(),
656
+ root = process.cwd(),
695
657
  entry,
696
658
  format = 'request-router',
697
659
  }: Pick<AppServerOptions, 'root' | 'entry' | 'format'> = {}) {
698
- const root = resolveRoot(rootPath);
660
+ const project = Project.load(root);
699
661
 
700
662
  return {
701
663
  name: '@quilted/app-server/input',
@@ -704,12 +666,13 @@ export function quiltAppServerInput({
704
666
 
705
667
  if (!finalEntry) {
706
668
  const serverEntry = entry
707
- ? path.resolve(root, entry)
708
- : await glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
709
- cwd: root,
710
- nodir: true,
711
- absolute: true,
712
- }).then((files) => files[0]);
669
+ ? project.resolve(entry)
670
+ : await project
671
+ .glob('{server,service,backend}.{ts,tsx,mjs,js,jsx}', {
672
+ nodir: true,
673
+ absolute: true,
674
+ })
675
+ .then((files) => files[0]);
713
676
 
714
677
  finalEntry =
715
678
  format === 'request-router'
@@ -728,52 +691,96 @@ export function quiltAppServerInput({
728
691
  } satisfies Plugin;
729
692
  }
730
693
 
731
- export function magicModuleAppComponent({entry}: {entry: string}) {
694
+ export function magicModuleAppComponent({
695
+ entry,
696
+ root = process.cwd(),
697
+ }: {
698
+ entry?: string;
699
+ root?: string;
700
+ }) {
732
701
  return createMagicModulePlugin({
733
702
  name: '@quilted/magic-module/app',
734
703
  module: MAGIC_MODULE_APP_COMPONENT,
735
- alias: entry,
704
+ alias:
705
+ entry ??
706
+ async function magicModuleApp() {
707
+ const project = Project.load(root);
708
+ const {packageJSON} = project;
709
+
710
+ if (typeof packageJSON.raw.main === 'string') {
711
+ return project.resolve(packageJSON.raw.main);
712
+ }
713
+
714
+ const rootEntry = (packageJSON.raw.exports as any)?.['.'];
715
+
716
+ if (typeof rootEntry === 'string') {
717
+ return project.resolve(rootEntry);
718
+ }
719
+
720
+ const globbed = await project.glob(
721
+ '{App,app,index}.{ts,tsx,mjs,js,jsx}',
722
+ {
723
+ nodir: true,
724
+ absolute: true,
725
+ },
726
+ );
727
+
728
+ return globbed[0]!;
729
+ },
736
730
  });
737
731
  }
738
732
 
739
733
  export function magicModuleAppRequestRouter({
740
734
  entry,
741
- }: Pick<AppServerOptions, 'entry'> = {}) {
735
+ root = process.cwd(),
736
+ }: Pick<AppServerOptions, 'entry' | 'root'> = {}) {
742
737
  return createMagicModulePlugin({
743
738
  name: '@quilted/magic-module/app-request-router',
744
739
  module: MAGIC_MODULE_REQUEST_ROUTER,
745
- alias: entry,
746
- source: entry
747
- ? undefined
748
- : async function source() {
749
- return multiline`
750
- import '@quilted/quilt/globals';
751
-
752
- import {jsx} from 'react/jsx-runtime';
753
- import {RequestRouter} from '@quilted/quilt/request-router';
754
- import {renderToResponse} from '@quilted/quilt/server';
755
-
756
- import App from ${JSON.stringify(MAGIC_MODULE_APP_COMPONENT)};
757
- import {BrowserAssets} from ${JSON.stringify(
758
- MAGIC_MODULE_BROWSER_ASSETS,
759
- )};
760
-
761
- const router = new RequestRouter();
762
- const assets = new BrowserAssets();
763
-
764
- // For all GET requests, render our React application.
765
- router.get(async (request) => {
766
- const response = await renderToResponse(jsx(App), {
767
- request,
768
- assets,
769
- });
770
-
771
- return response;
772
- });
740
+ alias:
741
+ entry ??
742
+ async function magicModuleRequestRouter() {
743
+ const project = Project.load(root);
744
+
745
+ const globbed = await project.glob(
746
+ '{server,service,backend}.{ts,tsx,mjs,js,jsx}',
747
+ {
748
+ nodir: true,
749
+ absolute: true,
750
+ },
751
+ );
752
+
753
+ return globbed[0]!;
754
+ },
755
+ async source() {
756
+ return multiline`
757
+ import '@quilted/quilt/globals';
773
758
 
774
- export default router;
775
- `;
776
- },
759
+ import {jsx} from 'react/jsx-runtime';
760
+ import {RequestRouter} from '@quilted/quilt/request-router';
761
+ import {renderToResponse} from '@quilted/quilt/server';
762
+
763
+ import App from ${JSON.stringify(MAGIC_MODULE_APP_COMPONENT)};
764
+ import {BrowserAssets} from ${JSON.stringify(
765
+ MAGIC_MODULE_BROWSER_ASSETS,
766
+ )};
767
+
768
+ const router = new RequestRouter();
769
+ const assets = new BrowserAssets();
770
+
771
+ // For all GET requests, render our React application.
772
+ router.get(async (request) => {
773
+ const response = await renderToResponse(jsx(App), {
774
+ request,
775
+ assets,
776
+ });
777
+
778
+ return response;
779
+ });
780
+
781
+ export default router;
782
+ `;
783
+ },
777
784
  });
778
785
  }
779
786
 
@@ -948,6 +955,30 @@ export function magicModuleAppAssetManifests() {
948
955
  });
949
956
  }
950
957
 
958
+ export async function sourceForAppBrowser({
959
+ entry,
960
+ root = process.cwd(),
961
+ }: {
962
+ entry?: string;
963
+ root?: string | URL;
964
+ }) {
965
+ const project = Project.load(root);
966
+
967
+ if (entry) {
968
+ return project.resolve(entry);
969
+ } else {
970
+ const files = await project.glob(
971
+ '{browser,client,web}.{ts,tsx,mjs,js,jsx}',
972
+ {
973
+ nodir: true,
974
+ absolute: true,
975
+ },
976
+ );
977
+
978
+ return files[0];
979
+ }
980
+ }
981
+
951
982
  const FRAMEWORK_CHUNK_NAME = 'framework';
952
983
  const POLYFILLS_CHUNK_NAME = 'polyfills';
953
984
  const VENDOR_CHUNK_NAME = 'vendor';
@@ -1046,30 +1077,3 @@ function createManualChunksSorter(): GetManualChunk {
1046
1077
  return `${bundleBaseName}-${relativeId.split(path.sep)[0]?.split('.')[0]}`;
1047
1078
  };
1048
1079
  }
1049
-
1050
- async function resolveAppEntry(
1051
- entry: string | undefined,
1052
- {root, packageJSON}: {root: string; packageJSON: PackageJSON},
1053
- ) {
1054
- if (entry) {
1055
- return path.resolve(root, entry);
1056
- }
1057
-
1058
- if (typeof packageJSON.main === 'string') {
1059
- return path.resolve(root, packageJSON.main);
1060
- }
1061
-
1062
- const rootEntry = (packageJSON.exports as any)?.['.'];
1063
-
1064
- if (typeof rootEntry === 'string') {
1065
- return path.resolve(root, rootEntry);
1066
- }
1067
-
1068
- const globbed = await glob('{App,app,index}.{ts,tsx,mjs,js,jsx}', {
1069
- cwd: root,
1070
- nodir: true,
1071
- absolute: true,
1072
- });
1073
-
1074
- return globbed[0];
1075
- }
@@ -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
+ }