Skip to content

Commit

Permalink
feat(tailwind): support v4 (#13049)
Browse files Browse the repository at this point in the history
Co-authored-by: HiDeoo <[email protected]>
Co-authored-by: Sarah Rainsberger <[email protected]>
  • Loading branch information
3 people authored Jan 29, 2025
1 parent db252e0 commit 2ed4bd9
Show file tree
Hide file tree
Showing 40 changed files with 547 additions and 265 deletions.
9 changes: 9 additions & 0 deletions .changeset/curvy-penguins-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@astrojs/tailwind': major
---

Deprecates the integration

Tailwind CSS now offers a Vite plugin which is the preferred way to use Tailwind 4 in Astro. Please uninstall `@astrojs/tailwind` and follow the [Tailwind documentation for manual installation](https://tailwindcss.com/docs/installation/framework-guides/astro).

This updated major version is only provided as a convenience for existing projects until they are able to migrate to the new plugin. It offers no additional functionality and is no longer recommended, but may continue to be used in your projects until it is removed entirely.
5 changes: 5 additions & 0 deletions .changeset/four-chairs-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Updates `astro add tailwind` to add the `@tailwindcss/vite` plugin instead of the `@astrojs/tailwind` integration
6 changes: 4 additions & 2 deletions examples/with-tailwindcss/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// @ts-check
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import tailwindcss from '@tailwindcss/vite';

// https://astro.build/config
export default defineConfig({
integrations: [tailwind()],
vite: {
plugins: [tailwindcss()]
}
});
6 changes: 2 additions & 4 deletions examples/with-tailwindcss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
},
"dependencies": {
"@astrojs/mdx": "^4.0.7",
"@astrojs/tailwind": "^5.1.5",
"@tailwindcss/vite": "^4.0.0",
"@types/canvas-confetti": "^1.9.0",
"astro": "^5.1.10",
"autoprefixer": "^10.4.20",
"canvas-confetti": "^1.9.3",
"postcss": "^8.5.1",
"tailwindcss": "^3.4.17"
"tailwindcss": "^4.0.0"
}
}
1 change: 1 addition & 0 deletions examples/with-tailwindcss/src/layouts/main.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
const { content } = Astro.props;
---

Expand Down
1 change: 1 addition & 0 deletions examples/with-tailwindcss/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
// Component Imports
import Button from '../components/Button.astro';
Expand Down
1 change: 1 addition & 0 deletions examples/with-tailwindcss/src/styles/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "tailwindcss";
7 changes: 0 additions & 7 deletions examples/with-tailwindcss/tailwind.config.cjs

This file was deleted.

10 changes: 2 additions & 8 deletions packages/astro/e2e/fixtures/tailwindcss/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { fileURLToPath } from 'node:url';
import tailwind from '@astrojs/tailwind';
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

// https://astro.build/config
export default defineConfig({
integrations: [
tailwind({
configFile: fileURLToPath(new URL('./tailwind.config.js', import.meta.url)),
applyBaseStyles: false
}),
],
devToolbar: {
enabled: false,
},
vite: {
plugins: [tailwindcss()],
build: {
assetsInlineLimit: 0,
},
Expand Down
5 changes: 2 additions & 3 deletions packages/astro/e2e/fixtures/tailwindcss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
"private": true,
"dependencies": {
"@astrojs/tailwind": "workspace:*",
"@tailwindcss/vite": "^4.0.0",
"astro": "workspace:*",
"autoprefixer": "^10.4.20",
"postcss": "^8.5.1",
"tailwindcss": "^3.4.17"
"tailwindcss": "^4.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
import Button from '../components/Button.astro';
import Complex from '../components/Complex.astro';
// Component Imports
Expand Down
7 changes: 7 additions & 0 deletions packages/astro/e2e/fixtures/tailwindcss/src/styles/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import 'tailwindcss';

@theme {
--color-dawn: #f3e9fa;
--color-dusk: #514375;
--color-midnight: #31274a;
}
14 changes: 0 additions & 14 deletions packages/astro/e2e/fixtures/tailwindcss/tailwind.config.js

This file was deleted.

4 changes: 2 additions & 2 deletions packages/astro/e2e/tailwindcss.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ test.describe('Tailwind CSS', () => {
await expect(button, 'should have bg-purple-600').toHaveClass(/bg-purple-600/);
await expect(button, 'should have background color').toHaveCSS(
'background-color',
'rgb(147, 51, 234)',
'oklch(0.558 0.288 302.321)',
);

await expect(button, 'should have lg:py-3').toHaveClass(/lg:py-3/);
Expand All @@ -66,7 +66,7 @@ test.describe('Tailwind CSS', () => {
await expect(button, 'should have bg-purple-400').toHaveClass(/bg-purple-400/);
await expect(button, 'should have background color').toHaveCSS(
'background-color',
'rgb(192, 132, 252)',
'oklch(0.714 0.203 305.504)',
);
});
});
81 changes: 57 additions & 24 deletions packages/astro/src/cli/add/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,7 @@ const ALIASES = new Map([

const STUBS = {
ASTRO_CONFIG: `import { defineConfig } from 'astro/config';\n// https://astro.build/config\nexport default defineConfig({});`,
TAILWIND_CONFIG: `/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
}\n`,
TAILWIND_GLOBAL_CSS: `@import "tailwindcss";`,
SVELTE_CONFIG: `\
import { vitePreprocess } from '@astrojs/svelte';
Expand Down Expand Up @@ -154,23 +147,28 @@ export async function add(names: string[], { flags }: AddOptions) {
switch (installResult) {
case UpdateResult.updated: {
if (integrations.find((integration) => integration.id === 'tailwind')) {
await setupIntegrationConfig({
root,
logger,
const dir = new URL('./styles/', new URL(userConfig.srcDir ?? './src/', root));
const styles = new URL('./global.css', dir);
if (!existsSync(styles)) {
logger.info(
'SKIP_FORMAT',
`\n ${magenta(`Astro will scaffold ${green('./src/styles/global.css')}.`)}\n`,
);

flags,
integrationName: 'Tailwind',
possibleConfigFiles: [
'./tailwind.config.cjs',
'./tailwind.config.mjs',
'./tailwind.config.ts',
'./tailwind.config.mts',
'./tailwind.config.cts',
'./tailwind.config.js',
],
defaultConfigFile: './tailwind.config.mjs',
defaultConfigContent: STUBS.TAILWIND_CONFIG,
});
if (await askToContinue({ flags })) {
if (!existsSync(dir)) {
await fs.mkdir(dir);
}
await fs.writeFile(styles, STUBS.TAILWIND_GLOBAL_CSS, 'utf-8');
} else {
logger.info(
'SKIP_FORMAT',
`\n @astrojs/tailwind requires additional configuration. Please refer to https://docs.astro.build/en/guides/integrations-guide/tailwind/`,
);
}
} else {
logger.debug('add', `Using existing tailwind configuration`);
}
}
if (integrations.find((integration) => integration.id === 'svelte')) {
await setupIntegrationConfig({
Expand Down Expand Up @@ -290,6 +288,8 @@ export async function add(names: string[], { flags }: AddOptions) {
)}`,
);
}
} else if (integration.id === 'tailwind') {
addVitePlugin(mod, 'tailwindcss', '@tailwindcss/vite');
} else {
addIntegration(mod, integration);
}
Expand Down Expand Up @@ -358,6 +358,7 @@ export async function add(names: string[], { flags }: AddOptions) {
} to your project:\n${list}`,
),
);
logger.info('SKIP_FORMAT', msg.success("Import './src/styles/global.css' in a layout"));
}
}

Expand Down Expand Up @@ -456,6 +457,31 @@ function addIntegration(mod: ProxifiedModule<any>, integration: IntegrationInfo)
}
}

