惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
博客园 - Franky
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
GbyAI
GbyAI
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 叶小钗
罗磊的独立博客
The GitHub Blog
The GitHub Blog
H
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
Spread Privacy
Spread Privacy
Google DeepMind News
Google DeepMind News
AWS News Blog
AWS News Blog
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
云风的 BLOG
云风的 BLOG
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
Cyberwarzone
Cyberwarzone
T
Threatpost
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
T
Tor Project blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
L
Lohrmann on Cybersecurity
量子位
V
V2EX
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Proofpoint News Feed
I
Intezer
Schneier on Security
Schneier on Security
雷峰网
雷峰网
B
Blog RSS Feed
Jina AI
Jina AI
爱范儿
爱范儿
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
美团技术团队
博客园 - 【当耐特】

Nx Blog

Sharing Tailwind CSS Styles Across Apps in a Monorepo | Nx Blog How SiriusXM Stays Competitive by Iterating and Getting to Market Fast | Nx Blog Agentic Experience Is the New Developer Experience | Nx Blog Nx Joins the Linux Foundation and the Agentic AI Foundation | Nx Blog A Monorepo Is NOT a Monolith | Nx Blog Why we deleted (most of) our MCP tools | Nx Blog Teach Your AI Agent How to Work in a Monorepo | Nx Blog How Broadcom stays efficient and nimble with monorepos | Nx Blog Why Monorepos are King in the Age of AI | Nx Blog Nx 2026 Roadmap: Expanding Agent Autonomy, Improving Performance, Better Polyglot and More | Nx Blog End to End Autonomous AI Agent Workflows with Nx | Nx Blog Autonomous Agents at Scale | Nx Blog Scaling 700+ Projects: How Nx Became a 'No-Brainer' for Caseware | Nx Blog The Missing Multiplier for AI Agent Productivity | Nx Blog A Year of Nx Webinars | Nx Blog Wrapping Up 2025 | Nx Blog Nx 22.3 Release: Angular 21 Support, tsgo Compiler, and Prettier v3 | Nx Blog Nx Cloud Release: Agent Resource Usage | Nx Blog Nx Platform Outperforms DIY Cache by 5x | Nx Blog An Nx Carol: Past, Present, and Future of Your Monorepo | Nx Blog Nx 22.1 Release: Terminal UI on Windows, Storybook 10, Vitest 4, and more! | Nx Blog The Compounding Effect: How Nx Features Multiply Performance Gains | Nx Blog 10 Monorepo Myths Debunked: Separating Fact from Fiction | Nx Blog Nx Cloud Release: Enterprise Task Analytics | Nx Blog Watch and Rebuild Storybook Dependencies with Nx | Nx Blog Book - React for Enterprise: Timeless Architecture for Enterprise Apps | Nx Blog Beyond Remote Cache: Unlock 70% More CI Performance | Nx Blog Nx 22 Release: Expanding the build platform | Nx Blog What's the Point of Generating All This Code If You Can't Merge It? | Nx Blog What's New in Nx Self-Healing CI | Nx Blog Nx Highlights: Smarter AI integration, all-new graph UI, and big new versions of your favorite tools | Nx Blog Making the Case for Smarter Monorepos, and How to Not Get Fooled by Myths | Nx Blog Integrating Biome in 20 Minutes | Nx Blog S1ngularity - What Happened, How We Responded, What We Learned | Nx Blog Stop Babysitting Your PRs: Self-Healing CI Cuts Time to Green by 50% | Nx Blog UKG Unifies Their Codebase and Eliminates CI Overhead to Focus on Customer Value | Nx Blog How Git Worktrees Changed My AI Agent Workflow | Nx Blog Nx Cloud Workspace Graph: See Your Organization's Code Structure Like Never Before | Nx Blog Seamless Java Deployment in Nx Using Docker | Nx Blog Getting Mobile Into Your Monorepo: Android + Nx | Nx Blog Polyglot Projects Made Easy: Integrating Spring Boot into an Nx Workspace | Nx Blog The Journey of the Nx Plugin for Gradle: From Prototype to Production | Nx Blog Combining Predictability and Intelligence With Nx Generators and AI | Nx Blog A New UI For The Humble Terminal | Nx Blog Continuous tasks are a huge DX improvement | Nx Blog New and Improved Module Federation Experience with Nx | Nx Blog A New UI for Nx Migration | Nx Blog Custom Task Runners and Self-Hosted Caching Changes | Nx Blog Enterprise Angular Monorepo Patterns | Nx Blog Using Rspack with Angular | Nx Blog Angular Architecture Guide To Building Maintainable Applications at Scale | Nx Blog Modern Angular Testing with Nx | Nx Blog Nx Update: 20.5 | Nx Blog Are Monorepos the Answer to Better AI-Assisted Development? | Nx Blog Making Cursor Smarter with an MCP Server For Nx Monorepos | Nx Blog React Development for 2025 | Nx Blog Using Apollo GraphQL in an Nx Workspace | Nx Blog Angular State Management for 2025 | Nx Blog Tailoring Nx for Your Organization | Nx Blog Nx Cloud Pipelines Come To Nx Console | Nx Blog Define the relationship with monorepos | Nx Blog See your affected project graph in Nx Cloud | Nx Blog Handling CORS In Your Workspace | Nx Blog Improve your architecture and CI pipeline times with Nx projects | Nx Blog Announcing Nx 20 | Nx Blog Introducing Nx Powerpack | Nx Blog Nx 19.5 is here! Stackblitz, Bun, Incremental Builds for Vite, Gradle Test Atomizer | Nx Blog Introducing Explain with AI | Nx Blog Nx Enterprise Podcast Episode 2: Tine Kondo | Nx Blog Monorepos and CI can be a Mess - Here's How Nx and Nx Cloud Fixed It | Nx Blog Nx Enterprise Podcast Episode 1: Hicham El Hammouchi | Nx Blog Nx 19.0 Release!! | Nx Blog Manage Your Gradle Project using Nx | Nx Blog Making the Argument for Monorepos | Nx Blog Reliable CI. A new execution model fixing both flakiness and slowness | Nx Blog Monorepos - Why Speed Matters | Nx Blog Nx Agents Walkthrough: Effortlessly Fast CI Built for Monorepos | Nx Blog Launch Nx Week Recap | Nx Blog Versioning and Releasing Packages in a Monorepo | Nx Blog Fast, Effortless CI | Nx Blog Introducing @nx/nuxt Enhanced Nuxt.js Support in Nx | Nx Blog What if Nx Plugins Were More Like VSCode Extensions | Nx Blog Monorepos: the Benefits, Challenges, and Importance of Tooling Support | Nx Blog Nx — Highlights of 2023 | Nx Blog Nx 17.2 Update | Nx Blog Unit Testing Expo Apps With Jest | Nx Blog Nx Docs AI Assistant | Nx Blog State Management Nx React Native/Expo Apps with TanStack Query and Redux | Nx Blog Nx 17 has Landed | Nx Blog Nx Conf 2023 — Recap | Nx Blog Nx Raises $16M Series A | Nx Blog Introducing Playwright Support for Nx | Nx Blog Nx 16.8 Release!!! | Nx Blog Step-by-Step Guide to Creating an Expo Monorepo with Nx | Nx Blog Qwikify your Development with Nx | Nx Blog Create Your Own create-react-app CLI | Nx Blog Storybook Interaction Tests in Nx | Nx Blog Evergreen Tooling — More than Just CodeMods | Nx Blog Nx 16.5 Release!!! | Nx Blog A Practical Guide on Effective AI Use - AI as Your Peer Programmer | Nx Blog
Configure Tailwind v4 with Angular in an Nx Monorepo | Nx Blog
Juri Strumpflohner · 2026-01-15 · via Nx Blog

