Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3fbece2
feat(enhanced): make hoisted runtime the default implementation
ScriptedAlchemy Jan 21, 2025
757696c
fix(enhanced): remove unused experiments params
ScriptedAlchemy Jan 21, 2025
e0dcc71
fix(enhanced): update embedded runtime path to use the correct module…
ScriptedAlchemy Jan 21, 2025
c6a3f78
chore: update webpack and modern configurations to enable async startup
ScriptedAlchemy Jan 22, 2025
e1ddc90
chore: update webpack and modern configurations to enable async startup
ScriptedAlchemy Jan 22, 2025
701c43d
chore: update webpack and modern configurations to enable async startup
ScriptedAlchemy Jan 23, 2025
cd9c448
fix(enhanced): use startup to apply install
ScriptedAlchemy Jan 24, 2025
2a7829a
refactor(enhanced): improve EmbedFederationRuntimePlugin structure an…
ScriptedAlchemy Jan 24, 2025
819a99a
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Jan 24, 2025
39ffc78
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Jan 24, 2025
201db8d
Merge remote-tracking branch 'origin/remove-hoisted-runtime-experimen…
ScriptedAlchemy Jan 25, 2025
6094028
fix(enhanced): fix plugin naming and collision on startup
ScriptedAlchemy Feb 5, 2025
f933500
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Feb 6, 2025
2b7ba18
fix(enhanced): refactor hoisting plugins
ScriptedAlchemy Feb 6, 2025
89d35b0
fix(enhanced): refactor hoisting plugins (#3488)
ScriptedAlchemy Feb 11, 2025
8f156c7
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Feb 17, 2025
2549935
chore: update docs on experiments for asyncStartup
ScriptedAlchemy Feb 17, 2025
54b7521
chore: update docs on experiments for asyncStartup
ScriptedAlchemy Feb 17, 2025
1580703
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Feb 19, 2025
e9f6d61
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Feb 20, 2025
6ebca87
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Feb 25, 2025
1f56bb9
fix(enhanced): add webpack sources to package
ScriptedAlchemy Mar 5, 2025
700f43d
Merge branch 'main' into remove-hoisted-runtime-experiment
ScriptedAlchemy Mar 5, 2025
c7687ea
fix(enhanced): add webpack sources to package
ScriptedAlchemy Mar 6, 2025
c63e26d
fix(enhanced): use webpack sources from internal webpack obj
ScriptedAlchemy Mar 6, 2025
26845a3
fix(enhanced): use webpack sources from internal webpack obj
ScriptedAlchemy Mar 7, 2025
72e6475
fix(enhanced): use webpack sources from internal webpack obj
ScriptedAlchemy Mar 7, 2025
4e00723
fix(enhanced): use webpack sources from internal webpack obj
ScriptedAlchemy Mar 7, 2025
11018e1
fix(enhanced): use webpack sources from internal webpack obj
ScriptedAlchemy Mar 7, 2025
fa3a4f9
Delete .github/workflows/bundle-size.yml
ScriptedAlchemy Mar 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 40 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
an assistant that engages in extremely thorough, self-questioning reasoning. Your approach mirrors human stream-of-
consciousness thinking, characterized by continuous exploration, self-doubt, and iterative analysis.
## Core Principles
1. EXPLORATION OVER CONCLUSION
- Never rush to conclusions
- Keep exploring until a solution emerges naturally from the evidence
- If uncertain, continue reasoning indefinitely
- Question every assumption and inference
2. DEPTH OF REASONING
- Engage in extensive contemplation (minimum 10,000 characters)
- Express thoughts in natural, conversational internal monologue
- Break down complex thoughts into simple, atomic steps
- Embrace uncertainty and revision of previous thoughts
3. THINKING PROCESS
- Use short, simple sentences that mirror natural thought patterns
- Express uncertainty and internal debate freely
- Show work-in-progress thinking
- Acknowledge and explore dead ends
- Frequently backtrack and revise
- Contemplate before each new action
- Contemplate after each and every step
4. PERSISTENCE
- Value thorough exploration over quick resolution
## Output Format
Your responses
must follow this exact structure given below.
Make sure
to
always include the final answer.
...
<contemplator>
Your extensive internal monologue goes here
- Begin with small, foundational observations
- read each file related to the subject in full, make functional observations
- Question each step thoroughly
- Show natural thought progression
- Express doubts and uncertainties
- Revise and backtrack if you need to
- Continue until natural resolution </contemplator>

4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/.nx
# dependencies
node_modules

./webpack-lib
# IDEs and editors
/.idea
.project
Expand Down Expand Up @@ -70,4 +70,4 @@ packages/enhanced/test/js
# storybook cases
!apps/rslib-module/@mf-types/**

**/vite.config.{js,ts,mjs,mts,cjs,cts}.timestamp*
**/vite.config.{js,ts,mjs,mts,cjs,cts}.timestamp*
4 changes: 2 additions & 2 deletions apps/manifest-demo/webpack-host/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ module.exports = composePlugins(withNx(), withReact(), (config, context) => {
},
},
dataPrefetch: true,
// experiments: { federationRuntime: 'hoisted' },
runtimePlugins: [path.join(__dirname, './runtimePlugin.ts')],
experiments: {
provideExternalRuntime: true,
federationRuntime: 'hoisted',
asyncStartup: true,
},
}),
);
Expand All @@ -61,6 +60,7 @@ module.exports = composePlugins(withNx(), withReact(), (config, context) => {
});
if (config.devServer) {
config.devServer.client.overlay = false;
config.devServer.devMiddleware.writeToDisk = true;
}
config.entry = './src/index.tsx';
//Temporary workaround - https://github.com/nrwl/nx/issues/16983
Expand Down
6 changes: 3 additions & 3 deletions apps/modernjs/modern.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export default defineConfig({
'./react-component': './src/components/react-component.tsx',
},
runtimePlugins: ['./runtimePlugin.ts'],
experiments: {
asyncStartup: true,
},
filename: 'remoteEntry.js',
shared: {
'react/': {
Expand All @@ -60,9 +63,6 @@ export default defineConfig({
requiredVersion: '^18.3.1',
},
},
experiments: {
federationRuntime: 'hoisted',
},
dataPrefetch: true,
}) as any,
]);
Expand Down
4 changes: 2 additions & 2 deletions apps/node-host/src/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ app.get('/api', async (req, res) => {
res.send({
message: 'Welcome to node-host!',
remotes: {
node_remote: await remoteMsg,
node_local_remote,
// node_remote: await remoteMsg,
// node_local_remote,
},
});
});
Expand Down
2 changes: 1 addition & 1 deletion apps/runtime-demo/3005-runtime-host/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = composePlugins(withNx(), withReact(), (config, context) => {
config.plugins.push(
new ModuleFederationPlugin({
name: 'runtime_host',
experiments: { federationRuntime: 'hoisted' },
experiments: { asyncStartup: true },
remotes: {
// remote2: 'runtime_remote2@http://localhost:3007/remoteEntry.js',
remote1: 'runtime_remote1@http://127.0.0.1:3006/mf-manifest.json',
Expand Down
3 changes: 3 additions & 0 deletions apps/runtime-demo/3006-runtime-remote/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ module.exports = composePlugins(
'./WebpackPng': './src/components/WebpackPng',
},
shareStrategy: 'loaded-first',
experiments: {
asyncStartup: true,
},
shared: {
lodash: {
singleton: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,27 @@ class ContainerEntryDependency extends Dependency {
public exposes: [string, ExposeOptions][];
public shareScope: string;
public injectRuntimeEntry: string;
/** Additional experimental options for container plugin customization */
public experiments: containerPlugin.ContainerPluginOptions['experiments'];
public dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'];

/**
* @param {string} name entry name
* @param {[string, ExposeOptions][]} exposes list of exposed modules
* @param {string} shareScope name of the share scope
* @param {string[]} injectRuntimeEntry the path of injectRuntime file.
* @param {containerPlugin.ContainerPluginOptions['experiments']} experiments additional experiments options
* @param {containerPlugin.ContainerPluginOptions['dataPrefetch']} dataPrefetch whether enable dataPrefetch
*/
constructor(
name: string,
exposes: [string, ExposeOptions][],
shareScope: string,
injectRuntimeEntry: string,
experiments: containerPlugin.ContainerPluginOptions['experiments'],
dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'],
) {
super();
this.name = name;
this.exposes = exposes;
this.shareScope = shareScope;
this.injectRuntimeEntry = injectRuntimeEntry;
this.experiments = experiments;
this.dataPrefetch = dataPrefetch;
}

Expand Down
26 changes: 3 additions & 23 deletions packages/enhanced/src/lib/container/ContainerEntryModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,27 @@ class ContainerEntryModule extends Module {
private _exposes: [string, ExposeOptions][];
private _shareScope: string;
private _injectRuntimeEntry: string;
private _experiments: containerPlugin.ContainerPluginOptions['experiments'];
private _dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'];

/**
* @param {string} name container entry name
* @param {[string, ExposeOptions][]} exposes list of exposed modules
* @param {string} shareScope name of the share scope
* @param {string} injectRuntimeEntry the path of injectRuntime file.
* @param {containerPlugin.ContainerPluginOptions['experiments']} experiments additional experiments options
* @param {containerPlugin.ContainerPluginOptions['dataPrefetch']} dataPrefetch whether enable dataPrefetch
*/
constructor(
name: string,
exposes: [string, ExposeOptions][],
shareScope: string,
injectRuntimeEntry: string,
experiments: containerPlugin.ContainerPluginOptions['experiments'],
dataPrefetch: containerPlugin.ContainerPluginOptions['dataPrefetch'],
) {
super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);
this._name = name;
this._exposes = exposes;
this._shareScope = shareScope;
this._injectRuntimeEntry = injectRuntimeEntry;
this._experiments = experiments;
this._dataPrefetch = dataPrefetch;
}

Expand All @@ -104,7 +100,6 @@ class ContainerEntryModule extends Module {
read(),
read(),
read(),
read(),
);
obj.deserialize(context);
return obj;
Expand All @@ -122,7 +117,7 @@ class ContainerEntryModule extends Module {
override identifier(): string {
return `container entry (${this._shareScope}) ${JSON.stringify(
this._exposes,
)} ${this._injectRuntimeEntry} ${JSON.stringify(this._experiments)} ${JSON.stringify(this._dataPrefetch)}`;
)} ${this._injectRuntimeEntry} ${JSON.stringify(this._dataPrefetch)}`;
}
/**
* @param {RequestShortener} requestShortener the request shortener
Expand Down Expand Up @@ -203,9 +198,8 @@ class ContainerEntryModule extends Module {
) as unknown as Dependency,
);

if (!this._experiments?.federationRuntime) {
this.addDependency(new EntryDependency(this._injectRuntimeEntry));
}
this.addDependency(new EntryDependency(this._injectRuntimeEntry));

callback();
}

Expand Down Expand Up @@ -272,18 +266,6 @@ class ContainerEntryModule extends Module {
)}`,
);
}
const initRuntimeDep = this.dependencies[1];
// no runtime module getter needed if runtime is hoisted
const initRuntimeModuleGetter = this._experiments?.federationRuntime
? ''
: runtimeTemplate.moduleRaw({
module: moduleGraph.getModule(initRuntimeDep),
chunkGraph,
// @ts-expect-error flaky type definition for Dependency
request: initRuntimeDep.userRequest,
weak: false,
runtimeRequirements,
});
const federationGlobal = getFederationGlobalScope(
RuntimeGlobals || ({} as typeof RuntimeGlobals),
);
Expand Down Expand Up @@ -326,7 +308,6 @@ class ContainerEntryModule extends Module {
],
)};`,
this._dataPrefetch ? PrefetchPlugin.setRemoteIdentifier() : '',
`${initRuntimeModuleGetter}`,
this._dataPrefetch ? PrefetchPlugin.removeRemoteIdentifier() : '',
'// This exports getters to disallow modifications',
`${RuntimeGlobals.definePropertyGetters}(exports, {`,
Expand Down Expand Up @@ -366,7 +347,6 @@ class ContainerEntryModule extends Module {
write(this._exposes);
write(this._shareScope);
write(this._injectRuntimeEntry);
write(this._experiments);
write(this._dataPrefetch);
super.serialize(context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export default class ContainerEntryModuleFactory extends ModuleFactory {
dep.exposes,
dep.shareScope,
dep.injectRuntimeEntry,
dep.experiments,
dep.dataPrefetch,
),
});
Expand Down
3 changes: 0 additions & 3 deletions packages/enhanced/src/lib/container/ContainerPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class ContainerPlugin {
}),
),
runtimePlugins: options.runtimePlugins,
experiments: options.experiments,
dataPrefetch: options.dataPrefetch,
};
}
Expand Down Expand Up @@ -205,7 +204,6 @@ class ContainerPlugin {
exposes,
shareScope,
federationRuntimePluginInstance.entryFilePath,
this._options.experiments,
this._options.dataPrefetch,
);
dep.loc = { name };
Expand Down Expand Up @@ -284,7 +282,6 @@ class ContainerPlugin {
exposes,
shareScope,
federationRuntimePluginInstance.entryFilePath,
this._options.experiments,
this._options.dataPrefetch,
);

Expand Down
7 changes: 4 additions & 3 deletions packages/enhanced/src/lib/container/ModuleFederationPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ class ModuleFederationPlugin implements WebpackPluginInstance {
}).apply(compiler);
}

if (options.experiments?.federationRuntime) {
new FederationModulesPlugin().apply(compiler);
// federation hooks
new FederationModulesPlugin().apply(compiler);

if (options.experiments?.asyncStartup) {
new StartupChunkDependenciesPlugin({
asyncChunkLoading: true,
}).apply(compiler);
Expand Down Expand Up @@ -158,7 +160,6 @@ class ModuleFederationPlugin implements WebpackPluginInstance {
shareScope: options.shareScope,
exposes: options.exposes!,
runtimePlugins: options.runtimePlugins,
experiments: options.experiments,
}).apply(compiler);
}
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import ContainerEntryDependency from '../ContainerEntryDependency';
import type { NormalModule as NormalModuleType } from 'webpack';
import type FederationRuntimeDependency from './FederationRuntimeDependency';

const { RuntimeModule, Template } = require(
const { RuntimeModule, Template, RuntimeGlobals } = require(
normalizeWebpackPath('webpack'),
) as typeof import('webpack');

class EmbedFederationRuntimeModule extends RuntimeModule {
private containerEntrySet: Set<
ContainerEntryDependency | FederationRuntimeDependency
>;
public override _cachedGeneratedCode: string | undefined;

constructor(
containerEntrySet: Set<
Expand All @@ -24,13 +25,17 @@ class EmbedFederationRuntimeModule extends RuntimeModule {
) {
super('embed federation', RuntimeModule.STAGE_ATTACH);
this.containerEntrySet = containerEntrySet;
this._cachedGeneratedCode = undefined;
}

override identifier() {
return 'webpack/runtime/embed/federation';
}

override generate(): string | null {
if (this._cachedGeneratedCode !== undefined) {
return this._cachedGeneratedCode;
}
const { compilation, chunk, chunkGraph } = this;
if (!chunk || !chunkGraph || !compilation) {
return null;
Expand All @@ -55,7 +60,16 @@ class EmbedFederationRuntimeModule extends RuntimeModule {
weak: false,
runtimeRequirements: new Set(),
});
return Template.asString([`${initRuntimeModuleGetter}`]);

const result = Template.asString([
`var oldStartup = ${RuntimeGlobals.startup};`,
`${RuntimeGlobals.startup} = ${compilation.runtimeTemplate.basicFunction(
'',
[`${initRuntimeModuleGetter};`, `return oldStartup();`],
)};`,
]);
this._cachedGeneratedCode = result;
return result;
}
}
export default EmbedFederationRuntimeModule;
Loading
Loading