function addVitePlugin(mod: ProxifiedModule<any>, pluginId: string, packageName: string) {
const config = getDefaultExportOptions(mod);

if (!mod.imports.$items.some((imp) => imp.local === pluginId)) {
mod.imports.$append({
imported: 'default',
local: pluginId,
from: packageName,
});
}

config.vite ??= {};
config.vite.plugins ??= [];
if (
!config.vite.plugins.$ast.elements.some(
(el: ASTNode) =>
el.type === 'CallExpression' &&
el.callee.type === 'Identifier' &&
el.callee.name === pluginId,
)
) {
config.vite.plugins.push(builders.functionCall(pluginId));
}
}

export function setAdapter(
mod: ProxifiedModule<any>,
adapter: IntegrationInfo,
Expand Down Expand Up @@ -796,6 +822,13 @@ async function validateIntegrations(integrations: string[]): Promise<Integration
);
}

if (integration === 'tailwind') {
dependencies = [
['@tailwindcss/vite', '^4.0.0'],
['tailwindcss', '^4.0.0'],
];
}

return { id: integration, packageName, dependencies, type: integrationType };
}),
);
Expand Down
11 changes: 4 additions & 7 deletions packages/astro/test/fixtures/astro-scripts/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { fileURLToPath } from 'node:url';
import tailwind from '@astrojs/tailwind';
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
integrations: [
tailwind({
configFile: fileURLToPath(new URL('./tailwind.config.cjs', import.meta.url)),
}),
],
vite: {
plugins: [tailwindcss()]
}
});
3 changes: 2 additions & 1 deletion packages/astro/test/fixtures/astro-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/tailwind": "workspace:*"
"@tailwindcss/vite": "^4.0.0",
"tailwindcss": "^4.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import './styles/global.css';
---

<html lang="en">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
import NoHoistClassic from '../components/NoHoistClassic.astro';
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
import NoHoistModule from '../components/NoHoistModule.astro';
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
import Widget from '../components/Widget.astro';
import Widget2 from '../components/Widget2.astro';
---
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
const components = await Astro.glob('/src/components/Glob/*');
const MyComponent = components[0].default;
---
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
import '../styles/global.css';
---

<html>
<head>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import '../styles/global.css';
import Inline from '../components/Inline.astro';
---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
import '../styles/global.css';
---

<html>
<head>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import 'tailwindcss';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { fileURLToPath } from 'node:url';
import tailwind from '@astrojs/tailwind';
import { defineConfig } from 'astro/config';
import tailwindcss from "@tailwindcss/vite"

// https://astro.build/config
export default defineConfig({
integrations: [
tailwind({
configFile: fileURLToPath(new URL('./tailwind.config.cjs', import.meta.url)),
}),
],
vite: {
plugins: [tailwindcss()],
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/tailwind": "workspace:*"
"@tailwindcss/vite": "^4.0.0",
"tailwindcss": "^4.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
import '../styles/global.css';
---

<h1 class="text-blue-500 text-2xl font-bold">Hello world</h1>

<style>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import 'tailwindcss';
Loading

0 comments on commit 2ed4bd9

Please sign in to comment.