Tailwind CSS v4 brought significant simplifications: no more tailwind.config.js, minimal dependencies, and a simple CSS import to get started. But if you're using Angular with Tailwind v4 in an Nx monorepo, there's a catch: your production CSS might be larger than it needs to be.

This article explains how Tailwind v4's scanning works with Angular's PostCSS setup, why it can lead to bloated CSS output, and how to optimize it using @source directives and Nx Sync Generators.

Using Vite in an NPM Workspace?

Setting Up Tailwind v4 with Angular

Setting up Tailwind v4 with Angular is straightforward. Both the Angular docs and Tailwind docs have guides for this. But they miss one important aspect when working in a monorepo, which is what we're digging into today.

Since Angular uses PostCSS for CSS processing, you need the PostCSS plugin.

Install the required packages:

{
  "dependencies": {
    "@tailwindcss/postcss": "^4.1.13",
    "tailwindcss": "^4.1.13"
  }
}

Configure PostCSS in your application:

apps/demoapp/.postcssrc.json

{
  "plugins": {
    "@tailwindcss/postcss": {}
  }
}

Import Tailwind in your styles entry point:

apps/demoapp/src/styles.css

@import 'tailwindcss';

That's it. Your Angular app now has Tailwind v4 configured. But here's where things get interesting in a monorepo setup.

The Problem: Over-Scanning in Monorepos

Consider a typical Nx workspace structure:

apps/
  demoapp/           # Your Angular application
libs/
  ui-design-system/  # Shared UI components (used by demoapp)
  another-ui/        # Another library (NOT used by demoapp)

When you run nx build demoapp, you'd expect only the Tailwind classes from demoapp and its dependency ui-design-system to end up in the final CSS. But that's not what happens by default.

Let's say another-ui has a component with this template:

libs/another-ui/src/lib/another-ui/another-ui.html

<p class="text-red-500">AnotherUi works!</p>

