Skip to content

Commit

Permalink
feat(angular): add module-federation-dev-server builder (#9843)
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Apr 14, 2022
1 parent 74a4047 commit 4b846e8
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 1 deletion.
110 changes: 110 additions & 0 deletions docs/generated/packages/angular.json
Expand Up @@ -2963,6 +2963,116 @@
"aliases": [],
"hidden": false,
"path": "/packages/angular/src/builders/webpack-server/schema.json"
},
{
"name": "module-federation-dev-server",
"implementation": "/packages/angular/src/builders/module-federation-dev-server/module-federation-dev-server.impl.ts",
"schema": {
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Schema for Module Federation Dev Server",
"description": "The module-federation-dev-server executor is reserved exclusively for use with host Module Federation applications. It allows the user to specify which remote applications should be served with the host.",
"type": "object",
"presets": [
{
"name": "Using a Different Port",
"keys": ["browserTarget", "port"]
}
],
"properties": {
"browserTarget": {
"type": "string",
"description": "A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
"pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
},
"port": {
"type": "number",
"description": "Port to listen on.",
"default": 4200
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
},
"proxyConfig": {
"type": "string",
"description": "Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server."
},
"ssl": {
"type": "boolean",
"description": "Serve using HTTPS.",
"default": false
},
"sslKey": {
"type": "string",
"description": "SSL key to use for serving HTTPS."
},
"sslCert": {
"type": "string",
"description": "SSL certificate to use for serving HTTPS."
},
"headers": {
"type": "object",
"description": "Custom HTTP headers to be added to all responses.",
"propertyNames": { "pattern": "^[-_A-Za-z0-9]+$" },
"additionalProperties": { "type": "string" }
},
"open": {
"type": "boolean",
"description": "Opens the url in default browser.",
"default": false,
"alias": "o"
},
"verbose": {
"type": "boolean",
"description": "Adds more details to output logging."
},
"liveReload": {
"type": "boolean",
"description": "Whether to reload the page on change, using live-reload.",
"default": true
},
"publicHost": {
"type": "string",
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
},
"allowedHosts": {
"type": "array",
"description": "List of hosts that are allowed to access the dev server.",
"default": [],
"items": { "type": "string" }
},
"servePath": {
"type": "string",
"description": "The pathname where the app will be served."
},
"disableHostCheck": {
"type": "boolean",
"description": "Don't verify connected clients are part of allowed hosts.",
"default": false
},
"hmr": {
"type": "boolean",
"description": "Enable hot module replacement.",
"default": false
},
"watch": {
"type": "boolean",
"description": "Rebuild on change.",
"default": true
},
"poll": {
"type": "number",
"description": "Enable and define the file watching poll time period in milliseconds."
}
},
"additionalProperties": false,
"required": ["browserTarget"]
},
"description": "The module-federation-dev-server executor is reserved exclusively for use with host Module Federation applications. It allows the user to specify which remote applications should be served with the host.",
"aliases": [],
"hidden": false,
"path": "/packages/angular/src/builders/module-federation-dev-server/schema.json"
}
]
}
3 changes: 2 additions & 1 deletion docs/packages.json
Expand Up @@ -13,7 +13,8 @@
"ng-packagr-lite",
"package",
"webpack-browser",
"webpack-server"
"webpack-server",
"module-federation-dev-server"
],
"generators": [
"add-linting",
Expand Down
10 changes: 10 additions & 0 deletions packages/angular/executors.json
Expand Up @@ -24,6 +24,11 @@
"implementation": "./src/builders/webpack-server/webpack-server.impl",
"schema": "./src/builders/webpack-server/schema.json",
"description": "The `webpack-server` executor is very similar to the standard `dev-server` builder provided by the Angular Devkit. It is usually used in tandem with `@nrwl/angular:webpack-browser` when your Angular application uses a custom webpack configuration."
},
"module-federation-dev-server": {
"implementation": "./src/builders/module-federation-dev-server/module-federation-dev-server.impl",
"schema": "./src/builders/module-federation-dev-server/schema.json",
"description": "The module-federation-dev-server executor is reserved exclusively for use with host Module Federation applications. It allows the user to specify which remote applications should be served with the host."
}
},
"builders": {
Expand Down Expand Up @@ -51,6 +56,11 @@
"implementation": "./src/builders/webpack-server/webpack-server.impl",
"schema": "./src/builders/webpack-server/schema.json",
"description": "The `webpack-server` executor is very similar to the standard `dev-server` builder provided by the Angular Devkit. It is usually used in tandem with `@nrwl/angular:webpack-browser` when your Angular application uses a custom webpack configuration."
},
"module-federation-dev-server": {
"implementation": "./src/builders/module-federation-dev-server/module-federation-dev-server.impl",
"schema": "./src/builders/module-federation-dev-server/schema.json",
"description": "The module-federation-dev-server executor is reserved exclusively for use with host Module Federation applications. It allows the user to specify which remote applications should be served with the host."
}
}
}
@@ -0,0 +1,50 @@
import type { Schema } from './schema';
import { Workspaces } from '@nrwl/devkit';
import { scheduleTarget } from 'nx/src/adapter/ngcli-adapter';
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
import { join } from 'path';
import { webpackServer } from '../webpack-server/webpack-server.impl';

