Skip to content

Commit dd31a44

Browse files
committed
Step 2 - Add button to trigger Vite restart for remoteEntry changes; streamline updates without server restarts.
1 parent 813aa39 commit dd31a44

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

libs/nx-angular-mf/src/builders/custom-loader/custom-loader-serve.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from './custom-loader-utils';
1212

1313
import { Context, DefaultLoad, NextResolve } from './types';
14-
import { CACHE_FILE, IMPORT_MAP } from './constants';
14+
import { CACHE_FILE, CLEAR_REMOTE, IMPORT_MAP } from './constants';
1515
import { join } from 'path';
1616
import { PREF } from './patch-vite-dev-server';
1717
import { OutputFileRecord } from '../types';
@@ -37,6 +37,7 @@ let cacheFiles: Map<string, OutputFileRecord> = new Map<
3737
>();
3838
const packageNameToImportNameMap = new Map<string, string>();
3939

40+
const remotePackages = new Map<string, string>();
4041

4142
async function getImportMap() {
4243
if (importMap) return importMap;
@@ -68,6 +69,9 @@ export async function initialize({ port }: { port: MessagePort }) {
6869
}
6970
cacheFilesDeferred.resolve(event.data.result);
7071
break;
72+
case CLEAR_REMOTE:
73+
remotePackages.clear();
74+
break;
7175
}
7276
};
7377
}
@@ -129,14 +133,22 @@ export async function resolve(
129133
}
130134
}
131135

132-
const specifierUrl = new URL(specifier, fakeRootPath);
133-
134136
const cacheFiles = await getCacheFiles();
137+
135138
const dataFromCache = cacheFiles.get(importMapName);
136139

140+
const specifierUrl = new URL(specifier, fakeRootPath);
137141
if (dataFromCache && dataFromCache.hash) {
138142
specifierUrl.searchParams.set('v', dataFromCache.hash);
139143
}
144+
if (!importMapName && resolveUrl) {
145+
let tmp = remotePackages.get(specifier);
146+
if (!remotePackages.has(specifier)) {
147+
tmp = Date.now().toString();
148+
remotePackages.set(specifier, tmp);
149+
}
150+
specifierUrl.searchParams.set('v', tmp);
151+
}
140152

141153
return {
142154
url: specifierUrl.toString(),

libs/nx-angular-mf/src/builders/helpers/transform-html.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,36 @@ export async function indexHtml(
9999
return serialize(document);
100100
};
101101
}
102+
103+
export function addLinkForReload(input: string) {
104+
const template = `
105+
<div>
106+
<a href="#" id="manualReloadDevServerLink">Manual reload dev server</a>
107+
<style>
108+
#manualReloadDevServerLink {
109+
position:absolute;
110+
top: 0px;
111+
left: 50%;
112+
}
113+
</style>
114+
<script type="module">
115+
import('/@vite/client').then(r => {
116+
document.getElementById('manualReloadDevServerLink').addEventListener('click', (event) => {
117+
event.preventDefault();
118+
event.stopPropagation()
119+
r.createHotContext('/').send('reload:manual');
120+
return false;
121+
});
122+
})
123+
124+
</script>
125+
</div>`;
126+
127+
const linkDiv = parseFragment(template);
128+
129+
const document = parse(input);
130+
const bodyNode = findBody(document);
131+
// @ts-ignore
132+
bodyNode.childNodes.push(...linkDiv.childNodes);
133+
return serialize(document);
134+
}

libs/nx-angular-mf/src/builders/serve/index.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Plugin } from 'esbuild';
1313
import { ServeExecutorSchema } from './schema';
1414
import { BuildExecutorSchema } from '../build/schema';
1515
import {
16+
addLinkForReload,
1617
deepMergeObject,
1718
getMapName,
1819
getPathForRegister,
@@ -27,6 +28,8 @@ import { CACHE_FILE, CLEAR_REMOTE, IMPORT_MAP } from '../custom-loader/constants
2728
import { OutputFileRecord } from '../types';
2829
import process from 'node:process';
2930
import { loadEsmModule } from '../custom-loader/custom-loader-utils';
31+
// @ts-expect-error need only type
32+
import { ViteDevServer } from 'vite';
3033

3134
const { port1, port2 } = new MessageChannel();
3235

@@ -165,7 +168,7 @@ export async function* runBuilder(
165168

166169
const transforms = {
167170
indexHtml: async (input: string) => {
168-
const mainTransformResult = await mainTransform(input);
171+
const mainTransformResult = await mainTransform(addLinkForReload(input));
169172
return optionsMfe.indexHtmlTransformer(mainTransformResult);
170173
},
171174
};
@@ -186,7 +189,7 @@ export async function* runBuilder(
186189
},
187190
});
188191
}
189-
192+
let serverFromPatch: ViteDevServer;
190193
const runServer = serveWithVite(
191194
normalizeOuterOptions,
192195
'@angular-devkit/build-angular:application',
@@ -196,6 +199,22 @@ export async function* runBuilder(
196199
extensions
197200
);
198201
for await (const output of runServer) {
202+
if (targetOptions['ssr'] && !serverFromPatch) {
203+
const serverFromPatch = await loadEsmModule<typeof import('vite')>(
204+
'vite'
205+
).then((r) => r.default['serverFromPatch']);
206+
serverFromPatch.ws.on('reload:manual', async () => {
207+
await reloadDevServer(serverFromPatch);
208+
serverFromPatch.ws.send({
209+
type: 'full-reload',
210+
path: '*',
211+
});
212+
context.logger.info('Page reload sent to client(s).');
213+
port1.postMessage({
214+
kind: CLEAR_REMOTE,
215+
});
216+
});
217+
}
199218
yield output;
200219
}
201220
}

0 commit comments

Comments
 (0)