Even though demoapp never imports another-ui, if you check your production CSS output, you'll find text-red-500 in there. This happens for every unused class in every library in your workspace.

Why Does This Happen?

The @tailwindcss/postcss plugin uses process.cwd() as its default scanning base:

// @tailwindcss/postcss source
let base = opts.base ?? process.cwd();

When you run nx build demoapp, process.cwd() is your workspace root. Tailwind scans from there, finding all .html, .ts, and other template files across your entire monorepo.

This is different from the @tailwindcss/vite plugin, which uses the Vite config root (typically the app directory) as its base. With Vite you have the opposite problem: not enough is included by default, so you must explicitly add library sources. If you're using Vite with React or other frameworks, check out the Tailwind v4 with Vite in an NPM Workspace guide.

You could restrict the scanning by providing the base property in your PostCSS config:

apps/demoapp/.postcssrc.json

{
  "plugins": {
    "@tailwindcss/postcss": {
      "base": "./apps/demoapp/src"
    }
  }
}

But then you'd need to manually add @source directives for all your library dependencies. We'll look at a more automated approach.

Comparing PostCSS vs Vite Plugin Behavior

PluginDefault BaseMonorepo BehaviorNeeds @source for libs?
@tailwindcss/postcssprocess.cwd()Scans entire workspaceOnly if you restrict with source()
@tailwindcss/viteconfig.rootScans app directory onlyYes, always

With the PostCSS plugin, you get all classes from all libraries. With the Vite plugin, you get only classes from the app and must explicitly add library sources. Both approaches benefit from automation to manage @source directives.

Solution: Restricting Scanning with @source Directives

Tailwind v4 provides the source() function and @source directive to control which directories get scanned.

Step 1: Restrict Automatic Scanning

Update your styles entry point to limit automatic scanning to just your app:

apps/demoapp/src/styles.css

@import 'tailwindcss' source('./app');

The source("./app") modifier tells Tailwind to only auto-scan the app subdirectory relative to this CSS file.

Step 2: Add Library Dependencies

Now you need to explicitly add your library dependencies:

apps/demoapp/src/styles.css

@import 'tailwindcss' source('./app');

@source "../../../libs/ui-design-system/src";

With this configuration:

  • Classes from apps/demoapp/src/app/** are included (via source("./app"))
  • Classes from libs/ui-design-system/src/** are included (via @source)
  • Classes from libs/another-ui/** are NOT included

Your production CSS now contains only what you actually use.

Automating @source with Nx Sync Generators

Manually maintaining @source directives works, but introduces maintenance burden:

  • Easy to forget when adding new dependencies
  • Missing styles don't break builds (just cause visual bugs)
  • Every team member needs to remember to update paths

Nx Sync Generators solve this by automatically keeping your @source directives in sync with your project dependencies.

Using @juristr/nx-tailwind-sync

In the Tailwind v4 with Vite in an NPM Workspace article, I explained how to build a custom sync generator to automate @source directive management. I've since packaged this into @juristr/nx-tailwind-sync so you can use it directly.

Install it:

npm install @juristr/nx-tailwind-sync

Register the sync generator in your application's project.json:

apps/demoapp/project.json

{
  "name": "demoapp",
  "targets": {
    "build": {
      "executor": "@angular/build:application",
      "syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"],
      ...
    },
    "serve": {
      "executor": "@angular/build:dev-server",
      "syncGenerators": ["@juristr/nx-tailwind-sync:source-directives"],
      ...
    }
  }
}

Now when you run nx build demoapp or nx serve demoapp, the sync generator:

  1. Analyzes your application's dependency graph
  2. Generates @source directives for each dependency
  3. Updates your styles.css automatically

Your styles file gets managed markers:

apps/demoapp/src/styles.css

@import 'tailwindcss' source('./app');

/* nx-tailwind-sources:start */
@source "../../../libs/ui-design-system";
/* nx-tailwind-sources:end */

When you add a new library dependency, the next build or serve detects the change and updates the directives automatically.

How Sync Generators Work

Sync generators run before certain targets (like build or serve) and check if generated files are in sync with your source code. If something is out of sync, Nx prompts you to apply the changes.

This is the same mechanism Nx uses to keep TypeScript project references in sync with your dependency graph. Learn more in the Sync Generators documentation.

Alternative: PostCSS Plugin Approach

Community member Poul Hansen created a PostCSS plugin that achieves similar automation at build time rather than through sync generators.

This approach uses the createGlobPatternsForDependencies function from @nx/angular/tailwind to dynamically inject sources during the PostCSS processing phase. Check out the gist for implementation details.

Conclusion

Tailwind v4's simplified setup is great for standalone projects, but requires attention in monorepos. With Angular's PostCSS-based setup, the default behavior scans your entire workspace, potentially bloating your production CSS with unused classes.

By combining source() restrictions with @source directives and automating their maintenance through Nx Sync Generators, you get optimal CSS output without manual upkeep.

Learn More