Skip to content

Commit

Permalink
feat(angular): add mfe helpers for sharing workspace libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Mar 9, 2022
1 parent 16c6891 commit 3c36c69
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/angular/package.json
Original file line number Diff line number Diff line change
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",
"./mfe-utils": "./src/utils/mfe-webpack.js"
},
"author": "Victor Savkin",
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { normalizeOptions } from './lib';
import type { Schema } from './schema';

export function webpackServer(schema: Schema, context: BuilderContext) {
process.env.NX_TSCONFIG_PATH = joinPathFragments(
context.workspaceRoot,
'tsconfig.base.json'
);

const options = normalizeOptions(schema);
const workspaceConfig = new Workspaces(
context.workspaceRoot
Expand Down
67 changes: 67 additions & 0 deletions packages/angular/src/utils/mfe-webpack.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
jest.mock('fs');
jest.mock('@nrwl/workspace');
import * as fs from 'fs';
import * as workspace from '@nrwl/workspace';

import { shareWorkspaceLibraries } from './mfe-webpack';

describe('MFE Webpack Utils', () => {
afterEach(() => jest.clearAllMocks());

it('should error when the tsconfig file does not exist', () => {
// ARRANGE
(fs.existsSync as jest.Mock).mockReturnValue(false);

// ACT
try {
shareWorkspaceLibraries(['@myorg/shared']);
} catch (error) {
// ASSERT
expect(error.message).toEqual(
'NX MFE: TsConfig Path for workspace libraries does not exist! (undefined)'
);
}
});

it('should create an object with correct setup', () => {
// ARRANGE
(fs.existsSync as jest.Mock).mockReturnValue(true);
(workspace.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
'@myorg/shared': ['/libs/shared/src/index.ts'],
},
},
});

// ACT
const sharedLibraries = shareWorkspaceLibraries(['@myorg/shared']);
// ASSERT
expect(sharedLibraries.getAliases()).toHaveProperty('@myorg/shared');
expect(sharedLibraries.getAliases()['@myorg/shared']).toContain(
'libs/shared/src/index.ts'
);
expect(sharedLibraries.getLibraries()).toEqual({
'@myorg/shared': {
eager: undefined,
requiredVersion: false,
},
});
});

it('should create an object with empty setup when tsconfig does not contain the shared lib', () => {
// ARRANGE
(fs.existsSync as jest.Mock).mockReturnValue(true);
(workspace.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {},
},
});

// ACT
const sharedLibraries = shareWorkspaceLibraries(['@myorg/shared']);
// ASSERT
expect(sharedLibraries.getAliases()).toEqual({});
expect(sharedLibraries.getLibraries()).toEqual({});
});
});
73 changes: 73 additions & 0 deletions packages/angular/src/utils/mfe-webpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { readTsConfig } from '@nrwl/workspace';
import { existsSync } from 'fs';
import { NormalModuleReplacementPlugin } from 'webpack';
import { appRootPath as rootPath } from '@nrwl/tao/src/utils/app-root';
import { normalizePath, joinPathFragments } from '@nrwl/devkit';
import { dirname } from 'path';
import { ParsedCommandLine } from 'typescript';

export function shareWorkspaceLibraries(
libraries: string[],
tsConfigPath = process.env.NX_TSCONFIG_PATH
) {
if (!existsSync(tsConfigPath)) {
throw new Error(
`NX MFE: TsConfig Path for workspace libraries does not exist! (${tsConfigPath})`
);
}

const tsConfig: ParsedCommandLine = readTsConfig(tsConfigPath);
const tsconfigPathAliases = tsConfig.options?.paths;

if (!tsconfigPathAliases) {
return {
getAliases: () => [],
getLibraries: () => [],
getReplacementPlugin: () =>
new NormalModuleReplacementPlugin(/./, () => {}),
};
}

const pathMappings: { name: string; path: string }[] = [];
for (const [key, paths] of Object.entries(tsconfigPathAliases)) {
if (libraries && libraries.includes(key)) {
const pathToLib = normalizePath(joinPathFragments(rootPath, paths[0]));
pathMappings.push({
name: key,
path: pathToLib,
});
}
}

return {
getAliases: () =>
pathMappings.reduce(
(aliases, library) => ({ ...aliases, [library.name]: library.path }),
{}
),
getLibraries: (eager?: boolean) =>
pathMappings.reduce(
(libraries, library) => ({
...libraries,
[library.name]: { requiredVersion: false, eager },
}),
{}
),
getReplacementPlugin: () =>
new NormalModuleReplacementPlugin(/./, (req) => {
if (!req.request.startsWith('.')) {
return;
}

const from = req.context;
const to = normalizePath(joinPathFragments(req.context, req.request));

for (const library of pathMappings) {
const libFolder = normalizePath(dirname(library.path));
if (!from.startsWith(libFolder) && to.startsWith(libFolder)) {
req.request = library.name;
}
}
}),
};
}

0 comments on commit 3c36c69

Please sign in to comment.