Skip to content

Commit

Permalink
feat(mf): add remove schematic
Browse files Browse the repository at this point in the history
  • Loading branch information
manfredsteyer committed Jun 22, 2024
1 parent 6170f35 commit afa8343
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 26 deletions.
6 changes: 3 additions & 3 deletions libs/mf-runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@angular-architects/module-federation-runtime",
"license": "MIT",
"version": "17.0.7",
"version": "18.0.3",
"peerDependencies": {
"@angular/common": ">=17.0.0",
"@angular/core": ">=17.0.0"
"@angular/common": ">=18.0.0",
"@angular/core": ">=18.0.0"
},
"dependencies": {
"tslib": "^2.0.0"
Expand Down
2 changes: 1 addition & 1 deletion libs/mf-tools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@angular-architects/module-federation-tools",
"version": "17.0.7",
"version": "18.0.3",
"license": "MIT",
"peerDependencies": {},
"dependencies": {
Expand Down
5 changes: 5 additions & 0 deletions libs/mf/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
"factory": "./src/schematics/boot-async/schematic",
"schema": "./src/schematics/boot-async/schema.json",
"description": "Enables or disables async bootstrapping"
},
"remove": {
"factory": "./src/schematics/remove/schematic",
"schema": "./src/schematics/remove/schema.json",
"description": "Removes Module Federation"
}
}
}
4 changes: 2 additions & 2 deletions libs/mf/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@angular-architects/module-federation",
"version": "17.0.7",
"version": "18.0.3",
"license": "MIT",
"repository": {
"type": "GitHub",
Expand All @@ -17,7 +17,7 @@
"schematics": "./collection.json",
"builders": "./builders.json",
"dependencies": {
"@angular-architects/module-federation-runtime": "17.0.7",
"@angular-architects/module-federation-runtime": "18.0.3",
"word-wrap": "^1.2.3",
"callsite": "^1.0.0",
"node-fetch": "^2.6.7",
Expand Down
37 changes: 25 additions & 12 deletions libs/mf/post-build.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
const fs = require('fs');
const path = require('path');

const index = fs.readFileSync(path.join(__dirname, 'src/index.ts'), {
encoding: 'utf-8',
});
fs.writeFileSync(
path.join(__dirname, '../../dist/libs/mf/src/index.js'),
index
);

const nguniversal = fs.readFileSync(
path.join(__dirname, 'src/nguniversal.ts'),
// const index = fs.readFileSync(path.join(__dirname, 'src/index.ts'), {
// encoding: 'utf-8',
// });
// fs.writeFileSync(
// path.join(__dirname, '../../dist/libs/mf/src/index.js'),
// index
// );

// const nguniversal = fs.readFileSync(
// path.join(__dirname, 'src/nguniversal.ts'),
// {
// encoding: 'utf-8',
// }
// );
// fs.writeFileSync(
// path.join(__dirname, '../../dist/libs/mf/src/nguniversal.js'),
// nguniversal
// );


const webpack2 = fs.readFileSync(
path.join(__dirname, 'webpack.ts'),
{
encoding: 'utf-8',
}
);
fs.writeFileSync(
path.join(__dirname, '../../dist/libs/mf/src/nguniversal.js'),
nguniversal
);
path.join(__dirname, '../../dist/libs/mf/webpack.js'),
'module.exports = require("./src/webpack.js");'
);
4 changes: 0 additions & 4 deletions libs/mf/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@
"post-build": {
"dependsOn": ["build"],
"executor": "nx:run-commands",
"outputs": [
"{options.outputPath}/src/index.js",
"{options.outputPath}/src/nguniversal.ts"
],
"options": {
"cwd": "libs/mf",
"command": "node post-build.js"
Expand Down
75 changes: 71 additions & 4 deletions libs/mf/src/schematics/mf/schematic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function makeMainAsync(main: string, options: MfSchematicSchema): Rule {
if (options.type === 'dynamic-host') {
newMainContent = `import { initFederation } from '@angular-architects/module-federation';
initFederation('/assets/mf.manifest.json')
initFederation('mf.manifest.json')
.catch(err => console.error(err))
.then(_ => import('./bootstrap'))
.catch(err => console.error(err));
Expand Down Expand Up @@ -227,20 +227,42 @@ export default function config(options: MfSchematicSchema): Rule {
.join(projectRoot, 'webpack.prod.config.js')
.replace(/\\/g, '/');
const manifestPath = path
.join(projectRoot, 'src/assets/mf.manifest.json')
.join(projectRoot, 'public/mf.manifest.json')
.replace(/\\/g, '/');

const buildConfig = projectConfig?.architect?.build;
const isApplicationBuilder =
buildConfig?.builder === '@angular-devkit/build-angular:application';

if (isApplicationBuilder) {
console.warn(`\nWARNING: This package uses the tradtional webpack-based Module Federation implementation and not the fast new esbuild-based ApplicationBuilder.`)
console.warn(`\nFor new projects, consider Native Federation as an alternative: https://shorturl.at/0ZQ0j`)
console.warn(`\nHowever, if you want to add a new host or remote to an existing Module Federation-based system, this package is what you are looking for.`)
console.warn(`\nDo you want to proceeed: [y] Yes [n] No \n`)

for (; ;) {
const key = await readKey();
if (key === 'Y' || key === 'y') {
break;
}
if (key === 'N' || key === 'n') {
process.exit(0);
}
}

}

if (buildConfig?.options?.browser) {
buildConfig.options.main = buildConfig.options.browser;
delete buildConfig.options.browser;
delete buildConfig.options.server;
delete buildConfig.options.prerender;
}

if (buildConfig?.options?.assets) {
updateAssets();
}

const port = parseInt(options.port) || 4200;
const main = projectConfig.architect.build.options.main;

Expand Down Expand Up @@ -376,11 +398,11 @@ export default function config(options: MfSchematicSchema): Rule {

const dep = getPackageJsonDependency(tree, 'ngx-build-plus');

if (!dep || !semver.satisfies(dep.version, '>=17.0.0')) {
if (!dep || !semver.satisfies(dep.version, '>=18.0.0')) {
addPackageJsonDependency(tree, {
name: 'ngx-build-plus',
type: NodeDependencyType.Dev,
version: '^17.0.0',
version: '^18.0.0',
overwrite: true,
});

Expand All @@ -392,9 +414,32 @@ export default function config(options: MfSchematicSchema): Rule {
makeMainAsync(main, options),
adjustSSR(projectSourceRoot, ssrMappings),
]);

function updateAssets() {
for (const asset of buildConfig.options.assets) {
if (typeof asset === 'object' && typeof asset.output === 'undefined') {
asset.output = '.';
}
}
}
};
}

async function readKey() {
return await new Promise((r) => {
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', (key) => {
process.stdin.setRawMode(false);
process.stdin.pause();
r(key);
});

});
}

function updateTsConfig(tree, tsConfigName: string) {
const tsConfig = json5.parse(tree.read(tsConfigName).toString('utf-8'));
const target = tsConfig.compilerOptions.target as string;
Expand Down Expand Up @@ -499,3 +544,25 @@ export function generateSsrMappings(

return remotes;
}

function downgradeToWebpack(build: any) {

if (!build.options) {
return;
}

if (build.options.browser) {
build.options.main = build.options.browser;
delete build.options.browser;
}

if (!build.options.assets) {
return;
}

for (const asset of build.options.assets) {
if (typeof asset === 'object' && typeof asset.output === 'undefined') {
asset.output = '.';
}
}
}
3 changes: 3 additions & 0 deletions libs/mf/src/schematics/remove/schema.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface RemoveSchema {
project: string;
}
13 changes: 13 additions & 0 deletions libs/mf/src/schematics/remove/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "mf",
"title": "",
"type": "object",
"properties": {
"project": {
"type": "string",
"description": "The project to add module federation",
"x-prompt": "Project name (press enter for default project)"
}
}
}
98 changes: 98 additions & 0 deletions libs/mf/src/schematics/remove/schematic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import path = require('path');
import { noop } from 'rxjs';
import { getWorkspaceFileName } from '../mf/schematic';
import { Rule, Tree } from '@angular-devkit/schematics';
import { RemoveSchema } from './schema';

export default function remove(options: RemoveSchema): Rule {
return async function (tree: Tree) {
const workspaceFileName = getWorkspaceFileName(tree);
const workspace = JSON.parse(tree.read(workspaceFileName).toString('utf8'));
const normalized = normalize(options, workspace);

removeBootstrap(normalized, tree);

updateBuildConfig(normalized);
updateServeConfig(normalized);

tree.overwrite(workspaceFileName, JSON.stringify(workspace, null, 2));

return noop();
};
}

function updateBuildConfig(normalized: { projectConfig: any; projectName: string; }) {
const build = normalized.projectConfig.architect.build;
build.builder = '@angular-devkit/build-angular:browser';
delete build.options.extraWebpackConfig;
const buildProd = build.configurations.production;
delete buildProd.extraWebpackConfig;
}

function updateServeConfig(normalized: { projectConfig: any; projectName: string; }) {
const serve = normalized.projectConfig.architect.serve;
serve.builder = '@angular-devkit/build-angular:dev-server';
delete serve.options.extraWebpackConfig;

const serveProd = serve.configurations.production;
delete serveProd.extraWebpackConfig;

const prodTarget = serveProd.browserTarget;
if (prodTarget) {
delete serveProd.browserTarget;
serveProd.buildTarget = prodTarget;
}

const serveDev = serve.configurations.development;
const devTarget = serveDev.browserTarget;

if (devTarget) {
delete serveDev.browserTarget;
serveDev.buildTarget = devTarget;
}

}

function normalize(options: RemoveSchema, workspace: any) {

if (!options.project) {
options.project = workspace.defaultProject;
}

if (!options.project && Object.keys(workspace.projects).length > 0) {
options.project = Object.keys(workspace.projects)[0];
}

if (!options.project) {
throw new Error(
`No default project found. Please specifiy a project name!`
);
}

const projectName = options.project;
const projectConfig = workspace.projects[projectName];

if (!projectConfig?.architect?.build?.options?.main) {
throw new Error(
`architect.build.options.main not found for project ` + projectName
);
}
return { projectConfig, projectName };
}

function removeBootstrap(normalized, tree) {
const currentMain = normalized.projectConfig.architect.build.options.main;

const mainPath = path
.join(path.dirname(currentMain), 'main.ts')
.replace(/\\/g, '/');

const bootstrapPath = path
.join(path.dirname(currentMain), 'bootstrap.ts')
.replace(/\\/g, '/');

const content = tree.readText(bootstrapPath);
tree.overwrite(mainPath, content);
tree.delete(bootstrapPath);
}

0 comments on commit afa8343

Please sign in to comment.