Skip to content

Commit

Permalink
fix(angular): support secondary entry points #10329 (#10615)
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Jun 9, 2022
1 parent e8cfa35 commit 67a2777
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
18 changes: 15 additions & 3 deletions e2e/angular-core/src/projects.test.ts
Expand Up @@ -222,13 +222,14 @@ describe('Angular Projects', () => {
expect(buildOutput).toContain('Successfully ran target build');
});

it('MFE - should serve the host and remote apps successfully, even with a shared library between them', async () => {
it('MFE - should serve the host and remote apps successfully, even with a shared library with a secondary entry point between them', async () => {
// ACT + ASSERT
const port1 = 4200;
const port2 = 4206;
const hostApp = uniq('app');
const remoteApp1 = uniq('remote');
const sharedLib = uniq('sharedLib');
const sharedLib = uniq('shared-lib');
const secondaryEntry = uniq('secondary');

// generate host app
runCLI(
Expand All @@ -241,7 +242,12 @@ describe('Angular Projects', () => {
);

// generate a shared lib
runCLI(`generate @nrwl/angular:library ${sharedLib} --no-interactive`);
runCLI(
`generate @nrwl/angular:library ${sharedLib} --buildable --no-interactive`
);
runCLI(
`generate @nrwl/angular:library-secondary-entry-point --library=${sharedLib} --name=${secondaryEntry} --no-interactive`
);

// update the files to use shared library
updateFile(
Expand All @@ -251,6 +257,9 @@ describe('Angular Projects', () => {
import { ${
names(sharedLib).className
}Module } from '@${proj}/${sharedLib}';
import { ${
names(secondaryEntry).className
}Module } from '@${proj}/${secondaryEntry}';
import { AppComponent } from './app.component';
import { NxWelcomeComponent } from './nx-welcome.component';
import { RouterModule } from '@angular/router';
Expand Down Expand Up @@ -285,6 +294,9 @@ describe('Angular Projects', () => {
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { ${names(sharedLib).className}Module } from '@${proj}/${sharedLib}';
import { ${
names(secondaryEntry).className
}Module } from '@${proj}/${secondaryEntry}';
import { RemoteEntryComponent } from './entry.component';
@NgModule({
Expand Down
70 changes: 70 additions & 0 deletions packages/angular/src/utils/mfe/mfe-webpack.ts
Expand Up @@ -22,6 +22,65 @@ export interface SharedLibraryConfig {
eager?: boolean;
}

function traverseUpFileTreeAndPerformActionUntil(
dirPath: string,
endPath: string,
action: (dirname: string) => boolean
) {
while (dirPath !== endPath) {
if (action(dirPath)) {
break;
}
dirPath = dirname(dirPath);
}
}

function collectWorkspaceLibrarySecondaryEntryPoints(
library: string,
libraryPath: string,
tsconfigPathAliases: Record<string, string[]>
) {
let libraryRootDirPath = libraryPath;
traverseUpFileTreeAndPerformActionUntil(
dirname(libraryRootDirPath),
workspaceRoot,
(currentDirPath) => {
if (existsSync(join(currentDirPath, 'package.json'))) {
libraryRootDirPath = currentDirPath;
return true;
}
}
);

const aliasesUnderLibrary = Object.keys(tsconfigPathAliases).filter(
(libName) => libName.startsWith(library) && libName !== library
);
const secondaryEntryPoints = [];
for (const alias of aliasesUnderLibrary) {
const pathToLib = dirname(
join(workspaceRoot, tsconfigPathAliases[alias][0])
);
let isSecondaryEntrypoint = false;
let searchDir = pathToLib;
traverseUpFileTreeAndPerformActionUntil(
searchDir,
libraryRootDirPath,
(currentDirPath) => {
if (existsSync(join(currentDirPath, 'ng-package.json'))) {
isSecondaryEntrypoint = true;
return true;
}
}
);

if (isSecondaryEntrypoint) {
secondaryEntryPoints.push({ name: alias, path: pathToLib });
}
}

return secondaryEntryPoints;
}

export function shareWorkspaceLibraries(
libraries: string[],
tsConfigPath = process.env.NX_TSCONFIG_PATH ?? getRootTsConfigPath()
Expand All @@ -48,6 +107,17 @@ export function shareWorkspaceLibraries(
for (const [key, paths] of Object.entries(tsconfigPathAliases)) {
if (libraries && libraries.includes(key)) {
const pathToLib = normalize(join(workspaceRoot, paths[0]));
collectWorkspaceLibrarySecondaryEntryPoints(
key,
pathToLib,
tsconfigPathAliases
).forEach(({ name, path }) =>
pathMappings.push({
name,
path,
})
);

pathMappings.push({
name: key,
path: pathToLib,
Expand Down

0 comments on commit 67a2777

Please sign in to comment.