Im using angular v15 for my project. It's not small but not really big. I'd say medium to big. Running ng serve takes A LOT of time. Build at: 2025-07-23T12:23:56.259Z - Hash: 5ba2b19880727f6c - Time: 150153ms Making a really small change like adding console.log: Build at: 2025-07-23T12:28:27.654Z - Hash: be9deeddc53e7be5 - Time: 60598ms I mean this is just ridiculous and I have no idea what's wrong.. I'm still using NgModules and have around 150 of them. this is my angular.json setting for build and serve "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "webpack.config.js" }, "sourceMap": true, "optimization": true, "statsJson": true, "outputPath": "dist/fuse", "index": "src/index.html", "main": "src/main.ts", "polyfills": [ "zone.js" ], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "allowedCommonJsDependencies": [ "apexcharts", "highlight.js", "crypto-js/enc-utf8", "crypto-js/hmac-sha256", "crypto-js/enc-base64", "flat", "quill", "lodash", "moment", "pdfmake/build/pdfmake", "pdfmake/build/vfs_fonts", "html-to-pdfmake", "jquery", "quill-image-resize-module-ts" ], "assets": [ "src/favicon-16x16.png", "src/favicon-32x32.png", "src/web.config", "src/assets", { "glob": "_redirects", "input": "src", "output": "/" } ], "stylePreprocessorOptions": { "includePaths": [ "src/@fuse/styles" ] }, "styles": [ "node_modules/@fortawesome/fontawesome-free/css/all.min.css", "node_modules/angular-calendar/css/angular-calendar.css", "node_modules/flatpickr/dist/flatpickr.css", "node_modules/slick-carousel/slick/slick.css", "node_modules/slick-carousel/slick/slick-theme.css", "src/@fuse/styles/tailwind.scss", "src/@fuse/styles/themes.scss", "src/styles/vendors.scss", "src/@fuse/styles/main.scss", "src/styles/styles.scss", "src/styles/tailwind.scss" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", "node_modules/slick-carousel/slick/slick.min.js" ] }, "configurations": { "production": { "customWebpackConfig": { "path": "webpack.config.js" }, "outputPath": "dist/production", "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "budgets": [ { "type": "initial", "maximumWarning": "3mb", "maximumError": "10mb" }, { "type": "anyComponentStyle", "maximumWarning": "75kb", "maximumError": "90kb" } ], "outputHashing": "all", "sourceMap": false }, "staging": { "outputPath": "dist/staging", "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.staging.ts" } ], "budgets": [ { "type": "initial", "maximumWarning": "3mb", "maximumError": "10mb" }, { "type": "anyComponentStyle", "maximumWarning": "75kb", "maximumError": "90kb" } ], "outputHashing": "all", "sourceMap": false }, "development": { "buildOptimizer": true, "optimization": true, "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-builders/custom-webpack:dev-server", "options": { "browserTarget": "fuse:build" }, "configurations": { "production": { "browserTarget": "fuse:buildroduction" }, "development": { "browserTarget": "fuse:build:development", "hmr": true } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "fuse:build" } }, tailwind.config.js: const path = require("path"); const colors = require("tailwindcss/colors"); const defaultTheme = require("tailwindcss/defaultTheme"); const generatePalette = require(path.resolve( __dirname, "src/@fuse/tailwind/utils/generate-palette" )); /** * Custom palettes * * Uses the generatePalette helper method to generate * Tailwind-like color palettes automatically */ const customPalettes = { brand: generatePalette("#2196F3"), }; /** * Themes */ const themes = { // Default theme is required for theming system to work correctly! default: { primary: { ...colors.indigo, DEFAULT: colors.indigo[600], }, accent: { ...colors.slate, DEFAULT: colors.slate[800], }, warn: { ...colors.red, DEFAULT: colors.red[600], }, "on-warn": { 500: colors.red["50"], }, }, // Rest of the themes will use the 'default' as the base // theme and will extend it with their given configuration. brand: { primary: customPalettes.brand, }, teal: { primary: { ...colors.teal, DEFAULT: colors.teal[600], }, }, rose: { primary: colors.rose, }, purple: { primary: { ...colors.purple, DEFAULT: colors.purple[600], }, }, amber: { primary: colors.amber, }, }; /** * Tailwind configuration */ const config = { darkMode: "class", content: ["./src/**/*.{html,scss,ts}", "./node_modules/flowbite/**/*.js"], important: true, theme: { fontSize: { xs: "0.625rem", sm: "0.75rem", md: "0.8125rem", base: "0.875rem", lg: "1rem", xl: "1.125rem", "2xl": "1.25rem", "3xl": "1.5rem", "4xl": "2rem", "5xl": "2.25rem", "6xl": "2.5rem", "7xl": "3rem", "8xl": "4rem", "9xl": "6rem", "10xl": "8rem", }, screens: { sm: "600px", md: "960px", lg: "1280px", xl: "1440px", }, extend: { gridTemplateColumns: { '5': 'repeat(5, minmax(0, 1fr))', }, animation: { "spin-slow": "spin 3s linear infinite", }, colors: { gray: colors.slate, 'chat-message-blue': '#57E6FF', 'primary-color': '#3C9ECF', 'secondary-color': '#e3f4fb', 'orange-color': '#ff8600', 'title-color': '#90D5F7' }, flex: { 0: "0 0 auto", }, fontFamily: { sans: `"Inter var", ${defaultTheme.fontFamily.sans.join(",")}`, mono: `"IBM Plex Mono", ${defaultTheme.fontFamily.mono.join( "," )}`, }, opacity: { 12: "0.12", 38: "0.38", 87: "0.87", }, rotate: { "-270": "270deg", 15: "15deg", 30: "30deg", 60: "60deg", 270: "270deg", }, scale: { "-1": "-1", }, zIndex: { "-1": -1, 49: 49, 60: 60, 70: 70, 80: 80, 90: 90, 99: 99, 999: 999, 9999: 9999, 99999: 99999, }, spacing: { 13: "3.25rem", 15: "3.75rem", 18: "4.5rem", 22: "5.5rem", 26: "6.5rem", 30: "7.5rem", 50: "12.5rem", 90: "22.5rem", // Bigger values 100: "25rem", 120: "30rem", 128: "32rem", 140: "35rem", 160: "40rem", 180: "45rem", 192: "48rem", 200: "50rem", 240: "60rem", 256: "64rem", 280: "70rem", 320: "80rem", 360: "90rem", 400: "100rem", 480: "120rem", // Fractional values "1/2": "50%", "1/3": "33.333333%", "2/3": "66.666667%", "1/4": "25%", "2/4": "50%", "3/4": "75%", }, minHeight: ({ theme }) => ({ ...theme("spacing"), }), maxHeight: { none: "none", }, minWidth: ({ theme }) => ({ ...theme("spacing"), screen: "100vw", }), maxWidth: ({ theme }) => ({ ...theme("spacing"), screen: "100vw", }), transitionDuration: { 400: "400ms", }, transitionTimingFunction: { drawer: "cubic-bezier(0.25, 0.8, 0.25, 1)", }, // @tailwindcss/typography typography: ({ theme }) => ({ DEFAULT: { css: { color: "var(--fuse-text-default)", '[class~="lead"]': { color: "var(--fuse-text-secondary)", }, a: { color: "var(--fuse-primary-500)", }, strong: { color: "var(--fuse-text-default)", }, "ol > li::before": { color: "var(--fuse-text-secondary)", }, "ul > li::before": { backgroundColor: "var(--fuse-text-hint)", }, hr: { borderColor: "var(--fuse-border)", }, blockquote: { color: "var(--fuse-text-default)", borderLeftColor: "var(--fuse-border)", }, h1: { color: "var(--fuse-text-default)", }, h2: { color: "var(--fuse-text-default)", }, h3: { color: "var(--fuse-text-default)", }, h4: { color: "var(--fuse-text-default)", }, "figure figcaption": { color: "var(--fuse-text-secondary)", }, code: { color: "var(--fuse-text-default)", fontWeight: "500", }, "a code": { color: "var(--fuse-primary)", }, pre: { color: theme("colors.white"), backgroundColor: theme("colors.gray.800"), }, thead: { color: "var(--fuse-text-default)", borderBottomColor: "var(--fuse-border)", }, "tbody tr": { borderBottomColor: "var(--fuse-border)", }, 'ol[type="A" s]': false, 'ol[type="a" s]': false, 'ol[type="I" s]': false, 'ol[type="i" s]': false, }, }, sm: { css: { code: { fontSize: "1em", }, pre: { fontSize: "1em", }, table: { fontSize: "1em", }, }, }, }), }, }, corePlugins: { appearance: false, container: false, float: false, clear: false, placeholderColor: false, placeholderOpacity: false, verticalAlign: false, }, plugins: [ // Fuse - Tailwind plugins require(path.resolve( __dirname, "src/@fuse/tailwind/plugins/utilities" )), require(path.resolve( __dirname, "src/@fuse/tailwind/plugins/icon-size" )), require(path.resolve(__dirname, "src/@fuse/tailwind/plugins/theming"))({ themes, }), require("flowbite/plugin"), // Other third party and/or custom plugins require("@tailwindcss/typography")({ modifiers: ["sm", "lg"] }), require("@tailwindcss/line-clamp"), ], }; module.exports = config; package.json: { "name": "fuse-angular", "version": "17.0.1", "description": "Fuse - Angular Admin Template and Starter Project", "author": "https://themeforest.net/user/srcn", "license": "https://themeforest.net/licenses/standard", "private": true, "scripts": { "ng": "ng", "start": "ng serve", "startrod": "ng serve --configuration production", "build": "ng build", "buildrod": "ng build --configuration production", "build:staging": "ng build --configuration staging", "build:stats": "ng build --stats-json", "analyze": "webpack-bundle-analyzer dist/fuse/stats.json", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "ng lint", "explore": "source-map-explorer dist/**/*.js" }, "dependencies": { "@angular-eslint/schematics": "^18.3.0", "@angular-material-components/datetime-picker": "^16.0.1", "@angular/animations": "15.0.0", "@angular/cdk": "15.0.0", "@angular/common": "15.0.0", "@angular/compiler": "15.0.0", "@angular/core": "15.0.0", "@angular/forms": "15.0.0", "@angular/material": "15.0.0", "@angular/material-luxon-adapter": "15.0.0", "@angular/material-moment-adapter": "^18.0.0", "@angular/platform-browser": "15.0.0", "@angular/platform-browser-dynamic": "15.0.0", "@angular/router": "15.0.0", "@fortawesome/fontawesome-free": "^6.6.0", "@microsoft/signalr": "^7.0.2", "@ng-bootstrap/ng-bootstrap": "^14.2.0", "@ngneat/transloco": "4.1.1", "@ngx-translate/core": "^14.0.0", "@ngx-translate/http-loader": "^8.0.0", "@ngxs/devtools-plugin": "^3.8.2", "@ngxs/storage-plugin": "^3.8.2", "@ngxs/store": "^3.8.2", "@popperjs/core": "^2.11.8", "angular-calendar": "^0.31.0", "apexcharts": "^3.53.0", "bootstrap": "^5.3.2", "crypto-js": "^4.2.0", "date-fns": "^2.30.0", "flatpickr": "^4.6.13", "flowbite": "^2.2.1", "html-to-pdfmake": "^2.5.13", "jquery": "^3.7.1", "jwt-decode": "^3.1.2", "lodash-es": "4.17.21", "luxon": "3.1.0", "moment": "^2.30.1", "ng-apexcharts": "1.7.4", "ng-recaptcha": "^13.2.1", "ngx-cookie-service": "^18.0.0", "ngx-image-cropper": "^6.3.2", "ngx-mat-select-search": "^7.0.7", "ngx-mat-timepicker": "^18.0.0", "ngx-material-file-input": "^4.0.0", "ngx-quill": "^20.0.1", "ngx-slick-carousel": "^17.0.0", "ngx-spinner": "^15.0.1", "ngx-toastr": "^16.0.1", "ngxs-reset-plugin": "^3.0.0", "pdfmake": "^0.2.20", "perfect-scrollbar": "1.5.5", "quill": "1.3.7", "quill-image-resize-module-ts": "^3.0.3", "rxjs": "7.5.7", "slick-carousel": "^1.8.1", "zone.js": "0.12.0" }, "devDependencies": { "@angular-builders/custom-webpack": "^15.0.0", "@angular-devkit/build-angular": "15.0.0", "@angular-devkit/core": "^18.2.5", "@angular-eslint/eslint-plugin": "15.2.1", "@angular-eslint/eslint-plugin-template": "15.2.1", "@angular/cli": "15.0.0", "@angular/compiler-cli": "15.0.0", "@angular/localize": "15.0.0", "@tailwindcss/line-clamp": "0.4.2", "@tailwindcss/typography": "0.5.8", "@types/crypto-js": "3.1.47", "@types/highlight.js": "10.1.0", "@types/jasmine": "4.3.0", "@types/jquery": "^3.5.32", "@types/lodash": "4.14.189", "@types/lodash-es": "4.17.6", "@types/luxon": "3.1.0", "@types/pdfmake": "^0.2.11", "@types/slick-carousel": "^1.6.40", "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", "chroma-js": "2.4.2", "eslint": "^8.57.0", "jasmine-core": "4.5.0", "karma": "6.4.1", "karma-chrome-launcher": "3.1.1", "karma-coverage": "2.2.0", "karma-jasmine": "5.1.0", "karma-jasmine-html-reporter": "2.0.0", "lodash": "^4.17.21", "postcss": "8.4.19", "raw-loader": "^2.0.0", "tailwindcss": "3.2.4", "typescript": "4.8.4", "webpack-bundle-analyzer": "^4.10.2" } } I also ran npx webpack-bundle-analyzer dist/fuse/stats.json (i know about report-generator.service.ts but i need that one as well as pdf and vfs stuff): Continue reading...