'main.js file size is too high - Micro Front End with Single SPA
I am trying microfrontend using Single SPA Framework, i span one angular application and did the Single SPA Configuration. When i try to boot the angular application i could see the file size of main.js as 9 MB which is too huge for simple sample application with one component
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"app2": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app2",
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"outputPath": "dist/app2",
"index": "src/index.html",
"main": "src/main.single-spa.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": [],
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
}
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "app2:build"
},
"configurations": {
"production": {
"browserTarget": "app2:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "app2:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "app2:serve"
},
"configurations": {
"production": {
"devServerTarget": "app2:serve:production"
}
}
}
}
}
},
"defaultProject": "app2",
"cli": {
"analytics": false
}
}
package.json
{
"name": "app1",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "npm run serve:single-spa",
"build": "npm run build:single-spa",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:single-spa": "ng build --prod --deploy-url /dist/app1 --output-hashing none",
"serve:single-spa": "ng serve --disable-host-check --port 4203 --deploy-url http://localhost:4203/ --live-reload false"
},
"private": true,
"dependencies": {
"@angular-builders/custom-webpack": "^8",
"@angular/animations": "~9.1.7",
"@angular/common": "~9.1.7",
"@angular/compiler": "~9.1.7",
"@angular/core": "~9.1.7",
"@angular/forms": "~9.1.7",
"@angular/platform-browser": "~9.1.7",
"@angular/platform-browser-dynamic": "~9.1.7",
"@angular/router": "~9.1.7",
"rxjs": "~6.5.5",
"single-spa": "^5.5.0",
"single-spa-angular": "^4.0.1",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.901.6",
"@angular/cli": "~9.1.6",
"@angular/compiler-cli": "~9.1.7",
"@angular/language-service": "~9.1.7",
"@types/node": "^12.11.1",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.8.3"
}
}
extra-webpack-config.js
const singleSpaAngularWebpack = require('single-spa-angular/lib/webpack').default
module.exports = (angularWebpackConfig, options) => {
const singleSpaWebpackConfig = singleSpaAngularWebpack(angularWebpackConfig, options)
// Feel free to modify this webpack config however you'd like to
return singleSpaWebpackConfig
}
Help me on reducing the file size, Thanks in Advance
Solution 1:[1]
You should try using a bundle analyzer like source-map-explorer. That will show you what takes up all the space.
Install the package:
npm i -g source-map-explorer
Use it to analyze your application:
ng build --configuration production --sourceMap=true && source-map-explorer dist\\main-*.*.js
Solution 2:[2]
dev bundle size should not matter, as when you develop, you download the files locally. only thing that actually matters is the prod build.
if you develop off machine to a remote server, that all is lost and you should rethink your strategy regarding this situation.
Solution 3:[3]
My suggestion would be, try using module federation for sharing only resources you need by exposing remoteEntry.js
.
you can specify which module or component or lib to be shared by configuring your app using module federation.
In your sample, you are exposing your whole app as
main.js
bundle, so probably it will consume lot of memory size.But using module federation, you can customize your exposing module.
For example,
Imagine you are only exposing an AppModule
(only the code which has dependency) will be shared not an entire app code as main.js
For clear idea, watch this video explanation
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Bertramp |
Solution 2 | Lexxx |
Solution 3 | Yuvaraj |