export function moduleFederationDevServer(
schema: Schema,
context: BuilderContext
) {
const workspaces = new Workspaces(context.workspaceRoot);
const workspaceConfig = workspaces.readWorkspaceConfiguration();

const p = workspaceConfig.projects[context.target.project];

const mfeConfigPath = join(context.workspaceRoot, p.root, 'mfe.config.js');

let mfeConfig: { remotes: string[] };
try {
mfeConfig = require(mfeConfigPath);
} catch {
throw new Error(
`Could not load ${mfeConfigPath}. Was this project generated with "@nrwl/angular:host"?`
);
}

const { ...options } = schema;
const unparsedRemotes = mfeConfig.remotes.length > 0 ? mfeConfig.remotes : [];
const remotes = unparsedRemotes.map((a) => (Array.isArray(a) ? a[0] : a));

for (const remote of remotes) {
scheduleTarget(
context.workspaceRoot,
{
project: remote,
target: 'serve',
configuration: context.target.configuration,
runOptions: {},
executor: context.builder.builderName,
},
options.verbose
);
}

return webpackServer(options, context);
}

export default createBuilder<JsonObject & Schema>(moduleFederationDevServer);
@@ -0,0 +1,20 @@
export interface Schema {
browserTarget: string;
port: number;
host: string;
proxyConfig?: string;
ssl: boolean;
sslKey?: string;
sslCert?: string;
headers?: Record<string, string>;
open: boolean;
verbose?: boolean;
liveReload: boolean;
publicHost?: string;
allowedHosts?: string[];
servePath?: string;
disableHostCheck?: boolean;
hmr?: boolean;
watch?: boolean;
poll?: number;
}
108 changes: 108 additions & 0 deletions packages/angular/src/builders/module-federation-dev-server/schema.json
@@ -0,0 +1,108 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Schema for Module Federation Dev Server",
"description": "The module-federation-dev-server executor is reserved exclusively for use with host Module Federation applications. It allows the user to specify which remote applications should be served with the host.",
"type": "object",
"presets": [
{
"name": "Using a Different Port",
"keys": ["browserTarget", "port"]
}
],
"properties": {
"browserTarget": {
"type": "string",
"description": "A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
"pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$"
},
"port": {
"type": "number",
"description": "Port to listen on.",
"default": 4200
},
"host": {
"type": "string",
"description": "Host to listen on.",
"default": "localhost"
},
"proxyConfig": {
"type": "string",
"description": "Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server."
},
"ssl": {
"type": "boolean",
"description": "Serve using HTTPS.",
"default": false
},
"sslKey": {
"type": "string",
"description": "SSL key to use for serving HTTPS."
},
"sslCert": {
"type": "string",
"description": "SSL certificate to use for serving HTTPS."
},
"headers": {
"type": "object",
"description": "Custom HTTP headers to be added to all responses.",
"propertyNames": {
"pattern": "^[-_A-Za-z0-9]+$"
},
"additionalProperties": {
"type": "string"
}
},
"open": {
"type": "boolean",
"description": "Opens the url in default browser.",
"default": false,
"alias": "o"
},
"verbose": {
"type": "boolean",
"description": "Adds more details to output logging."
},
"liveReload": {
"type": "boolean",
"description": "Whether to reload the page on change, using live-reload.",
"default": true
},
"publicHost": {
"type": "string",
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies."
},
"allowedHosts": {
"type": "array",
"description": "List of hosts that are allowed to access the dev server.",
"default": [],
"items": {
"type": "string"
}
},
"servePath": {
"type": "string",
"description": "The pathname where the app will be served."
},
"disableHostCheck": {
"type": "boolean",
"description": "Don't verify connected clients are part of allowed hosts.",
"default": false
},
"hmr": {
"type": "boolean",
"description": "Enable hot module replacement.",
"default": false
},
"watch": {
"type": "boolean",
"description": "Rebuild on change.",
"default": true
},
"poll": {
"type": "number",
"description": "Enable and define the file watching poll time period in milliseconds."
}
},
"additionalProperties": false,
"required": ["browserTarget"]
}

1 comment on commit 4b846e8

@vercel
Copy link

@vercel vercel bot commented on 4b846e8 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx.dev
nx-dev-nrwl.vercel.app

Please sign in to comment.