Skip to content

Commit 5ad2a09

Browse files
committed
fix(nf-core): use nearest tsconfig.json when building a shared mapping + make build more robust in general
1 parent ff97357 commit 5ad2a09

18 files changed

+2068
-507
lines changed
-107 Bytes
Binary file not shown.

libs/native-federation-core/src/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export { MappedPath } from './lib/utils/mapped-paths';
1212
export { BuildAdapter } from './lib/core/build-adapter';
1313
export { withNativeFederation } from './lib/config/with-native-federation';
1414
export { buildForFederation } from './lib/core/build-for-federation';
15-
export { share, shareAll } from './lib/config/share-utils';
15+
export { share, shareAll, findRootTsConfigJson } from './lib/config/share-utils';
1616
export {
1717
federationBuilder,
1818
BuildHelperParams,

libs/native-federation-core/src/lib/config/federation-config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SkipList } from '../core/default-skip-list';
12
import { MappedPath } from '../utils/mapped-paths';
23

34
export interface SharedConfig {
@@ -13,7 +14,7 @@ export interface FederationConfig {
1314
exposes?: Record<string, string>;
1415
shared?: Record<string, SharedConfig>;
1516
sharedMappings?: Array<string>;
16-
skip?: Array<string>;
17+
skip?: SkipList;
1718
}
1819

1920
export interface NormalizedSharedConfig {

libs/native-federation-core/src/lib/config/share-utils.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path = require('path');
22
import fs = require('fs');
33
import { cwd } from 'process';
44
import { SharedConfig } from './federation-config';
5-
import { DEFAULT_SKIP_LIST } from '../core/default-skip-list';
5+
import { DEFAULT_SKIP_LIST, isInSkipList, PREPARED_DEFAULT_SKIP_LIST, prepareSkipList, SkipList } from '../core/default-skip-list';
66

77
let inferVersion = false;
88

@@ -104,6 +104,11 @@ function _findSecondaries(
104104
if (excludes.includes(secondaryLibName)) {
105105
continue;
106106
}
107+
108+
if (isInSkipList(secondaryLibName, PREPARED_DEFAULT_SKIP_LIST)) {
109+
continue;
110+
}
111+
107112
acc[secondaryLibName] = { ...shareObject };
108113
_findSecondaries(s, excludes, shareObject, acc);
109114
}
@@ -196,6 +201,10 @@ function readConfiguredSecondaries(
196201
continue;
197202
}
198203

204+
if (isInSkipList(secondaryName, PREPARED_DEFAULT_SKIP_LIST)) {
205+
continue;
206+
}
207+
199208
result[secondaryName] = {
200209
...shareObject,
201210
// import: path.join(libPath, relPath)
@@ -207,7 +216,7 @@ function readConfiguredSecondaries(
207216

208217
export function shareAll(
209218
config: CustomSharedConfig = {},
210-
skip: string[] = [...DEFAULT_SKIP_LIST],
219+
skip: SkipList = DEFAULT_SKIP_LIST,
211220
packageJsonPath = ''
212221
): Config | null {
213222
if (!packageJsonPath) {
@@ -219,8 +228,10 @@ export function shareAll(
219228
const versions = readVersionMap(packagePath);
220229
const share: any = {};
221230

231+
const preparedSkipList = prepareSkipList(skip);
232+
222233
for (const key in versions) {
223-
if (skip.includes(key)) {
234+
if (isInSkipList(key, preparedSkipList)) {
224235
continue;
225236
}
226237

libs/native-federation-core/src/lib/config/with-native-federation.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import {
55
NormalizedFederationConfig,
66
NormalizedSharedConfig,
77
} from './federation-config';
8+
import { isInSkipList, PreparedSkipList, prepareSkipList } from '../core/default-skip-list';
89

910
export function withNativeFederation(
1011
config: FederationConfig
1112
): NormalizedFederationConfig {
12-
const skip = new Set(config.skip) ?? new Set<string>();
13+
14+
const skip = prepareSkipList(config.skip ?? []);
1315

1416
return {
1517
name: config.name ?? '',
@@ -21,7 +23,7 @@ export function withNativeFederation(
2123

2224
function normalizeShared(
2325
config: FederationConfig,
24-
skip: Set<string>
26+
skip: PreparedSkipList
2527
): Record<string, NormalizedSharedConfig> {
2628
let result: Record<string, NormalizedSharedConfig> = {};
2729

@@ -52,7 +54,7 @@ function normalizeShared(
5254
}
5355

5456
result = Object.keys(result)
55-
.filter((key) => !skip.has(key))
57+
.filter((key) => !isInSkipList(key, skip))
5658
.reduce(
5759
(acc, cur) => ({
5860
...acc,
@@ -66,7 +68,7 @@ function normalizeShared(
6668

6769
function normalizeSharedMappings(
6870
config: FederationConfig,
69-
skip: Set<string>
71+
skip: PreparedSkipList
7072
): Array<MappedPath> {
7173
const rootTsConfigPath = findRootTsConfigJson();
7274

@@ -75,7 +77,7 @@ function normalizeSharedMappings(
7577
sharedMappings: config.sharedMappings,
7678
});
7779

78-
const result = paths.filter((p) => !skip.has(p.key));
80+
const result = paths.filter((p) => !isInSkipList(p.key, skip));
7981

8082
return result;
8183
}

libs/native-federation-core/src/lib/core/bundle-shared-mappings.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export async function bundleSharedMappings(
2323
try {
2424
await bundle({
2525
entryPoint: m.path,
26-
tsConfigPath: fedOptions.tsConfig,
26+
tsConfigPath: findTsConfig(m.path) ?? fedOptions.tsConfig,
2727
external: externals,
2828
outfile: outFilePath,
2929
mappedPaths: [],
@@ -60,3 +60,31 @@ export async function bundleSharedMappings(
6060

6161
return result;
6262
}
63+
64+
function findTsConfig(folder: string): string | null {
65+
while (
66+
!fs.existsSync(path.join(folder, 'tsconfig.lib.json')) &&
67+
!fs.existsSync(path.join(folder, 'tsconfig.json')) &&
68+
!fs.existsSync(path.join(folder, 'tsconfig.base.json')) &&
69+
path.dirname(folder) !== folder
70+
) {
71+
folder = path.dirname(folder);
72+
}
73+
74+
const filePathOption0 = path.join(folder, 'tsconfig.lib.json');
75+
if (fs.existsSync(filePathOption0)) {
76+
return filePathOption0;
77+
}
78+
79+
const filePathOption1 = path.join(folder, 'tsconfig.json');
80+
if (fs.existsSync(filePathOption1)) {
81+
return filePathOption1;
82+
}
83+
84+
const filePathOption2 = path.join(folder, 'tsconfig.base.json');
85+
if (fs.existsSync(filePathOption2)) {
86+
return filePathOption2;
87+
}
88+
89+
return null;
90+
}

libs/native-federation-core/src/lib/core/bundle-shared.ts

+16-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { bundle } from '../utils/build-utils';
55
import { getPackageInfo, PackageInfo } from '../utils/package-info';
66
import { SharedInfo } from '@softarc/native-federation-runtime';
77
import { FederationOptions } from './federation-options';
8-
import { DEFAULT_SKIP_LIST } from './default-skip-list';
98
import { copySrcMapIfExists } from '../utils/copy-src-map-if-exists';
109

1110
export async function bundleShared(
@@ -14,9 +13,8 @@ export async function bundleShared(
1413
externals: string[]
1514
): Promise<Array<SharedInfo>> {
1615
const result: Array<SharedInfo> = [];
17-
1816
const packageInfos = Object.keys(config.shared)
19-
.filter((packageName) => !DEFAULT_SKIP_LIST.has(packageName))
17+
// .filter((packageName) => !isInSkipList(packageName, PREPARED_DEFAULT_SKIP_LIST))
2018
.map((packageName) => getPackageInfo(packageName, fedOptions.workspaceRoot))
2119
.filter((pi) => !!pi) as PackageInfo[];
2220

@@ -39,14 +37,21 @@ export async function bundleShared(
3937
const cachedFile = path.join(cachePath, outFileName);
4038

4139
if (!fs.existsSync(cachedFile)) {
42-
await bundle({
43-
entryPoint: pi.entryPoint,
44-
tsConfigPath: fedOptions.tsConfig,
45-
external: externals,
46-
outfile: cachedFile,
47-
mappedPaths: config.sharedMappings,
48-
packageName: pi.packageName,
49-
});
40+
try {
41+
await bundle({
42+
entryPoint: pi.entryPoint,
43+
tsConfigPath: fedOptions.tsConfig,
44+
external: externals,
45+
outfile: cachedFile,
46+
mappedPaths: config.sharedMappings,
47+
packageName: pi.packageName,
48+
});
49+
}
50+
catch(e) {
51+
console.error('Error bundling', pi.packageName);
52+
console.info(`If you don't need this package, skip it in your federation.config.js!`);
53+
continue;
54+
}
5055
}
5156

5257
const shared = config.shared[pi.packageName];
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,51 @@
1-
export const DEFAULT_SKIP_LIST = new Set([
2-
'@softarc/module-federation-runtime',
3-
'@softarc/module-federation-core',
4-
'@softarc/module-federation',
1+
export type SkipFn = (name: string) => boolean;
2+
export type SkipListEntry = (string | RegExp | SkipFn);
3+
export type SkipList = SkipListEntry[];
4+
5+
export const DEFAULT_SKIP_LIST: SkipList = [
6+
'@softarc/native-federation-runtime',
7+
'@softarc/native-federation',
8+
'@softarc/native-federation-core',
9+
'@softarc/native-federation-esbuild',
510
'@angular-architects/native-federation',
611
'@angular-architects/native-federation-runtime',
712
'es-module-shims',
8-
]);
13+
'zone.js',
14+
'tslib',
15+
/\/schematics(\/|$)/,
16+
(pkg) => pkg.startsWith('@angular/') && !!pkg.match(/\/testing(\/|$)/)
17+
];
18+
19+
export const PREPARED_DEFAULT_SKIP_LIST = prepareSkipList(DEFAULT_SKIP_LIST);
20+
21+
export type PreparedSkipList = {
22+
strings: Set<string>,
23+
functions: SkipFn[],
24+
regexps: RegExp[]
25+
}
26+
27+
export function prepareSkipList(skipList: SkipList): PreparedSkipList {
28+
return {
29+
strings: new Set<string>(skipList.filter(e => typeof e === 'string') as string[]),
30+
functions: skipList.filter(e => typeof e === 'function') as SkipFn[],
31+
regexps: skipList.filter(e => typeof e === 'object') as RegExp[],
32+
}
33+
}
34+
35+
export function isInSkipList(entry: string, skipList: PreparedSkipList): boolean {
36+
37+
if (skipList.strings.has(entry)) {
38+
return true;
39+
}
40+
41+
if (skipList.functions.find(f => f(entry))) {
42+
return true;
43+
}
44+
45+
if (skipList.regexps.find(r => r.test(entry))) {
46+
return true;
47+
}
48+
49+
return false;
50+
51+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { NormalizedFederationConfig } from '../config/federation-config';
2-
import { DEFAULT_SKIP_LIST } from './default-skip-list';
2+
import { isInSkipList, PREPARED_DEFAULT_SKIP_LIST } from './default-skip-list';
33

44
export function getExternals(config: NormalizedFederationConfig) {
55
const shared = Object.keys(config.shared);
66
const sharedMappings = config.sharedMappings.map((m) => m.key);
77

88
const externals = [...shared, ...sharedMappings];
99

10-
return externals.filter((p) => !DEFAULT_SKIP_LIST.has(p));
10+
return externals;
11+
// return externals.filter((p) => !isInSkipList(p, PREPARED_DEFAULT_SKIP_LIST));
1112
}

libs/native-federation-core/src/lib/utils/package-info.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface PackageInfo {
99

1010
export interface PartialPackageJson {
1111
module: string;
12+
main: string;
1213
}
1314

1415
export function getPackageInfo(
@@ -45,7 +46,7 @@ export function getPackageInfo(
4546
if (!relSecondaryPath) {
4647
relSecondaryPath = '.';
4748
} else {
48-
relSecondaryPath = './' + relSecondaryPath;
49+
relSecondaryPath = './' + relSecondaryPath.replace(/\\/g, '/');
4950
}
5051

5152
let cand = mainPkgJson?.exports?.[relSecondaryPath]?.default;
@@ -91,6 +92,14 @@ export function getPackageInfo(
9192
};
9293
}
9394

95+
if (secondaryPgkJson && secondaryPgkJson.main) {
96+
return {
97+
entryPoint: path.join(secondaryPgkPath, secondaryPgkJson.main),
98+
packageName,
99+
version,
100+
};
101+
}
102+
94103
cand = path.join(secondaryPgkPath, 'index.js');
95104
if (fs.existsSync(cand)) {
96105
return {

libs/native-federation-esbuild/src/lib/adapter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export const esBuildAdapter: BuildAdapter = async (options) => {
1919

2020
if (isPkg) {
2121
console.log('Preparing package ...');
22-
2322
await prepareNodePackage(entryPoint, external, tmpFolder);
2423
}
2524

@@ -34,6 +33,7 @@ export const esBuildAdapter: BuildAdapter = async (options) => {
3433
target: ["esnext"],
3534
plugins: [],
3635
});
36+
3737
};
3838

3939
async function prepareNodePackage(entryPoint: string, external: string[], tmpFolder: string) {

libs/native-federation/package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
"url": "https://github.com/angular-architects/module-federation-plugin"
1616
},
1717
"dependencies": {
18-
"@angular-architects/build-angular": "^14.2.0-next.0"
19-
18+
"@angular-architects/build-angular": "^14.2.0-next.0",
19+
"@rollup/plugin-commonjs": "^22.0.2",
20+
"@rollup/plugin-node-resolve": "^13.3.0",
21+
"@rollup/plugin-replace": "^4.0.0",
22+
"rollup": "^2.79.0",
23+
"rollup-plugin-node-externals": "^4.1.1",
24+
"esbuild": "^0.15.5"
2025
}
2126
}

libs/native-federation/src/config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ export {
33
findRootTsConfigJson,
44
share,
55
shareAll,
6-
} from '@angular-architects/module-federation/webpack';
6+
} from '@softarc/native-federation/build';

libs/native-federation/src/utils/angular-esbuild-adapter.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { createCompilerPlugin } from '@angular-devkit/build-angular/src/builders
44
import { createSharedMappingsPlugin } from './shared-mappings-plugin';
55
import { prepareNodePackage } from './prepare-node-package';
66

7-
const SKIP_PACKAGE_PREPARATION = ['@angular', '@ngrx', 'rxjs'];
7+
const SKIP_PACKAGE_PREPARATION = ['@angular', '@ngrx', 'rxjs', 'zone.js'];
88

99
export const AngularEsBuildAdapter: BuildAdapter = async (options) => {
1010
const { entryPoint, tsConfigPath, external, outfile, mappedPaths, packageName } = options;
1111

1212
const pNameOrEmpty = packageName ?? '';
1313

1414
const preparePackage = entryPoint.includes("node_modules")
15-
&& !SKIP_PACKAGE_PREPARATION.find(p => pNameOrEmpty === p);
15+
&& !SKIP_PACKAGE_PREPARATION.find(p => pNameOrEmpty?.split('/')[0] === p);
1616

1717
const pkgName = preparePackage ? inferePkgName(entryPoint) : "";
1818
const tmpFolder = `node_modules/.tmp/native-federation/${pkgName}`;
@@ -28,6 +28,7 @@ export const AngularEsBuildAdapter: BuildAdapter = async (options) => {
2828
bundle: true,
2929
sourcemap: true,
3030
minify: true,
31+
platform: 'node',
3132
format: 'esm',
3233
target: ['esnext'],
3334
plugins: [

0 commit comments

Comments
 (0)