Skip to content

Commit 77669c3

Browse files
committed
feat(nf): provide middleware for dev server to read federation artifacts from disk
1 parent d21e1c6 commit 77669c3

File tree

1 file changed

+56
-14
lines changed
  • libs/native-federation/src/builders/build

1 file changed

+56
-14
lines changed

libs/native-federation/src/builders/build/builder.ts

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import { DevServerBuilderOptions } from '@angular-devkit/build-angular/src/build
1616
import { normalizeOptions } from '@angular-devkit/build-angular/src/builders/dev-server/options';
1717

1818
import * as path from 'path';
19+
import * as fs from 'fs';
20+
21+
import * as mrmime from 'mrmime';
22+
1923
import { setLogLevel, logger } from '@softarc/native-federation/build';
2024

2125
import { FederationOptions } from '@softarc/native-federation/build';
@@ -37,7 +41,7 @@ import {
3741
startServer,
3842
} from '../../utils/dev-server';
3943
import { RebuildHubs } from '../../utils/rebuild-events';
40-
import { updateIndexHtml } from '../../utils/updateIndexHtml';
44+
import { updateIndexHtml, updateScriptTags } from '../../utils/updateIndexHtml';
4145
import { existsSync, mkdirSync, rmSync } from 'fs';
4246
import {
4347
EsBuildResult,
@@ -46,12 +50,12 @@ import {
4650
} from '../../utils/mem-resuts';
4751
import { JsonObject } from '@angular-devkit/core';
4852
import { createSharedMappingsPlugin } from '../../utils/shared-mappings-plugin';
53+
import { Connect } from 'vite';
4954

5055
export async function* runBuilder(
5156
nfOptions: NfBuilderSchema,
5257
context: BuilderContext
5358
): AsyncIterable<BuilderOutput> {
54-
5559
let target = targetFromTargetString(nfOptions.target);
5660
let _options = (await context.getTargetOptions(
5761
target
@@ -64,19 +68,19 @@ export async function* runBuilder(
6468
)) as JsonObject & Schema;
6569

6670
const outerOptions = options as DevServerBuilderOptions;
67-
const normOuterOptions = nfOptions.dev ? await normalizeOptions(context, context.target.project, outerOptions) : null;
71+
const normOuterOptions = nfOptions.dev
72+
? await normalizeOptions(context, context.target.project, outerOptions)
73+
: null;
6874

6975
if (nfOptions.dev) {
7076
target = targetFromTargetString(outerOptions.buildTarget);
7177
_options = (await context.getTargetOptions(
7278
target
7379
)) as unknown as JsonObject & Schema;
74-
80+
7581
builder = await context.getBuilderNameForTarget(target);
76-
options = (await context.validateOptions(
77-
_options,
78-
builder
79-
)) as JsonObject & Schema;
82+
options = (await context.validateOptions(_options, builder)) as JsonObject &
83+
Schema;
8084
}
8185

8286
const runServer = !!nfOptions.port;
@@ -90,7 +94,7 @@ export async function* runBuilder(
9094
setBuildAdapter(adapter);
9195

9296
setLogLevel(options.verbose ? 'verbose' : 'info');
93-
97+
9498
const outputPath = path.join(options.outputPath, 'browser');
9599

96100
const fedOptions: FederationOptions = {
@@ -112,9 +116,38 @@ export async function* runBuilder(
112116
{
113117
name: 'externals',
114118
setup(build) {
119+
console.log('setup::')
115120
build.initialOptions.external = externals.filter((e) => e !== 'tslib');
116121
},
117122
},
123+
// {
124+
// name: 'resolveId',
125+
// setup(build: PluginBuild) {
126+
// build.
127+
// console.log('resolveId', source, importer, options);
128+
// }
129+
// }
130+
];
131+
132+
const middleware: Connect.NextHandleFunction[] = [
133+
(req, res, next) => {
134+
const fileName = path.join(fedOptions.workspaceRoot, fedOptions.outputPath, req.url);
135+
const exists = fs.existsSync(fileName);
136+
137+
if (req.url !== '/' && req.url !== '' && exists) {
138+
console.log('loading from disk', req.url)
139+
const lookup = mrmime.lookup;
140+
const mimeType = lookup(path.extname(fileName)) || 'text/javascript';
141+
const body = fs.readFileSync(fileName)
142+
res.writeHead(200, {
143+
'Content-Type': mimeType,
144+
});
145+
res.end(body);
146+
}
147+
else {
148+
next();
149+
}
150+
}
118151
];
119152

120153
// for await (const r of buildEsbuildBrowser(options, context as any, { write: false })) {
@@ -169,10 +202,15 @@ export async function* runBuilder(
169202

170203
const appBuilderName = '@angular-devkit/build-angular:application';
171204

172-
const builderRun = nfOptions.dev ?
173-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
174-
serveWithVite(normOuterOptions, appBuilderName, context, undefined, { buildPlugins: plugins }) :
175-
buildApplication(options, context, plugins);
205+
const builderRun = nfOptions.dev
206+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
207+
serveWithVite(normOuterOptions, appBuilderName, context, {
208+
indexHtml: transformIndexHtml
209+
}, {
210+
buildPlugins: plugins,
211+
middleware
212+
})
213+
: buildApplication(options, context, plugins);
176214

177215
// builderRun.output.subscribe(async (output) => {
178216
for await (const output of builderRun) {
@@ -196,7 +234,7 @@ export async function* runBuilder(
196234
);
197235
}
198236

199-
if (write) {
237+
if (write && !nfOptions.dev) {
200238
updateIndexHtml(fedOptions);
201239
}
202240

@@ -241,3 +279,7 @@ function infereConfigPath(tsConfig: string): string {
241279

242280
return relConfigPath;
243281
}
282+
283+
function transformIndexHtml(content: string): Promise<string> {
284+
return Promise.resolve(updateScriptTags(content, 'main.js', 'polyfills.js'));
285+
}

0 commit comments

Comments
 (0)