Skip to content

Commit

Permalink
feat(angular): withModuleFederation helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Mar 11, 2022
1 parent a32d46c commit 1141c3a
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 4 deletions.
1 change: 1 addition & 0 deletions .verdaccio/htpasswd
@@ -1 +1,2 @@
test:$6FrCaT/v0dwE:autocreated 2020-03-25T19:10:50.254Z
colum:QozHQ9ck9zOe2:autocreated 2022-03-10T12:13:00.712Z
3 changes: 2 additions & 1 deletion packages/angular/package.json
Expand Up @@ -21,7 +21,8 @@
"./generators": "./generators.js",
"./executors": "./executors.js",
"./tailwind": "./tailwind.js",
"./src/generators/utils": "./src/generators/utils/index.js"
"./src/generators/utils": "./src/generators/utils/index.js",
"./module-federation": "./src/utils/mfe/with-module-federation.js"
},
"author": "Victor Savkin",
"license": "MIT",
Expand Down
@@ -0,0 +1,101 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`withModuleFederation should create a host config correctly 1`] = `
Object {
"experiments": Object {
"outputModule": true,
},
"optimization": Object {
"runtimeChunk": false,
},
"output": Object {
"publicPath": "auto",
"uniqueName": "host",
},
"plugins": Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": undefined,
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "host",
"remotes": Object {
"remote1": "http:/localhost:4201/remoteEntry.mjs",
},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
],
"resolve": Object {
"alias": Object {
"shared": "/Users/columferry/dev/nrwl/nx/libs/shared/src/index.ts",
},
},
}
`;

exports[`withModuleFederation should create a remote config correctly 1`] = `
Object {
"experiments": Object {
"outputModule": true,
},
"optimization": Object {
"runtimeChunk": false,
},
"output": Object {
"publicPath": "auto",
"uniqueName": "remote1",
},
"plugins": Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
],
"resolve": Object {
"alias": Object {
"shared": "/Users/columferry/dev/nrwl/nx/libs/shared/src/index.ts",
},
},
}
`;
Expand Up @@ -6,6 +6,13 @@ import { normalizePath, joinPathFragments } from '@nrwl/devkit';
import { dirname } from 'path';
import { ParsedCommandLine } from 'typescript';

export interface SharedLibraryConfig {
singleton: boolean;
strictVersion: boolean;
requiredVersion: string;
eager: boolean;
}

export function shareWorkspaceLibraries(
libraries: string[],
tsConfigPath = process.env.NX_TSCONFIG_PATH
Expand All @@ -22,7 +29,7 @@ export function shareWorkspaceLibraries(
if (!tsconfigPathAliases) {
return {
getAliases: () => [],
getLibraries: () => [],
getLibraries: () => {},
getReplacementPlugin: () =>
new NormalModuleReplacementPlugin(/./, () => {}),
};
Expand All @@ -45,7 +52,7 @@ export function shareWorkspaceLibraries(
(aliases, library) => ({ ...aliases, [library.name]: library.path }),
{}
),
getLibraries: (eager?: boolean) =>
getLibraries: (eager?: boolean): Record<string, SharedLibraryConfig> =>
pathMappings.reduce(
(libraries, library) => ({
...libraries,
Expand All @@ -72,7 +79,9 @@ export function shareWorkspaceLibraries(
};
}

export function sharePackages(packages: string[]) {
export function sharePackages(
packages: string[]
): Record<string, SharedLibraryConfig> {
const pkgJsonPath = joinPathFragments(rootPath, 'package.json');
if (!existsSync(pkgJsonPath)) {
throw new Error(
Expand Down
107 changes: 107 additions & 0 deletions packages/angular/src/utils/mfe/with-module-federation.spec.ts
@@ -0,0 +1,107 @@
jest.mock('fs');
jest.mock('@nrwl/workspace/src/core/project-graph');
jest.mock('@nrwl/workspace');
import * as graph from '@nrwl/workspace/src/core/project-graph';
import * as workspace from '@nrwl/workspace';
import * as fs from 'fs';

import { withModuleFederation } from './with-module-federation';

describe('withModuleFederation', () => {
afterEach(() => jest.clearAllMocks());
it('should create a host config correctly', async () => {
// ARRANGE
(graph.createProjectGraphAsync as jest.Mock).mockReturnValue(
Promise.resolve({
dependencies: {
host: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'shared' },
],
},
})
);

(workspace.readWorkspaceJson as jest.Mock).mockReturnValue({
projects: {
remote1: {
targets: {
serve: {
options: {
publicHost: 'http://localhost:4201',
},
},
},
},
},
});

(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.readFileSync as jest.Mock).mockReturnValue(
JSON.stringify({
dependencies: {
'@angular/core': '~13.2.0',
},
})
);

(workspace.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
},
},
});

// ACT
const config = await withModuleFederation({
name: 'host',
remotes: ['remote1'],
});

// ASSERT
expect(config).toMatchSnapshot();
});

it('should create a remote config correctly', async () => {
// ARRANGE
(graph.createProjectGraphAsync as jest.Mock).mockReturnValue(
Promise.resolve({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'shared' },
],
},
})
);

(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.readFileSync as jest.Mock).mockReturnValue(
JSON.stringify({
dependencies: {
'@angular/core': '~13.2.0',
},
})
);

(workspace.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
},
},
});

// ACT
const config = await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
});

// ASSERT
expect(config).toMatchSnapshot();
});
});

0 comments on commit 1141c3a

Please sign in to comment.