Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions libs/native-federation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,5 @@
"mrmime": "^1.0.1",
"npmlog": "^6.0.2",
"process": "0.11.10"
},
"peerDependencies": {}
}
}
92 changes: 29 additions & 63 deletions libs/native-federation/src/builders/build/builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import * as path from 'path';
import * as fs from 'fs';
import * as mrmime from 'mrmime';

import {
BuilderContext,
Expand Down Expand Up @@ -37,7 +35,6 @@ import {
startServer,
} from '../../utils/dev-server';
import { RebuildHubs } from '../../utils/rebuild-events';
import { updateIndexHtml, updateScriptTags } from '../../utils/updateIndexHtml';
import { existsSync, mkdirSync, rmSync } from 'fs';
import {
EsBuildResult,
Expand All @@ -46,9 +43,11 @@ import {
} from '../../utils/mem-resuts';
import { JsonObject } from '@angular-devkit/core';
import { createSharedMappingsPlugin } from '../../utils/shared-mappings-plugin';
import { Connect } from 'vite';
import { PluginBuild } from 'esbuild';
import { FederationInfo } from '@softarc/native-federation-runtime';
import { prepareBundles } from '../../utils/prepare-bundles';
import { updateScriptTags } from '../../utils/updateIndexHtml';
import { createI18nOptions } from '@angular-devkit/build-angular/src/utils/i18n-options';
import { getFederationFilesMiddleware } from '../../utils/federation-files-middleware';

export async function* runBuilder(
nfOptions: NfBuilderSchema,
Expand Down Expand Up @@ -103,6 +102,8 @@ export async function* runBuilder(
options = (await context.validateOptions(_options, builder)) as JsonObject &
Schema;
}
const metadata = await context.getProjectMetadata(context.target.project);
const i18nOpts = createI18nOptions(metadata, options.localize);

const runServer = !!nfOptions.port;
const write = !runServer;
Expand All @@ -116,7 +117,7 @@ export async function* runBuilder(

setLogLevel(options.verbose ? 'verbose' : 'info');

const outputPath = path.join(options.outputPath, 'browser');
const outputPath = path.join(options.outputPath as string, 'browser');

const fedOptions: FederationOptions = {
workspaceRoot: context.workspaceRoot,
Expand All @@ -143,32 +144,8 @@ export async function* runBuilder(
},
},
];

const middleware: Connect.NextHandleFunction[] = [
(req, res, next) => {
const fileName = path.join(
fedOptions.workspaceRoot,
fedOptions.outputPath,
req.url
);
const exists = fs.existsSync(fileName);

if (req.url !== '/' && req.url !== '' && exists) {
const lookup = mrmime.lookup;
const mimeType = lookup(path.extname(fileName)) || 'text/javascript';
const rawBody = fs.readFileSync(fileName, 'utf-8');
const body = addDebugInformation(req.url, rawBody);
res.writeHead(200, {
'Content-Type': mimeType,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type',
});
res.end(body);
} else {
next();
}
},
const middleware = [
getFederationFilesMiddleware(fedOptions, i18nOpts, nfOptions.pathMappings),
];

const memResults = new MemResults();
Expand Down Expand Up @@ -204,9 +181,11 @@ export async function* runBuilder(
normOuterOptions,
appBuilderName,
context,
nfOptions.skipHtmlTransform ? {} : {
indexHtml: transformIndexHtml,
},
nfOptions.skipHtmlTransform
? {}
: {
indexHtml: transformIndexHtml,
},
{
buildPlugins: plugins,
middleware,
Expand All @@ -220,8 +199,12 @@ export async function* runBuilder(

if (!output.success) {
setError('Compilation Error');
reloadBrowser();
continue;
if (nfOptions.dev) {
reloadBrowser();
continue;
} else {
yield output;
}
} else {
setError(null);
}
Expand All @@ -236,12 +219,17 @@ export async function* runBuilder(
);
}

if (write && !nfOptions.dev && !nfOptions.skipHtmlTransform) {
updateIndexHtml(fedOptions);
}
prepareBundles(
options,
fedOptions,
i18nOpts,
output,
write && !nfOptions.dev && !nfOptions.skipHtmlTransform,
memResults
);

if (first && runServer) {
startServer(nfOptions, options.outputPath, memResults);
startServer(nfOptions, options.outputPath as string, memResults);
}

if (!first && runServer) {
Expand Down Expand Up @@ -284,25 +272,3 @@ function infereConfigPath(tsConfig: string): string {
function transformIndexHtml(content: string): Promise<string> {
return Promise.resolve(updateScriptTags(content, 'main.js', 'polyfills.js'));
}

function addDebugInformation(fileName: string, rawBody: string): string {
if (fileName !== '/remoteEntry.json') {
return rawBody;
}

const remoteEntry = JSON.parse(rawBody) as FederationInfo;
const shared = remoteEntry.shared;

if (!shared) {
return rawBody;
}

const sharedForVite = shared.map((s) => ({
...s,
packageName: `/@id/${s.packageName}`,
}));

remoteEntry.shared = [...shared, ...sharedForVite];

return JSON.stringify(remoteEntry, null, 2);
}
1 change: 1 addition & 0 deletions libs/native-federation/src/builders/build/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export interface NfBuilderSchema extends JsonObject {
shell: string;
watch: boolean;
skipHtmlTransform: boolean;
pathMappings?: [string, string][];
} // eslint-disable-line
13 changes: 13 additions & 0 deletions libs/native-federation/src/builders/build/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@
"skipHtmlTransform": {
"type": "boolean",
"default": false
},
"pathMappings": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string",
"minItems": 2,
"maxItems": 2
}
},
"description": "In case baseHref doesn't match nicely to the Angular i18n folder structure you can provide a list of tuples that contain Regex string and a replacement string values. These will map the url's path part to physical location relative to the outputPath. First match applies.",
"default": null
}
}
}
15 changes: 11 additions & 4 deletions libs/native-federation/src/schematics/init/schematic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ export default function config(options: MfSchematicSchema): Rule {
version: '^1.5.12',
overwrite: false,
});
addPackageJsonDependency(tree, {
name: '@softarc/native-federation-runtime',
type: NodeDependencyType.Default,
version: '2.0.8',
overwrite: false,
});

context.addTask(new NodePackageInstallTask());

Expand Down Expand Up @@ -278,7 +284,8 @@ function generateRemoteMap(workspace: any, projectName: string) {
project?.architect?.serve &&
project?.architect?.build
) {
const pPort = project.architect['serve-original']?.options?.port ??
const pPort =
project.architect['serve-original']?.options?.port ??
project.architect.serve?.options?.port ??
4200;
result[
Expand Down Expand Up @@ -313,7 +320,7 @@ function makeMainAsync(

let newMainContent = '';
if (options.type === 'dynamic-host') {
newMainContent = `import { initFederation } from '@angular-architects/native-federation';
newMainContent = `import { initFederation } from '@softarc/native-federation-runtime';

initFederation('/assets/federation.manifest.json')
.catch(err => console.error(err))
Expand All @@ -322,15 +329,15 @@ initFederation('/assets/federation.manifest.json')
`;
} else if (options.type === 'host') {
const manifest = JSON.stringify(remoteMap, null, 2).replace(/"/g, "'");
newMainContent = `import { initFederation } from '@angular-architects/native-federation';
newMainContent = `import { initFederation } from '@softarc/native-federation-runtime';

initFederation(${manifest})
.catch(err => console.error(err))
.then(_ => import('./bootstrap'))
.catch(err => console.error(err));
`;
} else {
newMainContent = `import { initFederation } from '@angular-architects/native-federation';
newMainContent = `import { initFederation } from '@softarc/native-federation-runtime';

initFederation()
.catch(err => console.error(err))
Expand Down
Loading