@module-federation/treeshake-server 0.0.1 → 2.0.1
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/bin/treeshake-server.js +35 -0
- package/dist/domain/build/normalize-config.d.ts +1 -0
- package/dist/domain/upload/constant.d.ts +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/frontend/static/js/328.7d17cca6.js +2 -0
- package/dist/frontend/static/js/async/794.cada3bfc.js +12 -0
- package/dist/frontend/static/js/async/873.3956a71d.js +2 -0
- package/dist/frontend/static/js/async/{987.6bf8e9b0.js → 987.5b1e5ce3.js} +2 -2
- package/dist/frontend/static/js/{index.db4e73c6.js → index.e38c1fcc.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +105 -50
- package/dist/index.mjs +101 -48
- package/dist/server.js +105 -53
- package/dist/server.mjs +102 -52
- package/dist/services/buildService.d.ts +2 -2
- package/dist/services/uploadService.d.ts +1 -1
- package/dist/template/re-shake-share/package.json +2 -2
- package/package.json +20 -13
- package/dist/frontend/static/js/954.dfe166a3.js +0 -2
- package/dist/frontend/static/js/async/873.6ccd5409.js +0 -2
- package/dist/frontend/static/js/async/951.ec9191e2.js +0 -12
- /package/dist/frontend/static/js/{954.dfe166a3.js.LICENSE.txt → 328.7d17cca6.js.LICENSE.txt} +0 -0
- /package/dist/frontend/static/js/async/{951.ec9191e2.js.LICENSE.txt → 794.cada3bfc.js.LICENSE.txt} +0 -0
- /package/dist/frontend/static/js/async/{987.6bf8e9b0.js.LICENSE.txt → 987.5b1e5ce3.js.LICENSE.txt} +0 -0
package/dist/server.mjs
CHANGED
|
@@ -4,15 +4,18 @@ import node_path from "node:path";
|
|
|
4
4
|
import pino from "pino";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import { cors } from "hono/cors";
|
|
7
|
+
import node_os from "node:os";
|
|
7
8
|
import { zValidator } from "@hono/zod-validator";
|
|
8
9
|
import { nanoid } from "nanoid";
|
|
10
|
+
import p_limit from "p-limit";
|
|
9
11
|
import { z } from "zod";
|
|
10
12
|
import { createHash } from "node:crypto";
|
|
11
|
-
import
|
|
13
|
+
import promises from "node:fs/promises";
|
|
12
14
|
import { spawn } from "node:child_process";
|
|
13
15
|
import json_stable_stringify from "json-stable-stringify";
|
|
16
|
+
import { timeout } from "hono/timeout";
|
|
14
17
|
import { serve } from "@hono/node-server";
|
|
15
|
-
const SERVER_VERSION = 'v0-
|
|
18
|
+
const SERVER_VERSION = 'v0-0205';
|
|
16
19
|
const UPLOADED_DIR = '_shared-tree-shaking';
|
|
17
20
|
const createLogger = (opts)=>pino({
|
|
18
21
|
level: (null == opts ? void 0 : opts.level) ?? 'info',
|
|
@@ -71,7 +74,8 @@ class LocalObjectStore {
|
|
|
71
74
|
_define_property(this, "rootDir", void 0);
|
|
72
75
|
_define_property(this, "publicBaseUrl", void 0);
|
|
73
76
|
this.rootDir = (null == opts ? void 0 : opts.rootDir) ?? node_path.join(process.cwd(), 'log', 'static');
|
|
74
|
-
const
|
|
77
|
+
const port = process.env.PORT || 3000;
|
|
78
|
+
const base = (null == opts ? void 0 : opts.publicBaseUrl) === '/' ? `http://localhost:${port}/` : (null == opts ? void 0 : opts.publicBaseUrl) ?? '/';
|
|
75
79
|
this.publicBaseUrl = base.endsWith('/') ? base : `${base}/`;
|
|
76
80
|
}
|
|
77
81
|
}
|
|
@@ -238,14 +242,15 @@ function normalizeConfig(config) {
|
|
|
238
242
|
return normalizedConfig;
|
|
239
243
|
}
|
|
240
244
|
function extractBuildConfig(config, type) {
|
|
241
|
-
const { shared, plugins, target, libraryType, usedExports } = config;
|
|
245
|
+
const { shared, plugins, target, libraryType, usedExports, hostName } = config;
|
|
242
246
|
return {
|
|
243
247
|
shared,
|
|
244
248
|
plugins,
|
|
245
249
|
target,
|
|
246
250
|
libraryType,
|
|
247
251
|
usedExports,
|
|
248
|
-
type
|
|
252
|
+
type,
|
|
253
|
+
hostName
|
|
249
254
|
};
|
|
250
255
|
}
|
|
251
256
|
const UploadOptionsSchema = z.object({
|
|
@@ -374,11 +379,11 @@ const startPeriodicPrune = (intervalMs = DEFAULT_INTERVAL)=>{
|
|
|
374
379
|
maybePrune();
|
|
375
380
|
}, intervalMs);
|
|
376
381
|
};
|
|
377
|
-
const createUniqueTempDirByKey = (key)=>{
|
|
382
|
+
const createUniqueTempDirByKey = async (key)=>{
|
|
378
383
|
const base = node_path.join(node_os.tmpdir(), `re-shake-share-${key}`);
|
|
379
384
|
let candidate = base;
|
|
380
385
|
for(;;)try {
|
|
381
|
-
|
|
386
|
+
await promises.mkdir(candidate, {
|
|
382
387
|
recursive: false
|
|
383
388
|
});
|
|
384
389
|
return candidate;
|
|
@@ -387,15 +392,22 @@ const createUniqueTempDirByKey = (key)=>{
|
|
|
387
392
|
candidate = `${base}-${rand}`;
|
|
388
393
|
}
|
|
389
394
|
};
|
|
390
|
-
const prepareProject = (config, excludeShared)=>{
|
|
395
|
+
const prepareProject = async (config, excludeShared)=>{
|
|
391
396
|
const key = createHash('sha256').update(JSON.stringify(config)).digest('hex');
|
|
392
|
-
const dir = createUniqueTempDirByKey(key);
|
|
393
|
-
const templateDir = node_path.join(__dirname, '
|
|
394
|
-
|
|
397
|
+
const dir = await createUniqueTempDirByKey(key);
|
|
398
|
+
const templateDir = node_path.join(__dirname, '.', 'template', 're-shake-share');
|
|
399
|
+
await promises.cp(templateDir, dir, {
|
|
395
400
|
recursive: true
|
|
396
401
|
});
|
|
397
402
|
const pkgPath = node_path.join(dir, 'package.json');
|
|
398
|
-
const
|
|
403
|
+
const indexPath = node_path.join(dir, 'index.ts');
|
|
404
|
+
const rspackConfigPath = node_path.join(dir, 'rspack.config.ts');
|
|
405
|
+
const [pkgContent, indexContent, rspackConfigContent] = await Promise.all([
|
|
406
|
+
promises.readFile(pkgPath, 'utf-8'),
|
|
407
|
+
promises.readFile(indexPath, 'utf-8'),
|
|
408
|
+
promises.readFile(rspackConfigPath, 'utf-8')
|
|
409
|
+
]);
|
|
410
|
+
const pkg = JSON.parse(pkgContent);
|
|
399
411
|
const deps = {
|
|
400
412
|
...pkg.dependencies || {}
|
|
401
413
|
};
|
|
@@ -436,28 +448,29 @@ const prepareProject = (config, excludeShared)=>{
|
|
|
436
448
|
});
|
|
437
449
|
pluginOptionStr += '\n]';
|
|
438
450
|
pkg.dependencies = deps;
|
|
439
|
-
|
|
451
|
+
const newPkgContent = JSON.stringify(pkg, null, 2);
|
|
440
452
|
const sharedImportPlaceholder = "${SHARED_IMPORT}";
|
|
453
|
+
const newIndexContent = indexContent.replace(sharedImportPlaceholder, sharedImport);
|
|
441
454
|
const pluginsPlaceholder = "${ PLUGINS }";
|
|
442
455
|
const mfConfigPlaceholder = "${ MF_CONFIG }";
|
|
443
|
-
|
|
444
|
-
const indexContent = node_fs.readFileSync(indexPath, 'utf-8');
|
|
445
|
-
node_fs.writeFileSync(indexPath, indexContent.replace(sharedImportPlaceholder, sharedImport));
|
|
446
|
-
const rspackConfigPath = node_path.join(dir, 'rspack.config.ts');
|
|
447
|
-
let cfg = node_fs.readFileSync(rspackConfigPath, 'utf-8');
|
|
456
|
+
let cfg = rspackConfigContent;
|
|
448
457
|
cfg += pluginImportStr;
|
|
449
458
|
cfg = cfg.replace(pluginsPlaceholder, pluginOptionStr);
|
|
450
459
|
cfg = cfg.replace(mfConfigPlaceholder, JSON.stringify(mfConfig, null, 2));
|
|
451
|
-
|
|
460
|
+
await Promise.all([
|
|
461
|
+
promises.writeFile(pkgPath, newPkgContent),
|
|
462
|
+
promises.writeFile(indexPath, newIndexContent),
|
|
463
|
+
promises.writeFile(rspackConfigPath, cfg)
|
|
464
|
+
]);
|
|
452
465
|
return dir;
|
|
453
466
|
};
|
|
454
467
|
const installDependencies = async (cwd)=>{
|
|
455
468
|
markInstallStart();
|
|
456
469
|
try {
|
|
457
|
-
await runCommand(
|
|
470
|
+
await runCommand("pnpm i --ignore-scripts --prefer-offline --reporter=silent ", {
|
|
458
471
|
cwd,
|
|
459
472
|
env: {
|
|
460
|
-
npm_config_registry: 'https://registry.npmjs.org/'
|
|
473
|
+
npm_config_registry: process.env.MF_NPM_REGISTRY || 'https://registry.npmjs.org/'
|
|
461
474
|
}
|
|
462
475
|
});
|
|
463
476
|
} finally{
|
|
@@ -472,12 +485,13 @@ const buildProject = async (cwd, type)=>{
|
|
|
472
485
|
cwd
|
|
473
486
|
})));
|
|
474
487
|
};
|
|
475
|
-
const retrieveSharedFilepaths = (projectDir, type)=>{
|
|
488
|
+
const retrieveSharedFilepaths = async (projectDir, type)=>{
|
|
476
489
|
const sharedFilepaths = [];
|
|
477
|
-
const collectSharedFilepaths = (t)=>{
|
|
490
|
+
const collectSharedFilepaths = async (t)=>{
|
|
478
491
|
const dir = 'full' === t ? 'full-shared' : 'dist';
|
|
479
492
|
const distDir = node_path.join(projectDir, dir);
|
|
480
|
-
const
|
|
493
|
+
const statsContent = await promises.readFile(node_path.join(distDir, STATS_NAME), 'utf-8');
|
|
494
|
+
const stats = JSON.parse(statsContent);
|
|
481
495
|
stats.shared.forEach((s)=>{
|
|
482
496
|
const { name, version, fallback, fallbackName } = s;
|
|
483
497
|
if (fallback && fallbackName) {
|
|
@@ -495,22 +509,31 @@ const retrieveSharedFilepaths = (projectDir, type)=>{
|
|
|
495
509
|
}
|
|
496
510
|
});
|
|
497
511
|
};
|
|
498
|
-
collectSharedFilepaths(type);
|
|
512
|
+
await collectSharedFilepaths(type);
|
|
499
513
|
return sharedFilepaths;
|
|
500
514
|
};
|
|
501
515
|
const runBuild = async (normalizedConfig, excludeShared, type)=>{
|
|
502
|
-
const
|
|
516
|
+
const tStart = Date.now();
|
|
517
|
+
const tmpDir = await prepareProject(normalizedConfig, excludeShared);
|
|
518
|
+
const tPrepare = Date.now();
|
|
519
|
+
logger_logger.info(`prepareProject took ${tPrepare - tStart}ms`);
|
|
503
520
|
await installDependencies(tmpDir);
|
|
521
|
+
const tInstall = Date.now();
|
|
522
|
+
logger_logger.info(`installDependencies took ${tInstall - tPrepare}ms`);
|
|
504
523
|
await buildProject(tmpDir, type);
|
|
505
|
-
const
|
|
524
|
+
const tBuild = Date.now();
|
|
525
|
+
logger_logger.info(`buildProject took ${tBuild - tInstall}ms`);
|
|
526
|
+
const sharedFilePaths = await retrieveSharedFilepaths(tmpDir, type);
|
|
527
|
+
const tRetrieve = Date.now();
|
|
528
|
+
logger_logger.info(`retrieveSharedFilepaths took ${tRetrieve - tBuild}ms`);
|
|
506
529
|
return {
|
|
507
530
|
sharedFilePaths,
|
|
508
531
|
dir: tmpDir
|
|
509
532
|
};
|
|
510
533
|
};
|
|
511
|
-
function cleanUp(tmpDir) {
|
|
534
|
+
async function cleanUp(tmpDir) {
|
|
512
535
|
if (!tmpDir) return;
|
|
513
|
-
|
|
536
|
+
await promises.rm(tmpDir, {
|
|
514
537
|
recursive: true,
|
|
515
538
|
force: true
|
|
516
539
|
});
|
|
@@ -608,7 +631,7 @@ async function uploadToCacheStore(sharedFilePaths, normalizedConfig, store) {
|
|
|
608
631
|
const jsonFilePath = filepath.replace(/\.js$/, '.json');
|
|
609
632
|
const jsonFile = JSON.stringify(res);
|
|
610
633
|
const jsonCdnUrl = cdnPath.replace(/\.js$/, '.json');
|
|
611
|
-
|
|
634
|
+
await promises.writeFile(jsonFilePath, jsonFile);
|
|
612
635
|
await store.uploadFile(jsonFilePath, jsonCdnUrl);
|
|
613
636
|
} catch (error) {
|
|
614
637
|
logger_logger.error(`Failed to upload ${name}@${version} json file: ${error}`);
|
|
@@ -626,25 +649,26 @@ const downloadToFile = async (url, destPath)=>{
|
|
|
626
649
|
const res = await fetch(url);
|
|
627
650
|
if (!res.ok) throw new Error(`Download failed: ${res.status} ${res.statusText} - ${url}`);
|
|
628
651
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
629
|
-
await
|
|
652
|
+
await promises.mkdir(node_path.dirname(destPath), {
|
|
630
653
|
recursive: true
|
|
631
654
|
});
|
|
632
|
-
await
|
|
655
|
+
await promises.writeFile(destPath, buf);
|
|
633
656
|
return destPath;
|
|
634
657
|
};
|
|
635
|
-
async function uploadProject(uploadResults, sharedFilePaths, normalizedConfig, publisher) {
|
|
636
|
-
const tmpDir = createUniqueTempDirByKey(`upload-project${Date.now().toString()}`);
|
|
658
|
+
async function uploadProject(uploadResults, sharedFilePaths, normalizedConfig, publisher, store) {
|
|
659
|
+
const tmpDir = await createUniqueTempDirByKey(`upload-project${Date.now().toString()}`);
|
|
637
660
|
const uploaded = [];
|
|
638
661
|
try {
|
|
639
662
|
for (const item of uploadResults)try {
|
|
640
|
-
const
|
|
663
|
+
const sharedKey = normalizedKey(item.name, item.version);
|
|
664
|
+
const config = normalizedConfig[sharedKey];
|
|
641
665
|
if (!config) {
|
|
642
666
|
logger_logger.error(`No config found for ${item.name}`);
|
|
643
667
|
continue;
|
|
644
668
|
}
|
|
645
669
|
const { uploadOptions } = config;
|
|
646
670
|
if (!uploadOptions) throw new Error(`No uploadOptions found for ${item.name}`);
|
|
647
|
-
const filename = node_path.basename(new URL(item.cdnUrl).pathname);
|
|
671
|
+
const filename = node_path.basename(new URL(item.cdnUrl, 'http://dummy.com').pathname);
|
|
648
672
|
const localPath = node_path.join(tmpDir, filename);
|
|
649
673
|
const hash = createCacheHash({
|
|
650
674
|
...config,
|
|
@@ -706,16 +730,20 @@ async function uploadProject(uploadResults, sharedFilePaths, normalizedConfig, p
|
|
|
706
730
|
version: s.version,
|
|
707
731
|
globalName: s.globalName,
|
|
708
732
|
cdnUrl,
|
|
709
|
-
type: s.type
|
|
733
|
+
type: s.type,
|
|
734
|
+
modules: s.modules,
|
|
735
|
+
canTreeShaking: s.canTreeShaking
|
|
710
736
|
});
|
|
711
737
|
} catch (error) {
|
|
712
738
|
logger_logger.error(`Failed to upload ${s.name}@${s.version}: ${error}`);
|
|
713
739
|
}
|
|
714
740
|
return uploaded;
|
|
715
741
|
} finally{
|
|
716
|
-
|
|
742
|
+
promises.rm(tmpDir, {
|
|
717
743
|
recursive: true,
|
|
718
744
|
force: true
|
|
745
|
+
}).catch((err)=>{
|
|
746
|
+
logger_logger.error(`Failed to cleanup dir ${tmpDir}: ${err}`);
|
|
719
747
|
});
|
|
720
748
|
}
|
|
721
749
|
}
|
|
@@ -724,14 +752,14 @@ async function upload(sharedFilePaths, uploadResults, normalizedConfig, uploadOp
|
|
|
724
752
|
if (!uploadOptions) {
|
|
725
753
|
const hydrated = await Promise.all(uploadResults.map(async (item)=>{
|
|
726
754
|
if ('full' !== item.type) return item;
|
|
727
|
-
const tmpDir = createUniqueTempDirByKey(`download-full-json${Date.now().toString()}`);
|
|
755
|
+
const tmpDir = await createUniqueTempDirByKey(`download-full-json${Date.now().toString()}`);
|
|
728
756
|
const jsonPath = node_path.join(tmpDir, `${item.name}-${item.version}.json`);
|
|
729
757
|
try {
|
|
730
758
|
const tJson0 = Date.now();
|
|
731
759
|
await downloadToFile(item.cdnUrl.replace('.js', '.json'), jsonPath);
|
|
732
760
|
const tJson = Date.now() - tJson0;
|
|
733
761
|
logger_logger.info(`Downloaded ${item.name}@${item.version} json in ${tJson}ms`);
|
|
734
|
-
const jsonContent = JSON.parse(
|
|
762
|
+
const jsonContent = JSON.parse(await promises.readFile(jsonPath, 'utf8'));
|
|
735
763
|
return {
|
|
736
764
|
...item,
|
|
737
765
|
canTreeShaking: jsonContent.canTreeShaking,
|
|
@@ -744,7 +772,7 @@ async function upload(sharedFilePaths, uploadResults, normalizedConfig, uploadOp
|
|
|
744
772
|
canTreeShaking: item.canTreeShaking ?? true
|
|
745
773
|
};
|
|
746
774
|
} finally{
|
|
747
|
-
|
|
775
|
+
await promises.rm(tmpDir, {
|
|
748
776
|
recursive: true,
|
|
749
777
|
force: true
|
|
750
778
|
});
|
|
@@ -756,9 +784,10 @@ async function upload(sharedFilePaths, uploadResults, normalizedConfig, uploadOp
|
|
|
756
784
|
];
|
|
757
785
|
}
|
|
758
786
|
if (!publisher) throw new Error('uploadOptions provided but no projectPublisher configured (configure the selected adapter to enable it or omit uploadOptions)');
|
|
759
|
-
const projectUploadResults = await uploadProject(uploadResults, sharedFilePaths, normalizedConfig, publisher);
|
|
787
|
+
const projectUploadResults = await uploadProject(uploadResults, sharedFilePaths, normalizedConfig, publisher, store);
|
|
760
788
|
return projectUploadResults;
|
|
761
789
|
}
|
|
790
|
+
const buildLimit = p_limit(Math.max(1, node_os.cpus().length));
|
|
762
791
|
const buildRoute = new Hono();
|
|
763
792
|
buildRoute.post('/', zValidator('json', ConfigSchema), async (c)=>{
|
|
764
793
|
const logger = c.get('logger');
|
|
@@ -771,16 +800,27 @@ buildRoute.post('/', zValidator('json', ConfigSchema), async (c)=>{
|
|
|
771
800
|
const store = c.get('objectStore');
|
|
772
801
|
const publisher = c.get('projectPublisher');
|
|
773
802
|
try {
|
|
803
|
+
const t0 = Date.now();
|
|
774
804
|
const { cacheItems, excludeShared, restConfig } = await retrieveCacheItems(normalizedConfig, 're-shake', store);
|
|
805
|
+
const tRetrieveCache = Date.now();
|
|
806
|
+
logger.info(`retrieveCacheItems took ${tRetrieveCache - t0}ms`);
|
|
775
807
|
let sharedFilePaths = [];
|
|
776
808
|
let dir;
|
|
777
809
|
if (Object.keys(restConfig).length > 0) {
|
|
778
|
-
const buildResult = await runBuild(normalizedConfig, excludeShared, 're-shake');
|
|
810
|
+
const buildResult = await buildLimit(()=>runBuild(normalizedConfig, excludeShared, 're-shake'));
|
|
779
811
|
sharedFilePaths = buildResult.sharedFilePaths;
|
|
780
812
|
dir = buildResult.dir;
|
|
781
813
|
}
|
|
814
|
+
const tBuild = Date.now();
|
|
815
|
+
logger.info(`runBuild took ${tBuild - tRetrieveCache}ms`);
|
|
782
816
|
const uploadResults = await upload(sharedFilePaths, cacheItems, normalizedConfig, body.uploadOptions, store, publisher);
|
|
783
|
-
|
|
817
|
+
const tUpload = Date.now();
|
|
818
|
+
logger.info(`upload took ${tUpload - tBuild}ms`);
|
|
819
|
+
cleanUp(dir).catch((err)=>{
|
|
820
|
+
logger.error(`Failed to cleanup dir ${dir}: ${err}`);
|
|
821
|
+
});
|
|
822
|
+
const tCleanUp = Date.now();
|
|
823
|
+
logger.info(`cleanUp scheduled (non-blocking) took ${tCleanUp - tUpload}ms`);
|
|
784
824
|
return c.json({
|
|
785
825
|
jobId,
|
|
786
826
|
status: 'success',
|
|
@@ -818,16 +858,27 @@ async function handleCheckTreeshake(c, body) {
|
|
|
818
858
|
const store = c.get('objectStore');
|
|
819
859
|
const publisher = c.get('projectPublisher');
|
|
820
860
|
try {
|
|
861
|
+
const t0 = Date.now();
|
|
821
862
|
const { cacheItems, excludeShared, restConfig } = await retrieveCacheItems(normalizedConfig, 'full', store);
|
|
863
|
+
const tRetrieveCache = Date.now();
|
|
864
|
+
logger.info(`retrieveCacheItems took ${tRetrieveCache - t0}ms`);
|
|
822
865
|
let sharedFilePaths = [];
|
|
823
866
|
let dir;
|
|
824
867
|
if (Object.keys(restConfig).length > 0) {
|
|
825
|
-
const buildResult = await runBuild(normalizedConfig, excludeShared, 'full');
|
|
868
|
+
const buildResult = await buildLimit(()=>runBuild(normalizedConfig, excludeShared, 'full'));
|
|
826
869
|
sharedFilePaths = buildResult.sharedFilePaths;
|
|
827
870
|
dir = buildResult.dir;
|
|
828
871
|
}
|
|
872
|
+
const tBuild = Date.now();
|
|
873
|
+
logger.info(`runBuild took ${tBuild - tRetrieveCache}ms`);
|
|
829
874
|
const uploadResults = await upload(sharedFilePaths, cacheItems, normalizedConfig, body.uploadOptions, store, publisher);
|
|
830
|
-
|
|
875
|
+
const tUpload = Date.now();
|
|
876
|
+
logger.info(`upload took ${tUpload - tBuild}ms`);
|
|
877
|
+
cleanUp(dir).catch((err)=>{
|
|
878
|
+
logger.error(`Failed to cleanup dir ${dir}: ${err}`);
|
|
879
|
+
});
|
|
880
|
+
const tCleanUp = Date.now();
|
|
881
|
+
logger.info(`cleanUp scheduled (non-blocking) took ${tCleanUp - tUpload}ms`);
|
|
831
882
|
return c.json({
|
|
832
883
|
jobId,
|
|
833
884
|
status: 'success',
|
|
@@ -893,6 +944,7 @@ function createApp(deps, opts) {
|
|
|
893
944
|
}));
|
|
894
945
|
app.use('*', loggerMiddleware);
|
|
895
946
|
app.use('*', createDiMiddleware(deps));
|
|
947
|
+
app.use('*', timeout(60000));
|
|
896
948
|
if (null == opts ? void 0 : null == (_opts_appExtensions = opts.appExtensions) ? void 0 : _opts_appExtensions.length) for (const extend of opts.appExtensions)extend(app);
|
|
897
949
|
app.get('/tree-shaking-shared/healthz', (c)=>c.json({
|
|
898
950
|
status: 'ok',
|
|
@@ -985,7 +1037,8 @@ function createServer(opts) {
|
|
|
985
1037
|
return serve({
|
|
986
1038
|
fetch: opts.app.fetch,
|
|
987
1039
|
port,
|
|
988
|
-
hostname
|
|
1040
|
+
hostname,
|
|
1041
|
+
overrideGlobalObjects: false
|
|
989
1042
|
});
|
|
990
1043
|
}
|
|
991
1044
|
const hasIndexHtml = (dir)=>Boolean(dir && node_fs.existsSync(node_path.join(dir, 'index.html')));
|
|
@@ -1046,11 +1099,8 @@ async function main() {
|
|
|
1046
1099
|
port: resolved.port,
|
|
1047
1100
|
hostname: resolved.hostname
|
|
1048
1101
|
});
|
|
1049
|
-
console.log(
|
|
1050
|
-
if (frontendAdapters.length)
|
|
1051
|
-
const basePath = process.env.TREESHAKE_FRONTEND_BASE_PATH ?? '/tree-shaking';
|
|
1052
|
-
console.log(`Treeshake UI available at http://${resolved.hostname}:${resolved.port}${basePath}`);
|
|
1053
|
-
}
|
|
1102
|
+
console.log('Build service listening.');
|
|
1103
|
+
if (frontendAdapters.length) console.log('Treeshake UI available.');
|
|
1054
1104
|
}
|
|
1055
1105
|
main().catch((err)=>{
|
|
1056
1106
|
console.error(err);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type BuildType, type NormalizedConfig } from '../domain/build/normalize-config';
|
|
2
2
|
import type { SharedFilePath } from './uploadService';
|
|
3
|
-
export declare const createUniqueTempDirByKey: (key: string) => string
|
|
3
|
+
export declare const createUniqueTempDirByKey: (key: string) => Promise<string>;
|
|
4
4
|
export declare const runBuild: (normalizedConfig: NormalizedConfig, excludeShared: Array<[string, string]>, type: BuildType) => Promise<{
|
|
5
5
|
sharedFilePaths: SharedFilePath[];
|
|
6
6
|
dir: string;
|
|
7
7
|
}>;
|
|
8
|
-
export declare function cleanUp(tmpDir?: string): void
|
|
8
|
+
export declare function cleanUp(tmpDir?: string): Promise<void>;
|
|
@@ -32,5 +32,5 @@ export interface UploadOpts {
|
|
|
32
32
|
cdnRegion: string;
|
|
33
33
|
publicRoot: string;
|
|
34
34
|
}
|
|
35
|
-
export declare function uploadProject(uploadResults: UploadResult[], sharedFilePaths: SharedFilePath[], normalizedConfig: NormalizedConfig, publisher: ProjectPublisher): Promise<UploadResult[]>;
|
|
35
|
+
export declare function uploadProject(uploadResults: UploadResult[], sharedFilePaths: SharedFilePath[], normalizedConfig: NormalizedConfig, publisher: ProjectPublisher, store: ObjectStore): Promise<UploadResult[]>;
|
|
36
36
|
export declare function upload(sharedFilePaths: SharedFilePath[], uploadResults: UploadResult[], normalizedConfig: NormalizedConfig, uploadOptions: Config['uploadOptions'], store: ObjectStore, publisher?: ProjectPublisher): Promise<UploadResult[]>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/treeshake-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Build service powered by Hono that installs dependencies, builds with Rspack, and uploads artifacts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -13,17 +13,10 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"bin": {
|
|
16
|
-
"treeshake-server": "
|
|
17
|
-
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "pnpm -C ../treeshake-frontend build && rslib build && node scripts/copy-frontend.js",
|
|
20
|
-
"lint": "biome lint src scripts",
|
|
21
|
-
"prestart": "npm run build",
|
|
22
|
-
"dev": "node scripts/dev.js",
|
|
23
|
-
"start": "node dist/server.js",
|
|
24
|
-
"test": "rstest"
|
|
16
|
+
"treeshake-server": "bin/treeshake-server.js"
|
|
25
17
|
},
|
|
26
18
|
"files": [
|
|
19
|
+
"bin/",
|
|
27
20
|
"dist/",
|
|
28
21
|
"README.md"
|
|
29
22
|
],
|
|
@@ -34,11 +27,12 @@
|
|
|
34
27
|
"@hono/node-server": "1.19.5",
|
|
35
28
|
"@hono/zod-validator": "0.7.4",
|
|
36
29
|
"dotenv": "16.4.5",
|
|
37
|
-
"hono": "4.
|
|
30
|
+
"hono": "4.11.7",
|
|
38
31
|
"json-stable-stringify": "1.3.0",
|
|
39
32
|
"nanoid": "5.1.6",
|
|
33
|
+
"p-limit": "^7.2.0",
|
|
40
34
|
"pino": "10.1.0",
|
|
41
|
-
"undici": "
|
|
35
|
+
"undici": "6.23.0",
|
|
42
36
|
"zod": "4.1.12"
|
|
43
37
|
},
|
|
44
38
|
"devDependencies": {
|
|
@@ -57,5 +51,18 @@
|
|
|
57
51
|
},
|
|
58
52
|
"publishConfig": {
|
|
59
53
|
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "git+https://github.com/module-federation/core.git",
|
|
58
|
+
"directory": "packages/treeshake-server"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "pnpm -C ../treeshake-frontend build && rslib build && node scripts/copy-frontend.js",
|
|
62
|
+
"lint": "biome lint src scripts",
|
|
63
|
+
"prestart": "npm run build",
|
|
64
|
+
"dev": "node scripts/dev.js",
|
|
65
|
+
"start": "node dist/server.js",
|
|
66
|
+
"test": "node ../../scripts/ensure-playwright.js && rstest"
|
|
60
67
|
}
|
|
61
|
-
}
|
|
68
|
+
}
|