@nf-beta/angular 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builders.json +10 -0
- package/collection.json +27 -0
- package/generators.json +12 -0
- package/migration-collection.json +13 -0
- package/package.json +29 -5
- package/src/builders/build/builder.d.ts +6 -0
- package/src/builders/build/builder.d.ts.map +1 -0
- package/src/builders/build/builder.js +348 -0
- package/src/builders/build/federation-build-notifier.d.ts +70 -0
- package/src/builders/build/federation-build-notifier.d.ts.map +1 -0
- package/src/builders/build/federation-build-notifier.js +186 -0
- package/src/builders/build/schema.d.ts +21 -0
- package/src/builders/build/schema.json +84 -0
- package/src/config.d.ts +3 -0
- package/src/config.d.ts.map +1 -0
- package/src/config.js +2 -0
- package/src/generators/native-federation/files/src/index.ts__template__ +1 -0
- package/src/generators/native-federation/generator.d.ts +4 -0
- package/src/generators/native-federation/generator.d.ts.map +1 -0
- package/src/generators/native-federation/generator.js +43 -0
- package/src/generators/native-federation/schema.d.ts +5 -0
- package/src/generators/native-federation/schema.json +29 -0
- package/src/index.d.ts +2 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +1 -0
- package/src/patch-angular-build.d.ts +2 -0
- package/src/patch-angular-build.d.ts.map +1 -0
- package/src/patch-angular-build.js +5 -0
- package/src/plugin/dev-externals-mixin.d.ts +3 -0
- package/src/plugin/dev-externals-mixin.d.ts.map +1 -0
- package/src/plugin/dev-externals-mixin.js +29 -0
- package/src/plugin/externals-skip-list.d.ts +3 -0
- package/src/plugin/externals-skip-list.d.ts.map +1 -0
- package/src/plugin/externals-skip-list.js +4 -0
- package/src/plugin/index.d.ts +4 -0
- package/src/plugin/index.d.ts.map +1 -0
- package/src/plugin/index.js +75 -0
- package/src/schematics/appbuilder/schema.d.ts +3 -0
- package/src/schematics/appbuilder/schema.json +17 -0
- package/src/schematics/appbuilder/schematic.d.ts +5 -0
- package/src/schematics/appbuilder/schematic.d.ts.map +1 -0
- package/src/schematics/appbuilder/schematic.js +83 -0
- package/src/schematics/init/files/federation.config.js__tmpl__ +33 -0
- package/src/schematics/init/schema.d.ts +6 -0
- package/src/schematics/init/schema.json +34 -0
- package/src/schematics/init/schematic.d.ts +7 -0
- package/src/schematics/init/schematic.d.ts.map +1 -0
- package/src/schematics/init/schematic.js +422 -0
- package/src/schematics/remove/schema.d.ts +3 -0
- package/src/schematics/remove/schema.json +17 -0
- package/src/schematics/remove/schematic.d.ts +5 -0
- package/src/schematics/remove/schematic.d.ts.map +1 -0
- package/src/schematics/remove/schematic.js +109 -0
- package/src/schematics/update18/schema.json +7 -0
- package/src/schematics/update18/schematic.d.ts +3 -0
- package/src/schematics/update18/schematic.d.ts.map +1 -0
- package/src/schematics/update18/schematic.js +7 -0
- package/src/tools/fstart-as-data-url.d.ts +2 -0
- package/src/tools/fstart-as-data-url.d.ts.map +1 -0
- package/src/tools/fstart-as-data-url.js +1 -0
- package/src/utils/angular-esbuild-adapter.d.ts +10 -0
- package/src/utils/angular-esbuild-adapter.d.ts.map +1 -0
- package/src/utils/angular-esbuild-adapter.js +289 -0
- package/src/utils/angular-locales.d.ts +19 -0
- package/src/utils/angular-locales.d.ts.map +1 -0
- package/src/utils/angular-locales.js +18 -0
- package/src/utils/create-awaitable-compiler-plugin.d.ts +6 -0
- package/src/utils/create-awaitable-compiler-plugin.d.ts.map +1 -0
- package/src/utils/create-awaitable-compiler-plugin.js +29 -0
- package/src/utils/create-compiler-options.d.ts +5 -0
- package/src/utils/create-compiler-options.d.ts.map +1 -0
- package/src/utils/create-compiler-options.js +42 -0
- package/src/utils/event-source.d.ts +10 -0
- package/src/utils/event-source.d.ts.map +1 -0
- package/src/utils/event-source.js +10 -0
- package/src/utils/i18n.d.ts +23 -0
- package/src/utils/i18n.d.ts.map +1 -0
- package/src/utils/i18n.js +61 -0
- package/src/utils/mem-resuts.d.ts +29 -0
- package/src/utils/mem-resuts.d.ts.map +1 -0
- package/src/utils/mem-resuts.js +50 -0
- package/src/utils/patch-angular-build.d.ts +4 -0
- package/src/utils/patch-angular-build.d.ts.map +1 -0
- package/src/utils/patch-angular-build.js +29 -0
- package/src/utils/rebuild-events.d.ts +8 -0
- package/src/utils/rebuild-events.d.ts.map +1 -0
- package/src/utils/rebuild-events.js +4 -0
- package/src/utils/shared-mappings-plugin.d.ts +4 -0
- package/src/utils/shared-mappings-plugin.d.ts.map +1 -0
- package/src/utils/shared-mappings-plugin.js +28 -0
- package/src/utils/updateIndexHtml.d.ts +5 -0
- package/src/utils/updateIndexHtml.d.ts.map +1 -0
- package/src/utils/updateIndexHtml.js +34 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { BuildNotificationType } from '@nf-beta/runtime';
|
|
2
|
+
import { logger } from '@nf-beta/core/build';
|
|
3
|
+
/**
|
|
4
|
+
* Manages Server-Sent Events for federation hot reload in local development
|
|
5
|
+
* Only active when running in development mode with dev server
|
|
6
|
+
*/
|
|
7
|
+
export class FederationBuildNotifier {
|
|
8
|
+
connections = [];
|
|
9
|
+
cleanupInterval = null;
|
|
10
|
+
isActive = false;
|
|
11
|
+
endpoint;
|
|
12
|
+
/**
|
|
13
|
+
* Initializes the SSE reloader for local development
|
|
14
|
+
*/
|
|
15
|
+
initialize(endpoint) {
|
|
16
|
+
if (this.isActive) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this.endpoint = endpoint;
|
|
20
|
+
this.isActive = true;
|
|
21
|
+
this.startCleanup();
|
|
22
|
+
logger.info(`[Federation SSE] Local reloader initialized with endpoint ${this.endpoint}`);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates SSE middleware for federation events
|
|
26
|
+
*/
|
|
27
|
+
createEventMiddleware(removeBaseHref) {
|
|
28
|
+
if (!this.isActive) {
|
|
29
|
+
return (_req, _res, next) => next();
|
|
30
|
+
}
|
|
31
|
+
return (req, res, next) => {
|
|
32
|
+
const url = removeBaseHref(req);
|
|
33
|
+
if (url !== this.endpoint) {
|
|
34
|
+
return next();
|
|
35
|
+
}
|
|
36
|
+
this._setupSSEConnection(req, res);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sets up a new SSE connection
|
|
41
|
+
*/
|
|
42
|
+
_setupSSEConnection(req, res) {
|
|
43
|
+
res.writeHead(200, {
|
|
44
|
+
'Content-Type': 'text/event-stream',
|
|
45
|
+
'Cache-Control': 'no-cache',
|
|
46
|
+
Connection: 'keep-alive',
|
|
47
|
+
'Access-Control-Allow-Origin': '*',
|
|
48
|
+
'Access-Control-Allow-Headers': 'Cache-Control',
|
|
49
|
+
});
|
|
50
|
+
// Send initial connection event
|
|
51
|
+
this._sendEvent(res, {
|
|
52
|
+
type: 'connected',
|
|
53
|
+
timestamp: Date.now(),
|
|
54
|
+
});
|
|
55
|
+
// Store connection
|
|
56
|
+
const connection = { response: res, request: req };
|
|
57
|
+
this.connections.push(connection);
|
|
58
|
+
// Handle disconnection
|
|
59
|
+
req.on('close', () => this._removeConnection(connection));
|
|
60
|
+
req.on('error', () => this._removeConnection(connection));
|
|
61
|
+
logger.info(`[Federation SSE] Client connected. Active connections: ${this.connections.length}`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Removes a connection from the pool
|
|
65
|
+
*/
|
|
66
|
+
_removeConnection(connection) {
|
|
67
|
+
const index = this.connections.indexOf(connection);
|
|
68
|
+
if (index !== -1) {
|
|
69
|
+
this.connections.splice(index, 1);
|
|
70
|
+
logger.info(`[Federation SSE] Client disconnected. Active connections: ${this.connections.length}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Broadcasts an event to all connected clients
|
|
75
|
+
* Only works in local development mode
|
|
76
|
+
*/
|
|
77
|
+
_broadcastEvent(event) {
|
|
78
|
+
if (!this.isActive || this.connections.length === 0) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const deadConnections = [];
|
|
82
|
+
this.connections.forEach(connection => {
|
|
83
|
+
try {
|
|
84
|
+
this._sendEvent(connection.response, event);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
deadConnections.push(connection);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// Remove dead connections
|
|
91
|
+
deadConnections.forEach(connection => this._removeConnection(connection));
|
|
92
|
+
if (this.connections.length > 0) {
|
|
93
|
+
logger.info(`[Federation SSE] Event '${event.type}' broadcast to ${this.connections.length} clients`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Sends an event to a specific response stream
|
|
98
|
+
*/
|
|
99
|
+
_sendEvent(res, event) {
|
|
100
|
+
const data = JSON.stringify(event);
|
|
101
|
+
res.write(`data: ${data}\n\n`);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Starts periodic cleanup of dead connections
|
|
105
|
+
*/
|
|
106
|
+
startCleanup() {
|
|
107
|
+
if (this.cleanupInterval) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.cleanupInterval = setInterval(() => {
|
|
111
|
+
const aliveBefore = this.connections.length;
|
|
112
|
+
this.connections = this.connections.filter(connection => !connection.response.destroyed &&
|
|
113
|
+
!connection.request.destroyed &&
|
|
114
|
+
connection.response.writable);
|
|
115
|
+
if (this.connections.length !== aliveBefore) {
|
|
116
|
+
logger.info(`[Federation SSE] Cleaned up ${aliveBefore - this.connections.length} dead connections`);
|
|
117
|
+
}
|
|
118
|
+
}, 30000); // Clean every 30 seconds
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Notifies about successful federation rebuild
|
|
122
|
+
*/
|
|
123
|
+
broadcastBuildCompletion() {
|
|
124
|
+
this._broadcastEvent({
|
|
125
|
+
type: BuildNotificationType.COMPLETED,
|
|
126
|
+
timestamp: Date.now(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Notifies about cancellation of a federation rebuild
|
|
131
|
+
*/
|
|
132
|
+
broadcastBuildCancellation() {
|
|
133
|
+
this._broadcastEvent({
|
|
134
|
+
type: BuildNotificationType.CANCELLED,
|
|
135
|
+
timestamp: Date.now(),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Notifies about failed federation rebuild
|
|
140
|
+
*/
|
|
141
|
+
broadcastBuildError(error) {
|
|
142
|
+
this._broadcastEvent({
|
|
143
|
+
type: BuildNotificationType.ERROR,
|
|
144
|
+
timestamp: Date.now(),
|
|
145
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Stops cleanup and closes all connections
|
|
150
|
+
* Should be called when development server stops
|
|
151
|
+
*/
|
|
152
|
+
stopEventServer() {
|
|
153
|
+
if (!this.isActive) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (this.cleanupInterval) {
|
|
157
|
+
clearInterval(this.cleanupInterval);
|
|
158
|
+
this.cleanupInterval = null;
|
|
159
|
+
}
|
|
160
|
+
this.connections.forEach(connection => {
|
|
161
|
+
try {
|
|
162
|
+
connection.response.end();
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Connection might already be closed
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
this.connections = [];
|
|
169
|
+
this.isActive = false;
|
|
170
|
+
logger.info('[Federation SSE] Local reloader disposed');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Returns the number of active connections
|
|
174
|
+
*/
|
|
175
|
+
get activeConnections() {
|
|
176
|
+
return this.connections.length;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Returns whether the reloader is active
|
|
180
|
+
*/
|
|
181
|
+
get isRunning() {
|
|
182
|
+
return this.isActive;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Singleton instance for local development
|
|
186
|
+
export const federationBuildNotifier = new FederationBuildNotifier();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { JsonObject } from '@angular-devkit/core';
|
|
2
|
+
import type { BuildNotificationOptions } from '@nf-beta/runtime';
|
|
3
|
+
import type { ESMSInitOptions } from 'es-module-shims';
|
|
4
|
+
|
|
5
|
+
export interface NfBuilderSchema extends JsonObject {
|
|
6
|
+
target: string;
|
|
7
|
+
dev: boolean;
|
|
8
|
+
port: number;
|
|
9
|
+
open: boolean;
|
|
10
|
+
rebuildDelay: number;
|
|
11
|
+
buildNotifications?: BuildNotificationOptions;
|
|
12
|
+
shell: string;
|
|
13
|
+
watch: boolean;
|
|
14
|
+
skipHtmlTransform: boolean;
|
|
15
|
+
esmsInitOptions: ESMSInitOptions;
|
|
16
|
+
baseHref?: string;
|
|
17
|
+
outputPath?: string;
|
|
18
|
+
ssr: boolean;
|
|
19
|
+
devServer?: boolean;
|
|
20
|
+
cacheExternalArtifacts?: boolean;
|
|
21
|
+
} // eslint-disable-line
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"outputCapture": "direct-nodejs",
|
|
4
|
+
"$schema": "http://json-schema.org/draft-07/schema",
|
|
5
|
+
"title": "native federation browser builder",
|
|
6
|
+
"description": "builder for native federation browser apps",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"target": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "target configured for the esbuild builder"
|
|
12
|
+
},
|
|
13
|
+
"dev": {
|
|
14
|
+
"type": "boolean",
|
|
15
|
+
"description": "Set this to true to start the builder in dev mode",
|
|
16
|
+
"default": false
|
|
17
|
+
},
|
|
18
|
+
"watch": {
|
|
19
|
+
"type": "boolean",
|
|
20
|
+
"default": false
|
|
21
|
+
},
|
|
22
|
+
"port": {
|
|
23
|
+
"type": "number",
|
|
24
|
+
"default": 0
|
|
25
|
+
},
|
|
26
|
+
"open": {
|
|
27
|
+
"type": "boolean",
|
|
28
|
+
"default": true,
|
|
29
|
+
"description": "Open browser?",
|
|
30
|
+
"alias": "o"
|
|
31
|
+
},
|
|
32
|
+
"rebuildDelay": {
|
|
33
|
+
"type": "number",
|
|
34
|
+
"default": 2000,
|
|
35
|
+
"description": "The delay for rebuilding federation artefacts. This allows to have more resources for refreshing your micro frontend in the browser."
|
|
36
|
+
},
|
|
37
|
+
"shell": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"description": "Experimental",
|
|
40
|
+
"default": ""
|
|
41
|
+
},
|
|
42
|
+
"skipHtmlTransform": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"default": false
|
|
45
|
+
},
|
|
46
|
+
"baseHref": {
|
|
47
|
+
"type": "string"
|
|
48
|
+
},
|
|
49
|
+
"outputPath": {
|
|
50
|
+
"type": "string"
|
|
51
|
+
},
|
|
52
|
+
"esmsInitOptions": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"description": "Options for esms-module-shims https://github.com/guybedford/es-module-shims?tab=readme-ov-file#init-options",
|
|
55
|
+
"default": {
|
|
56
|
+
"shimMode": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"ssr": {
|
|
60
|
+
"type": "boolean",
|
|
61
|
+
"description": "uses federation for ssr in ApplicationBuilder too",
|
|
62
|
+
"default": false
|
|
63
|
+
},
|
|
64
|
+
"devServer": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"description": "can be used to disable the dev server when dev=true"
|
|
67
|
+
},
|
|
68
|
+
"buildNotifications": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"enable": {
|
|
72
|
+
"type": "boolean",
|
|
73
|
+
"default": true,
|
|
74
|
+
"description": "Enable build completion notifications for local development. It will send events to notify when the federation build is complete."
|
|
75
|
+
},
|
|
76
|
+
"endpoint": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"default": "/@angular-architects/native-federation:build-notifications",
|
|
79
|
+
"description": "You can override the default endpoint to send build completion events to."
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/src/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,EACL,QAAQ,EACR,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/src/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const variable = "<%= projectName %>";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../../src/generators/native-federation/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAqCnE,yBAA+B,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,iBAelF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { addProjectConfiguration, formatFiles, generateFiles, getWorkspaceLayout, names, offsetFromRoot, } from '@nx/devkit';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
function normalizeOptions(tree, options) {
|
|
4
|
+
const name = names(options.name).fileName;
|
|
5
|
+
const projectDirectory = options.directory
|
|
6
|
+
? `${names(options.directory).fileName}/${name}`
|
|
7
|
+
: name;
|
|
8
|
+
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
|
|
9
|
+
const projectRoot = `${getWorkspaceLayout(tree).libsDir}/${projectDirectory}`;
|
|
10
|
+
const parsedTags = options.tags ? options.tags.split(',').map(s => s.trim()) : [];
|
|
11
|
+
return {
|
|
12
|
+
...options,
|
|
13
|
+
projectName,
|
|
14
|
+
projectRoot,
|
|
15
|
+
projectDirectory,
|
|
16
|
+
parsedTags,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function addFiles(tree, options) {
|
|
20
|
+
const templateOptions = {
|
|
21
|
+
...options,
|
|
22
|
+
...names(options.name),
|
|
23
|
+
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
|
24
|
+
template: '',
|
|
25
|
+
};
|
|
26
|
+
generateFiles(tree, path.join(__dirname, 'files'), options.projectRoot, templateOptions);
|
|
27
|
+
}
|
|
28
|
+
export default async function (tree, options) {
|
|
29
|
+
const normalizedOptions = normalizeOptions(tree, options);
|
|
30
|
+
addProjectConfiguration(tree, normalizedOptions.projectName, {
|
|
31
|
+
root: normalizedOptions.projectRoot,
|
|
32
|
+
projectType: 'library',
|
|
33
|
+
sourceRoot: `${normalizedOptions.projectRoot}/src`,
|
|
34
|
+
targets: {
|
|
35
|
+
build: {
|
|
36
|
+
executor: '@angular-architects/native-federation:build',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
tags: normalizedOptions.parsedTags,
|
|
40
|
+
});
|
|
41
|
+
addFiles(tree, normalizedOptions);
|
|
42
|
+
await formatFiles(tree);
|
|
43
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "NativeFederation",
|
|
5
|
+
"title": "",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
},
|
|
15
|
+
"x-prompt": "What name would you like to use?"
|
|
16
|
+
},
|
|
17
|
+
"tags": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Add tags to the project (used for linting)",
|
|
20
|
+
"alias": "t"
|
|
21
|
+
},
|
|
22
|
+
"directory": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "A directory where the project is placed",
|
|
25
|
+
"alias": "d"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": ["name"]
|
|
29
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
package/src/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@nf-beta/runtime';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-angular-build.d.ts","sourceRoot":"","sources":["../../src/patch-angular-build.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// import { patchAngularBuild } from './utils/patch-angular-build';
|
|
2
|
+
// const workspaceRoot = process.cwd();
|
|
3
|
+
// patchAngularBuild(workspaceRoot);
|
|
4
|
+
console.log('Please remove the postbuild task calling patch-angular-build. This is not needed since Native Federation 18.1 anymore!');
|
|
5
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-externals-mixin.d.ts","sourceRoot":"","sources":["../../../src/plugin/dev-externals-mixin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA8B,MAAM,MAAM,CAAC;AAM/D,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,MAAM,CA0B7C,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { federationBuilder } from '@nf-beta/core/build';
|
|
2
|
+
import { filterExternals } from './externals-skip-list.js';
|
|
3
|
+
// see: https://github.com/vitejs/vite/issues/6393#issuecomment-1006819717
|
|
4
|
+
export const devExternalsMixin = {
|
|
5
|
+
enforce: 'pre',
|
|
6
|
+
config(config) {
|
|
7
|
+
config.optimizeDeps = {
|
|
8
|
+
...(config.optimizeDeps ?? {}),
|
|
9
|
+
exclude: [
|
|
10
|
+
...(config.optimizeDeps?.exclude ?? []),
|
|
11
|
+
...filterExternals(federationBuilder.externals),
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
configResolved(resolvedConfig) {
|
|
16
|
+
const VALID_ID_PREFIX = `/@id/`;
|
|
17
|
+
const reg = new RegExp(`${VALID_ID_PREFIX}(${federationBuilder.externals.join('|')})`, 'g');
|
|
18
|
+
resolvedConfig.plugins.push({
|
|
19
|
+
name: 'vite-plugin-ignore-static-import-replace-idprefix',
|
|
20
|
+
transform: (code) => reg.test(code) ? code.replace(reg, (_m, s1) => s1) : code,
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
resolveId(id) {
|
|
24
|
+
if (filterExternals(federationBuilder.externals).includes(id)) {
|
|
25
|
+
return { id, external: true };
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externals-skip-list.d.ts","sourceRoot":"","sources":["../../../src/plugin/externals-skip-list.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,aAAqB,CAAC;AAEpD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAExD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugin/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAoD,MAAM,MAAM,CAAC;AAIrF,OAAO,EAAE,KAAK,iBAAiB,EAAqB,MAAM,qBAAqB,CAAC;AAKhF,eAAO,MAAM,UAAU,GAAI,QAAQ,iBAAiB,KAAG,MAoCtD,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { lookup } from 'mrmime';
|
|
4
|
+
import { devExternalsMixin } from './dev-externals-mixin.js';
|
|
5
|
+
import { filterExternals } from './externals-skip-list.js';
|
|
6
|
+
import { federationBuilder } from '@nf-beta/core/build';
|
|
7
|
+
export const federation = (params) => {
|
|
8
|
+
return {
|
|
9
|
+
...devExternalsMixin,
|
|
10
|
+
name: '@module-federation/vite', // required, will show up in warnings and errors
|
|
11
|
+
async config(config, env) {
|
|
12
|
+
await federationBuilder.init(params);
|
|
13
|
+
if (typeof devExternalsMixin.config === 'function') {
|
|
14
|
+
devExternalsMixin.config.call(this, config, env);
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
options(o) {
|
|
18
|
+
o['external'] = filterExternals(federationBuilder.externals);
|
|
19
|
+
},
|
|
20
|
+
async closeBundle() {
|
|
21
|
+
await federationBuilder.build();
|
|
22
|
+
},
|
|
23
|
+
async configureServer(server) {
|
|
24
|
+
const fedInfoRef = {
|
|
25
|
+
federationInfo: federationBuilder.federationInfo,
|
|
26
|
+
};
|
|
27
|
+
await configureDevServer(server, params, fedInfoRef);
|
|
28
|
+
},
|
|
29
|
+
transformIndexHtml(html) {
|
|
30
|
+
const fragment = '<script src="polyfills.js" type="module-shim">';
|
|
31
|
+
const updated = `
|
|
32
|
+
<script type="esms-options">
|
|
33
|
+
{
|
|
34
|
+
"shimMode": true
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
<script src="polyfills.js" type="module">
|
|
38
|
+
`;
|
|
39
|
+
html = html.replace(/type="module"/g, 'type="module-shim"');
|
|
40
|
+
return html.replace(fragment, updated);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
const configureDevServer = async (server, params, fedInfo) => {
|
|
45
|
+
await federationBuilder.build();
|
|
46
|
+
const op = params.options;
|
|
47
|
+
const dist = path.join(op.workspaceRoot, op.outputPath);
|
|
48
|
+
server.middlewares.use(serveFromDist(dist, fedInfo));
|
|
49
|
+
};
|
|
50
|
+
const serveFromDist = (dist, fedInfoRef) => {
|
|
51
|
+
const fedFiles = new Set([
|
|
52
|
+
...fedInfoRef.federationInfo.shared.map(s => path.join('/', s.outFileName)),
|
|
53
|
+
...fedInfoRef.federationInfo.exposes.map(e => path.join('/', e.outFileName)),
|
|
54
|
+
'/remoteEntry.json',
|
|
55
|
+
]);
|
|
56
|
+
return (req, res, next) => {
|
|
57
|
+
if (!req.url || req.url.endsWith('/index.html') || !fedFiles.has(req.url)) {
|
|
58
|
+
next();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const file = path.join(dist, req.url);
|
|
62
|
+
if (fs.existsSync(file) && fs.lstatSync(file).isFile()) {
|
|
63
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
64
|
+
const type = lookup(req.url) || '';
|
|
65
|
+
res.setHeader('Content-Type', type);
|
|
66
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
67
|
+
// const modified = enhanceFile(file, content);
|
|
68
|
+
const modified = content;
|
|
69
|
+
res.write(modified);
|
|
70
|
+
res.end();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
next();
|
|
74
|
+
};
|
|
75
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "mf",
|
|
4
|
+
"title": "",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"project": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The project to add module federation",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "argv",
|
|
12
|
+
"index": 0
|
|
13
|
+
},
|
|
14
|
+
"x-prompt": "Project name (press enter for default project)"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Rule, Tree } from '@angular-devkit/schematics';
|
|
2
|
+
import type { MfSchematicSchema } from './schema.js';
|
|
3
|
+
export default function remove(options: MfSchematicSchema): Rule;
|
|
4
|
+
export declare function getWorkspaceFileName(tree: Tree): string;
|
|
5
|
+
//# sourceMappingURL=schematic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schematic.d.ts","sourceRoot":"","sources":["../../../../src/schematics/appbuilder/schematic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAcrD,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAS/D;AA0FD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAUvD"}
|