TailwindCSS is way too big with Angular build
Asked Answered
I

1

5

When I use Tailwind to style an Angular application with a custom webpack, the styles.js chunk is huge after running ng build, coming in at around 30mb. This not only takes forever to build, but also slows down my web app.

After purging the Tailwind, the styles.js chunk is far smaller (~100kb), however 30mb just seems ridiculously big, even un-purged.

This even applies to a fresh application built with https://github.com/notiz-dev/ngx-tailwind, so I'm not sure what is causing the issue.

tailwind.config.js

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            ident: 'postcss',
            syntax: 'postcss-scss',
            plugins: [
              require('postcss-import'),
              require('tailwindcss'),
              require('autoprefixer'),
            ],
          },
        },
      },
    ],
  },
};

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ngxTailwind": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "ngx-build-plus:browser",
          "options": {
            "extraWebpackConfig": "webpack.config.js",
            "outputPath": "dist/ngxTailwind",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "ngx-build-plus:dev-server",
          "options": {
            "extraWebpackConfig": "webpack.config.js",
            "browserTarget": "ngxTailwind:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ngxTailwind:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ngxTailwind:build"
          }
        },
        "test": {
          "builder": "ngx-build-plus:karma",
          "options": {
            "extraWebpackConfig": "webpack.config.js",
            "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.scss"
            ],
            "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": "ngxTailwind:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "ngxTailwind:serve:production"
            }
          }
        }
      }
    }
  },
  "defaultProject": "ngxTailwind",
  "cli": {
    "analytics": "c9efd59e-9db9-4f26-9a6f-e35b477d8e5a"
  }
}

styles.scss

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Does anyone have any idea as to why it's so big? I understand it is not purged, but https://tailwindcss.com/docs/optimizing-for-production claims the uncompressed size is under 4mb, why am I getting nearly 7 times this?

Incentive answered 30/11, 2020 at 21:33 Comment(5)
I see you mention style.js so you built it as development build. What's the size if you actually build it for production or with --extract-css?Inearth
@Inearth without purging, a production build gives a css file that is 3.52mb. This seems more reasonable, but the 30mb even in a development build just seems crazy to me.Incentive
That's just how it works with development build, reason behind it is because style.css is not a valid javascript module, so it need something to change css module to js module, and that is loaders. So style.js has all your css and includes javascript loadersInearth
@penleychan, I definitely expected it to be bigger, but 30mb?? It just makes developing a pain as it takes around a minute to build whenever any styling changes are made. When I use Bootstrap, the styles.js is far smaller, and the build time is much quicker.Incentive
I also experience the same issue. It's not normal as uncompressed tailwind is around 3MB. It's like it's included 10 times !? @JacobSwetmore Did you manage to find the root cause ?Syndesis
H
9

Just change tailwind.config.js

module.exports = {
  purge: {
    enabled: true,
    content: ['./src/**/*.{html,ts}']
  },
  //Other Code
};

then build: ng build --prod

Reference: Enabling manually

Hemminger answered 24/12, 2020 at 17:5 Comment(1)
My .css was 5mb. After "enabled: true" it's 145kb. Thanks.Alary

© 2022 - 2024 — McMap. All rights reserved.