Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE - feat(angular): add generator to migrate old mfe config #9366

Merged
merged 1 commit into from Mar 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 48 additions & 0 deletions docs/generated/api-angular/generators/convert-to-with-mf.md
@@ -0,0 +1,48 @@
---
title: '@nrwl/angular:convert-to-with-mf generator'
description:
'Converts an old micro frontend configuration to use the new withModuleFederation helper. It will run successfully if the following conditions are met:
- Is either a host or remote application
- Shared npm package configurations have not been modified
- Name used to identify the Micro Frontend application matches the project name

_**Note:** This generator will overwrite your webpack config. If you have additional custom configuration in your config file, it will be lost!_'
---

# @nrwl/angular:convert-to-with-mf

Converts an old micro frontend configuration to use the new withModuleFederation helper. It will run successfully if the following conditions are met:

- Is either a host or remote application
- Shared npm package configurations have not been modified
- Name used to identify the Micro Frontend application matches the project name

_**Note:** This generator will overwrite your webpack config. If you have additional custom configuration in your config file, it will be lost!_

## Usage

```bash
nx generate convert-to-with-mf ...
```

By default, Nx will search for `convert-to-with-mf` in the default collection provisioned in `workspace.json`.

You can specify the collection explicitly as follows:

```bash
nx g @nrwl/angular:convert-to-with-mf ...
```

Show what will be generated without writing to disk:

```bash
nx g convert-to-with-mf ... --dry-run
```

## Options

### project

Type: `string`

The name of the micro frontend project to migrate.
5 changes: 5 additions & 0 deletions docs/map.json
Expand Up @@ -689,6 +689,11 @@
"id": "move",
"file": "generated/api-angular/generators/move"
},
{
"name": "convert-to-with-mf generator",
"id": "convert-to-with-mf",
"file": "generated/api-angular/generators/convert-to-with-mf"
},
{
"name": "ngrx generator",
"id": "ngrx",
Expand Down
10 changes: 10 additions & 0 deletions packages/angular/generators.json
Expand Up @@ -80,6 +80,11 @@
"aliases": ["mv"],
"description": "Moves an Angular application or library to another folder within the workspace and updates the project configuration."
},
"convert-to-with-mf": {
"factory": "./src/generators/convert-to-with-mf/convert-to-with-mf.compat",
"schema": "./src/generators/convert-to-with-mf/schema.json",
"description": "Converts an old micro frontend configuration to use the new withModuleFederation helper. It will run successfully if the following conditions are met: \n - Is either a host or remote application \n - Shared npm package configurations have not been modified \n - Name used to identify the Micro Frontend application matches the project name \n\n _**Note:** This generator will overwrite your webpack config. If you have additional custom configuration in your config file, it will be lost!_"
},
"mfe-host": {
"factory": "./src/generators/mfe-host/mfe-host.compat",
"schema": "./src/generators/mfe-host/schema.json",
Expand Down Expand Up @@ -225,6 +230,11 @@
"aliases": ["mv"],
"description": "Moves an Angular application or library to another folder within the workspace and updates the project configuration."
},
"convert-to-with-mf": {
"factory": "./src/generators/convert-to-with-mf/convert-to-with-mf",
"schema": "./src/generators/convert-to-with-mf/schema.json",
"description": "Converts an old micro frontend configuration to use the new withModuleFederation helper. It will run successfully if the following conditions are met: \n - Is either a host or remote application \n - Shared npm package configurations have not been modified \n - Name used to identify the Micro Frontend application matches the project name \n\n _**Note:** This generator will overwrite your webpack config. If you have additional custom configuration in your config file, it will be lost!_"
},
"mfe-host": {
"factory": "./src/generators/mfe-host/mfe-host",
"schema": "./src/generators/mfe-host/schema.json",
Expand Down
@@ -0,0 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`convertToWithMF should migrate a standard previous generated host config correctly 1`] = `
"const { withModuleFederation } = require('@nrwl/angular/module-federation');
module.exports = withModuleFederation({
name: 'host1',
remotes: [['remote1', 'http://localhost:4201']],
});"
`;

exports[`convertToWithMF should migrate a standard previous generated remote config correctly 1`] = `
"const { withModuleFederation } = require('@nrwl/angular/module-federation');
module.exports = withModuleFederation({
name: 'remote1',
exposes: {
'./Module': 'apps/remote1/src/app/remote-entry/entry.module.ts',
},
});"
`;

