Open DavidGoethCplace opened 10 months ago
I have the same problem, I can't run MFE because of ngDevMode
error ReferenceError: ngDevMode is not defined
at 168 (platform-browser.mjs:172:50)
at __webpack_require__ (bootstrap:19:1)
at 8836 (home-widgets.component.html:30:48)
at __webpack_require__ (bootstrap:19:1)
at container-entry:3:1
at 460.9e51155742b22477.js:1:165936
at Generator.next (<anonymous>)
at s (460.9e51155742b22477.js:1:546695)
at xe (460.9e51155742b22477.js:1:546913)
at O.invoke (polyfills.34b46c4a98362076.js:1:6572)
Package.json
"dependencies": {
"@angular-architects/module-federation": "17.0.1",
"@angular-architects/module-federation-tools": "17.0.1",
"@angular/animations": "^17.0.5",
"@angular/cdk": "^17.0.2",
"@angular/common": "^17.0.5",
"@angular/compiler": "^17.0.5",
"@angular/core": "^17.0.5",
"@angular/elements": "^17.0.5",
"@angular/forms": "^17.0.5",
"@angular/material": "^17.0.2",
"@angular/platform-browser": "^17.0.5",
"@angular/platform-browser-dynamic": "^17.0.5",
"@angular/router": "^17.0.5",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.5",
"@angular-eslint/builder": "17.1.1",
"@angular-eslint/eslint-plugin": "^17.1.1",
"@angular-eslint/eslint-plugin-template": "17.1.1",
"@angular-eslint/schematics": "17.1.1",
"@angular-eslint/template-parser": "17.1.1",
"@angular/cli": "~17.0.5",
"@angular/compiler-cli": "^17.0.5",
"@types/file-saver": "^2.0.7",
"@types/jasmine": "~4.3.0",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"eslint": "^8.54.0",
"jasmine-core": "~4.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"ngx-build-plus": "^17.0.0",
"typescript": "~5.2.2"
}
webpack.config
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, '../../tsconfig.json'),
[/* mapped paths to share */]);
module.exports = {
output: {
uniqueName: "terms",
publicPath: "auto",
},
optimization: {
runtimeChunk: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
experiments: {
outputModule: true,
},
plugins: [
new ModuleFederationPlugin({
library: { type: "module" },
name: "terms",
filename: "remoteEntry.js",
exposes: {
"./web-components": "./projects/terms/src/bootstrap.ts",
},
shared: share({
"@angular/core": { requiredVersion: "auto" },
"@angular/common": { requiredVersion: "auto" },
"@angular/router": { requiredVersion: "auto" },
rxjs: { requiredVersion: "auto" },
...sharedMappings.getDescriptors(),
}),
}),
sharedMappings.getPlugin(),
],
};
solution: webpack.config.js
add code in plugins
new webpack.DefinePlugin({
ngDevMode: "undefined",
}),
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const webpack = require("webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, '../../tsconfig.json'),
[/* mapped paths to share */]);
module.exports = {
....OTHERS,
plugins: [
// DISABLE ngDevMode as it is not needed in a remoteEntry
new webpack.DefinePlugin({
ngDevMode: "undefined",
}),
// END DISABLE ngDevMode as it is not needed in a remoteEntry
new ModuleFederationPlugin({
library: { type: "module" },
name: "NAME",
filename: "remoteEntry.js",
exposes: {
"./web-components": "./projects/NAME/src/bootstrap.ts",
},
...
}),
],
};
Im running into the same issue.
For me it is caused by @angular/forms
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckboxComponent),
multi: true,
},
],
the NG_VALUE_ACCESSOR is causing this issue: https://github.com/angular/angular/blob/main/packages/forms/src/directives/control_value_accessor.ts#L212
Probably this is due to the missing initalization. https://github.com/angular/angular/blob/main/packages/core/src/util/ng_dev_mode.ts#L119
However this does not explain why the NgDevMode is missing with ModuleFederation
@raulmelo Thanks for the workaround info. When I do that in my webpack.config.js, the compilation blows up with:
Generating browser application bundles (phase: setup).../Users/dobeachy/ise/frontend/node_modules/webpack/lib/DefinePlugin.js:341
compiler.hooks.compilation.tap(
^
TypeError: Cannot read properties of undefined (reading 'tap')
at DefinePlugin.apply (/Users/dobeachy/ise/frontend/node_modules/webpack/lib/DefinePlugin.js:341:30)
at exports.createResolver (/Users/dobeachy/ise/frontend/node_modules/enhanced-resolve/lib/ResolverFactory.js:695:11)
at ResolverFactory._create (/Users/dobeachy/ise/frontend/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/ResolverFactory.js:131:12)
at ResolverFactory.get (/Users/dobeachy/ise/frontend/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/ResolverFactory.js:112:28)
at exports.resolveMatchedConfigs (/Users/dobeachy/ise/frontend/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js:46:47)
at /Users/dobeachy/ise/frontend/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js:126:21
at Hook.eval [as call] (eval at create (/Users/dobeachy/ise/frontend/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:84:1)
at Hook.CALL_DELEGATE [as _call] (/Users/dobeachy/ise/frontend/node_modules/tapable/lib/Hook.js:14:14)
at Compiler.newCompilation (/Users/dobeachy/ise/frontend/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Compiler.js:1125:30)
at /Users/dobeachy/ise/frontend/node_modules/@angular-devkit/build-angular/node_modules/webpack/lib/Compiler.js:1170:29
My webpack.config.js
has:
, plugins: [
new webpack.DefinePlugin({
// DISABLE ngDevMode as it is not needed in a remoteEntry
ngDevMode: 'undefined'
}),
I'm using "@angular-architects/module-federation": "^17.0.8",
, but I also tried it with 17.0.1 and I'm getting the same error. Any ideas, anyone?
@dbeachy1 share your webpack.config.js please.
my code shell MFE with angular
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const mf = require('@angular-architects/module-federation/webpack');
const webpack = require('webpack');
const path = require('path');
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(path.join(__dirname, './tsconfig.json'), [
/* mapped paths to share */
]);
module.exports = {
output: {
uniqueName: 'modulo-core',
publicPath: 'auto',
},
optimization: {
runtimeChunk: false,
},
resolve: {
alias: {
...sharedMappings.getAliases(),
},
},
experiments: {
outputModule: true,
},
plugins: [
// DISABLE ngDevMode as it is not needed in a remoteEntry
new webpack.DefinePlugin({
ngDevMode: 'undefined',
}),
// END DISABLE ngDevMode as it is not needed in a remoteEntry
new ModuleFederationPlugin({
library: { type: 'module' },
shared: share({
'@angular/core': { requiredVersion: 'auto' },
'@angular/common': { requiredVersion: 'auto' },
'@angular/router': { requiredVersion: 'auto' },
'@angular/common/http': { requiredVersion: 'auto' },
rxjs: { requiredVersion: 'auto' },
...sharedMappings.getDescriptors(),
}),
}),
sharedMappings.getPlugin(),
],
};
dependencies:
"@angular-architects/module-federation": "17.0.1",
"@angular-architects/module-federation-tools": "17.0.1",
"@angular/animations": "^17.1.1",
"@angular/cdk": "^17.1.0",
"@angular/common": "^17.1.1",
"@angular/compiler": "^17.1.1",
"@angular/core": "^17.1.1",
"@angular/elements": "^17.1.1",
"@angular/forms": "^17.1.1",
"@angular/material": "^17.1.0",
"@angular/platform-browser": "^17.1.1",
"@angular/platform-browser-dynamic": "^17.1.1",
"ngx-build-plus": "^17.0.0",
"typescript": "~5.3.3"
@raulmelo Thanks for info. Unfortunately I can't share my entire webpack.config.js
because the code is private (the place I work), but the relevant part of my webpack.config.js
is what I posted above. Here are the relevant dependencies, though:
"@angular-architects/module-federation": "^17.0.8",
"@angular/animations": "17.1.3",
"@angular/cdk": "17.1.2",
"@angular/common": "17.1.3",
"@angular/compiler": "17.1.3",
"@angular/core": "17.1.3",
"@angular/forms": "17.1.3",
"@angular/localize": "17.1.3",
"@angular/platform-browser": "17.1.3",
"@angular/platform-browser-dynamic": "17.1.3",
"@angular/router": "17.1.3",
So I'm using a slightly newer version of Angular (17.1.3 vs. your 17.1.1), and a slightly newer module-federation (17.0.8 vs. your 17.0.1). I also tried setting a JavaScript global variable named ngDevMode
in the MFE's index.js
, but that doesn't fix the runtime bug, either. I'm debating whether to just switch to an older version of Angular 17 from before this breaking change in January...
EDIT: here's the pull request that broke this for MFEs: https://github.com/angular/angular/pull/53747
@raulmelo I have it working now, thanks for posting your code shell MFE! It turns out I was putting the new webpack.DefinePlugin
block in the wrong plugins
section in my webpack.config.js
(we have some resolve
plugins as well). Thanks again!
Quick note here. Updating webpack.config.js
as has been suggested above to force an "undefined" value onto ngDevMode is (at least in my experience) being treated as a truthy value.
This means that I still see "Angular is running in development mode" in the browser console as I enter the MFE. It is a workaround to avoid the original issue (ngDevMode is undefined) ... but by forcing development mode to be ON.
Finally, my attempts to force a false value onto ngDevMode at this same spot do not get rid of the original undefined error. Only forcing a truthy value clears the error, counterintuitively.
For me, this issue didn't appear until we tried to upgrade to Angular 17; we didn't have this issue at Angular 16. Looks to me like a regression happened along the way that strongly suggests a fix is needed somewhere in the libraries.
For me it seems to be an issue when swapping out MFE child apps. If the first child app was built with dev mode then it's not a problem. However, if first load a production mode app and then switch to a dev mode app, I see the issue.
Before switching from the production mode child to the dev mode child I enter this into the console: window.ngDevMode = {} then I don't see the problem.
It seems like Angular is not properly resetting dev mode when switching out child apps.
thanks @raulmelo
// DISABLE ngDevMode as it is not needed in a remoteEntry
new webpack.DefinePlugin({
ngDevMode: 'undefined',
}),
// END DISABLE ngDevMode as it is not needed in a remoteEntry
this solved my problem!
Hi,
When using the
ModuleFederationPlugin
within a custom webpack 5 configuration that is set to 'development' mode, I face the problem that angular produces a 'ReferenceError: ngDevMode is not defined' error.I have a simple solution by defining the ngDevMode manually:
But I think that should be handled by
ModuleFederationPlugin
directly.Greetings David