Skip to content

Commit

Permalink
fix(angular): shared transitive npm deps from host and remote applica… (
Browse files Browse the repository at this point in the history
  • Loading branch information
yharaskrik committed Apr 26, 2022
1 parent 68207ef commit 4d17b32
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 35 deletions.
Expand Up @@ -23,6 +23,11 @@ Array [
"eager": undefined,
"requiredVersion": false,
},
"lodash": Object {
"requiredVersion": undefined,
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
Expand Down
Expand Up @@ -140,7 +140,7 @@ describe('withModuleFederation', () => {
{ target: 'npm:zone.js' },
{ target: 'core' },
],
core: [{ target: 'shared' }],
core: [{ target: 'shared' }, { target: 'npm:lodash' }],
},
});

Expand Down
55 changes: 39 additions & 16 deletions packages/angular/src/utils/mfe/with-module-federation.ts
Expand Up @@ -30,9 +30,15 @@ export interface MFEConfig {
) => SharedLibraryConfig | false;
}

interface DependencySets {
workspaceLibraries: Set<string>;
npmPackages: Set<string>;
}

function recursivelyResolveWorkspaceDependents(
projectGraph: ProjectGraph<any>,
target: string,
dependencySets: DependencySets,
seenTargets: Set<string> = new Set()
) {
if (seenTargets.has(target)) {
Expand All @@ -43,14 +49,27 @@ function recursivelyResolveWorkspaceDependents(

const workspaceDependencies = (
projectGraph.dependencies[target] ?? []
).filter((dep) => !dep.target.startsWith('npm:'));
).filter((dep) => {
const isNpm = dep.target.startsWith('npm:');

// If this is a npm dep ensure it is going to be added as a dep of this MFE so it can be shared if needed
if (isNpm) {
dependencySets.npmPackages.add(dep.target.replace('npm:', ''));
} else {
dependencySets.workspaceLibraries.add(dep.target);
}

return !isNpm;
});

if (workspaceDependencies.length > 0) {
for (const dep of workspaceDependencies) {
dependencies = [
...dependencies,
...recursivelyResolveWorkspaceDependents(
projectGraph,
dep.target,
dependencySets,
seenTargets
),
];
Expand Down Expand Up @@ -103,7 +122,8 @@ async function getDependentPackagesForProject(name: string) {
projectGraph = await createProjectGraphAsync();
}

const deps = projectGraph.dependencies[name].reduce(
// Build Sets for the direct deps (internal and external) for this MFE app
const dependencySets = projectGraph.dependencies[name].reduce(
(dependencies, dependency) => {
const workspaceLibraries = new Set(dependencies.workspaceLibraries);
const npmPackages = new Set(dependencies.npmPackages);
Expand All @@ -115,24 +135,27 @@ async function getDependentPackagesForProject(name: string) {
}

return {
workspaceLibraries: [...workspaceLibraries],
npmPackages: [...npmPackages],
workspaceLibraries,
npmPackages,
};
},
{ workspaceLibraries: [], npmPackages: [] }
{ workspaceLibraries: new Set<string>(), npmPackages: new Set<string>() }
);

const seenWorkspaceLibraries = new Set<string>();
deps.workspaceLibraries = deps.workspaceLibraries.reduce(
(workspaceLibraryDeps, workspaceLibrary) => [
...workspaceLibraryDeps,
...recursivelyResolveWorkspaceDependents(
projectGraph,
workspaceLibrary,
seenWorkspaceLibraries
),
],
[]
);
dependencySets.workspaceLibraries.forEach((workspaceLibrary) => {
recursivelyResolveWorkspaceDependents(
projectGraph,
workspaceLibrary,
dependencySets,
seenWorkspaceLibraries
);
});

const deps = {
workspaceLibraries: [...dependencySets.workspaceLibraries],
npmPackages: [...dependencySets.npmPackages],
};

deps.workspaceLibraries = mapWorkspaceLibrariesToTsConfigImport(
deps.workspaceLibraries
Expand Down
58 changes: 40 additions & 18 deletions packages/react/src/module-federation/with-module-federation.ts
Expand Up @@ -15,9 +15,15 @@ import { readWorkspaceJson } from 'nx/src/project-graph/file-utils';
import { ModuleFederationConfig, Remotes } from './models';
import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

interface DependencySets {
workspaceLibraries: Set<string>;
npmPackages: Set<string>;
}

function recursivelyResolveWorkspaceDependents(
projectGraph: ProjectGraph<any>,
target: string,
dependencySets: DependencySets,
seenTargets: Set<string> = new Set()
) {
if (seenTargets.has(target)) {
Expand All @@ -28,14 +34,27 @@ function recursivelyResolveWorkspaceDependents(

const workspaceDependencies = (
projectGraph.dependencies[target] ?? []
).filter((dep) => !dep.target.startsWith('npm:'));
).filter((dep) => {
const isNpm = dep.target.startsWith('npm:');

// If this is a npm dep ensure it is going to be added as a dep of this MFE so it can be shared if needed
if (isNpm) {
dependencySets.npmPackages.add(dep.target.replace('npm:', ''));
} else {
dependencySets.workspaceLibraries.add(dep.target);
}

return !isNpm;
});

if (workspaceDependencies.length > 0) {
for (const dep of workspaceDependencies) {
dependencies = [
...dependencies,
...recursivelyResolveWorkspaceDependents(
projectGraph,
dep.target,
dependencySets,
seenTargets
),
];
Expand Down Expand Up @@ -81,15 +100,15 @@ function mapWorkspaceLibrariesToTsConfigImport(workspaceLibraries: string[]) {
}

async function getDependentPackagesForProject(name: string) {
let projectGraph: ProjectGraph;

let projectGraph: ProjectGraph<any>;
try {
projectGraph = readCachedProjectGraph();
} catch (e) {
projectGraph = await createProjectGraphAsync();
}

const deps = projectGraph.dependencies[name].reduce(
// Build Sets for the direct deps (internal and external) for this MFE app
const dependencySets = projectGraph.dependencies[name].reduce(
(dependencies, dependency) => {
const workspaceLibraries = new Set(dependencies.workspaceLibraries);
const npmPackages = new Set(dependencies.npmPackages);
Expand All @@ -101,24 +120,27 @@ async function getDependentPackagesForProject(name: string) {
}

return {
workspaceLibraries: [...workspaceLibraries],
npmPackages: [...npmPackages],
workspaceLibraries,
npmPackages,
};
},
{ workspaceLibraries: [], npmPackages: [] }
{ workspaceLibraries: new Set<string>(), npmPackages: new Set<string>() }
);

const seenWorkspaceLibraries = new Set<string>();
deps.workspaceLibraries = deps.workspaceLibraries.reduce(
(workspaceLibraryDeps, workspaceLibrary) => [
...workspaceLibraryDeps,
...recursivelyResolveWorkspaceDependents(
projectGraph,
workspaceLibrary,
seenWorkspaceLibraries
),
],
[]
);
dependencySets.workspaceLibraries.forEach((workspaceLibrary) => {
recursivelyResolveWorkspaceDependents(
projectGraph,
workspaceLibrary,
dependencySets,
seenWorkspaceLibraries
);
});

const deps = {
workspaceLibraries: [...dependencySets.workspaceLibraries],
npmPackages: [...dependencySets.npmPackages],
};

deps.workspaceLibraries = mapWorkspaceLibrariesToTsConfigImport(
deps.workspaceLibraries
Expand Down

0 comments on commit 4d17b32

Please sign in to comment.