exports[`convertToWithMF should migrate a standard previous generated remote config using object shared syntax correctly 1`] = `
"const { withModuleFederation } = require('@nrwl/angular/module-federation');
module.exports = withModuleFederation({
name: 'remote1',
exposes: {
'./Module': 'apps/remote1/src/app/remote-entry/entry.module.ts',
},
});"
`;
@@ -0,0 +1,4 @@
import { convertNxGenerator } from '@nrwl/devkit';
import convertToWithMF from './convert-to-with-mf';

export default convertNxGenerator(convertToWithMF);
@@ -0,0 +1,166 @@
import { addProjectConfiguration } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import {
STANDARD_HOST_MFE_CONFIG,
STANDARD_REMOTE_MFE_CONFIG,
OLD_OBJECT_SHARED_SYNTAX,
ERROR_NAME_DOESNT_MATCH,
ERROR_SHARED_PACKAGES_DOESNT_MATCH,
} from './convert-to-with-mf.test-data';
import convertToWithMF from './convert-to-with-mf';

describe('convertToWithMF', () => {
it('should migrate a standard previous generated host config correctly', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'host1', {
name: 'host1',
root: 'apps/host1',
sourceRoot: 'apps/host1/src',
targets: {
build: {
executor: '@nrwl/angular:webpack-browser',
options: {
customWebpackConfig: {
path: 'apps/host1/webpack.config.js',
},
},
},
},
});

tree.write('apps/host1/webpack.config.js', STANDARD_HOST_MFE_CONFIG);

// ACT
await convertToWithMF(tree, {
project: 'host1',
});

// ASSERT
const webpackSource = tree.read('apps/host1/webpack.config.js', 'utf-8');
expect(webpackSource).toMatchSnapshot();
});

it('should migrate a standard previous generated remote config correctly', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'remote1', {
name: 'remote1',
root: 'apps/remote1',
sourceRoot: 'apps/remote1/src',
targets: {
build: {
executor: '@nrwl/angular:webpack-browser',
options: {
customWebpackConfig: {
path: 'apps/remote1/webpack.config.js',
},
},
},
},
});

tree.write('apps/remote1/webpack.config.js', STANDARD_REMOTE_MFE_CONFIG);

// ACT
await convertToWithMF(tree, {
project: 'remote1',
});

// ASSERT
const webpackSource = tree.read('apps/remote1/webpack.config.js', 'utf-8');
expect(webpackSource).toMatchSnapshot();
});

it('should migrate a standard previous generated remote config using object shared syntax correctly', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'remote1', {
name: 'remote1',
root: 'apps/remote1',
sourceRoot: 'apps/remote1/src',
targets: {
build: {
executor: '@nrwl/angular:webpack-browser',
options: {
customWebpackConfig: {
path: 'apps/remote1/webpack.config.js',
},
},
},
},
});

tree.write('apps/remote1/webpack.config.js', OLD_OBJECT_SHARED_SYNTAX);

// ACT
await convertToWithMF(tree, {
project: 'remote1',
});

// ASSERT
const webpackSource = tree.read('apps/remote1/webpack.config.js', 'utf-8');
expect(webpackSource).toMatchSnapshot();
});

it('should throw when the uniqueName doesnt match the project name', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'remote1', {
name: 'remote1',
root: 'apps/remote1',
sourceRoot: 'apps/remote1/src',
targets: {
build: {
executor: '@nrwl/angular:webpack-browser',
options: {
customWebpackConfig: {
path: 'apps/remote1/webpack.config.js',
},
},
},
},
});

tree.write('apps/remote1/webpack.config.js', ERROR_NAME_DOESNT_MATCH);

// ACT & ASSERT
await expect(
convertToWithMF(tree, {
project: 'remote1',
})
).rejects.toThrow();
});

it('should throw when the shared npm packages configs has been modified', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace(2);
addProjectConfiguration(tree, 'host1', {
name: 'host1',
root: 'apps/host1',
sourceRoot: 'apps/host1/src',
targets: {
build: {
executor: '@nrwl/angular:webpack-browser',
options: {
customWebpackConfig: {
path: 'apps/host1/webpack.config.js',
},
},
},
},
});

tree.write(
'apps/host1/webpack.config.js',
ERROR_SHARED_PACKAGES_DOESNT_MATCH
);

// ACT & ASSERT
await expect(
convertToWithMF(tree, {
project: 'host1',
})
).rejects.toThrow();
});
});