1
1
import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-path' ;
2
-
3
2
const { RuntimeGlobals, RuntimeModule, Template, javascript } = require (
4
3
normalizeWebpackPath ( 'webpack' ) ,
5
4
) as typeof import ( 'webpack' ) ;
@@ -34,15 +33,7 @@ class AutoPublicPathRuntimeModule extends RuntimeModule {
34
33
compilation ?. getPath ( publicPath || '' , {
35
34
hash : compilation ?. hash || 'XXXX' ,
36
35
} ) ;
37
- // If publicPath is not "auto", return the static value
38
- // if (publicPath !== 'auto') {
39
- // const path = getPath();
40
- // return Template.asString([
41
- // `${RuntimeGlobals.publicPath} = ${JSON.stringify(path)};`,
42
- // 'var addProtocol = (url)=> url.startsWith(\'//\') ? \'https:\' + url : url;',
43
- // `globalThis.currentVmokPublicPath = addProtocol(${RuntimeGlobals.publicPath}) || '/';`,
44
- // ]);
45
- // }
36
+
46
37
const chunkName = compilation ?. getPath (
47
38
javascript . JavascriptModulesPlugin . getChunkFilenameTemplate (
48
39
this . chunk ,
@@ -53,138 +44,116 @@ class AutoPublicPathRuntimeModule extends RuntimeModule {
53
44
contentHashType : 'javascript' ,
54
45
} ,
55
46
) ;
56
- let undoPath ;
47
+
48
+ let undoPath : string | null = null ;
57
49
if ( chunkName && path ) {
58
50
undoPath = getUndoPath ( chunkName , path , false ) ;
59
51
}
60
- const ident = Template . toIdentifier ( uniqueName || '' ) ;
61
-
62
- // Define potential lookup keys
63
- const potentialLookups = [ this . chunk ?. name , ident , uniqueName ] ;
64
-
65
- // Generate lookup string using potential keys
66
- const lookupString = potentialLookups
67
- . filter ( Boolean )
68
- . map ( ( lookup ) => {
69
- return `remoteReg[${ JSON . stringify ( lookup ) } ]` ;
70
- } )
71
- . join ( ' || ' ) ;
72
-
73
- const remotesFromFederation = Template . indent ( [
74
- 'var result = {};' ,
75
- '// Assuming the federationController is already defined on globalThis' ,
76
- 'const federationController = globalThis.__FEDERATION__;' ,
77
- '// Function to convert Map to Object' ,
78
- 'function mapToObject(map) {' ,
79
- Template . indent ( [
80
- 'const obj = {};' ,
81
- 'map.forEach((value, key) => {' ,
82
- Template . indent ( 'obj[key] = value;' ) ,
83
- '});' ,
84
- 'return obj;' ,
85
- ] ) ,
86
- '}' ,
87
- "console.log('instance', __webpack_require__.federation.instance.name);" ,
88
- '// Iterate over each instance in federationController' ,
89
- 'federationController.__INSTANCES__.forEach(instance => {' ,
90
- Template . indent ( [
91
- "// Check if the current instance has a moduleCache and it's a Map" ,
92
- 'if (instance.moduleCache) {' ,
93
- Template . indent ( [
94
- '// Convert Map keys and values to an object and merge it with the result' ,
95
- 'result = {...result, ...mapToObject(instance.moduleCache)};' ,
96
- ] ) ,
97
- '}' ,
98
- ] ) ,
99
- '});' ,
100
- "console.log('RESULTS', result);" ,
101
- '// Logic to determine the value of p, using result' ,
102
- `if(!result[${ JSON . stringify ( lookupString ) } ]) return false` ,
103
- `return result[${ JSON . stringify ( lookupString ) } ]` ,
104
- ] ) ;
105
-
106
- const importMetaLookup = Template . indent ( [
107
- `scriptUrl = new Function('return typeof ${ importMetaName } .url === "string" ? ${ importMetaName } .url : undefined;')();` ,
108
- ] ) ;
109
- const federationLookup = Template . asString ( [
110
- 'Object.defineProperty(__webpack_require__, "p", {' ,
111
- Template . indent ( [
112
- 'get: function() {' ,
113
- Template . indent ( [
114
- 'try {' ,
115
- importMetaLookup ,
116
- '} catch(e) {' ,
117
- remotesFromFederation ,
118
- '}' ,
119
- ] ) ,
120
- '}' ,
121
- ] ) ,
122
- '});' ,
123
- ] ) ;
124
-
125
- return Template . asString ( [
126
- 'var scriptUrl;' ,
127
- // its an esproxy so nesting into _config directly is not possible
128
- `
129
- let remoteContainerRegistry = {
130
- get url() {
131
- var remoteReg = globalThis.__remote_scope__ ? globalThis.__remote_scope__._config : {};
132
- return ${ lookupString }
52
+
53
+ const getPathFromFederation = `
54
+ function getPathFromFederation() {
55
+ // Access the global federation manager or create a fallback object
56
+ var federationManager = globalThis.__FEDERATION__ || {};
57
+ // Access the current Webpack instance's federation details or create a fallback object
58
+ var instance = __webpack_require__.federation.instance || {};
59
+
60
+ // Function to aggregate all known remote module paths
61
+ var getAllKnownRemotes = function() {
62
+ var found = {};
63
+ // Iterate over all federation instances to collect module cache entries
64
+ (federationManager.__INSTANCES__ || []).forEach((instance) => {
65
+ instance.moduleCache.forEach((value, key) => {
66
+ found[key] = value;
67
+ });
68
+ });
69
+ return found;
70
+ };
71
+
72
+ // Retrieve the combined remote cache from all federation instances
73
+ const combinedRemoteCache = getAllKnownRemotes();
74
+ // Get the name of the current host from the instance
75
+ const hostName = instance.name;
76
+ // Find the path for the current host in the remote cache
77
+ const foundPath = combinedRemoteCache[hostName];
78
+ // If a path is not found, return undefined to indicate the absence of an entry path
79
+ if (!foundPath) { return undefined; }
80
+ // Return the entry path for the found remote module
81
+ const entryPath = foundPath.remoteInfo.entry;
82
+ return entryPath;
83
+ }
84
+ ` ;
85
+ const definePropertyCode = `
86
+ Object.defineProperty(__webpack_require__, "p", {
87
+ get: function() {
88
+ var scriptUrl;
89
+
90
+ // Attempt to get the script URL based on the environment
91
+ var scriptType = ${ JSON . stringify ( scriptType ) } ;
92
+ var chunkLoading = ${ JSON . stringify ( chunkLoading ) } ;
93
+ var isModuleEnvironment = ['module', 'node', 'async-node', 'require'].includes(scriptType) || chunkLoading;
94
+
95
+ if (isModuleEnvironment) {
96
+ try {
97
+ // Use Function constructor to avoid direct reference to import.meta in environments that do not support it
98
+ scriptUrl = (new Function('return typeof ${ importMetaName } .url === "string" ? ${ importMetaName } .url : undefined;'))();
99
+ } catch (e) {
100
+ // Handle cases where import.meta is not available or other errors occur
101
+ var scriptPath = getPathFromFederation();
102
+ if (scriptPath) {
103
+ scriptUrl = scriptPath;
104
+ } else if (typeof __filename !== "undefined") {
105
+ scriptUrl = __filename;
106
+ } else {
107
+ scriptUrl = ${
108
+ publicPath !== 'auto' ? JSON . stringify ( getPath ( ) ) : 'undefined'
109
+ } ;
110
+ }
111
+ }
112
+ } else {
113
+ // Fallback for non-module environments, such as browsers
114
+ if (${ RuntimeGlobals . global } .importScripts) {
115
+ scriptUrl = ${ RuntimeGlobals . global } .location + "";
116
+ }
117
+ var document = ${ RuntimeGlobals . global } .document;
118
+ if (!scriptUrl && document) {
119
+ if (document.currentScript) {
120
+ scriptUrl = document.currentScript.src;
121
+ } else {
122
+ var scripts = document.getElementsByTagName("script");
123
+ if (scripts.length) {
124
+ scriptUrl = scripts[scripts.length - 1].src;
125
+ }
133
126
}
134
- };
135
- ` ,
136
-
137
- [ 'module' , 'node' , 'async-node' , 'require' ] . includes ( scriptType || '' ) ||
138
- chunkLoading
139
- ? Template . asString ( [
140
- 'try {' ,
141
-
142
- '} catch (e) {' ,
143
- Template . indent ( [
144
- 'if (typeof remoteContainerRegistry.url === "string") {' ,
145
- Template . indent ( 'scriptUrl = remoteContainerRegistry.url;' ) ,
146
- '} else if(typeof __filename !== "undefined") {' ,
147
- Template . indent ( 'scriptUrl = __filename;' ) ,
148
- '} else {' ,
149
- Template . indent ( [
150
- `scriptUrl = ${
151
- publicPath !== 'auto'
152
- ? JSON . stringify ( getPath ( ) )
153
- : 'undefined'
154
- } `,
155
- ] ) ,
156
- '}' ,
157
- ] ) ,
158
- '}' ,
159
- ] )
160
- : Template . asString ( [
161
- `if (${ RuntimeGlobals . global } .importScripts) scriptUrl = ${ RuntimeGlobals . global } .location + "";` ,
162
- `var document = ${ RuntimeGlobals . global } .document;` ,
163
- 'if (!scriptUrl && document) {' ,
164
- Template . indent ( [
165
- 'if (document.currentScript)' ,
166
- Template . indent ( 'scriptUrl = document.currentScript.src' ) ,
167
- 'if (!scriptUrl) {' ,
168
- Template . indent ( [
169
- 'var scripts = document.getElementsByTagName("script");' ,
170
- 'if(scripts.length) scriptUrl = scripts[scripts.length - 1].src' ,
171
- ] ) ,
172
- '}' ,
173
- ] ) ,
174
- '}' ,
175
- ] ) ,
176
- '// When supporting server environments where an automatic publicPath is not supported, you must specify an output.publicPath manually via configuration' ,
177
- '// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.' ,
178
- 'if (!scriptUrl) throw new Error("Unable to calculate automatic public path");' ,
179
- 'scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");' ,
180
- ! undoPath
181
- ? `${ RuntimeGlobals . publicPath } = scriptUrl;`
182
- : `${ RuntimeGlobals . publicPath } = scriptUrl + ${ JSON . stringify (
183
- undoPath ,
184
- ) } ;`,
185
- "var addProtocol = (url)=> url.startsWith('//') ? 'https:' + url : url;" ,
186
- `globalThis.currentVmokPublicPath = addProtocol(${ RuntimeGlobals . publicPath } ) || '/';` ,
187
- ] ) ;
127
+ }
128
+ }
129
+
130
+ if (!scriptUrl) {
131
+ throw new Error("Unable to calculate automatic public path");
132
+ }
133
+
134
+ // Clean up the script URL by removing any hash or query parameters
135
+ scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");
136
+
137
+ // Apply any undo path that might be necessary for nested public paths
138
+ var finalScript = ${ JSON . stringify (
139
+ undoPath ,
140
+ ) } ? scriptUrl + ${ JSON . stringify ( undoPath ) } : scriptUrl;
141
+
142
+ // Helper function to ensure the URL has a protocol if it starts with '//'
143
+ var addProtocol = function(url) {
144
+ return url.startsWith('//') ? 'https:' + url : url;
145
+ };
146
+
147
+ // Set the global variable for the public path
148
+ globalThis.currentVmokPublicPath = addProtocol(finalScript) || '/';
149
+
150
+ // Return the final public path
151
+ return finalScript
152
+ }
153
+ });
154
+ ` ;
155
+
156
+ return Template . asString ( [ getPathFromFederation , definePropertyCode ] ) ;
188
157
}
189
158
}
190
159
0 commit comments