Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tailwind): support v4 #13049

Merged
merged 29 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5619b9d
feat: work on tailwind v4
florian-lefebvre Jan 23, 2025
375f7f9
feat: refactor
florian-lefebvre Jan 23, 2025
dc7e433
test
florian-lefebvre Jan 23, 2025
5c9f155
feat: write file
florian-lefebvre Jan 23, 2025
c78b6ef
feat: update fixture
florian-lefebvre Jan 23, 2025
6af5580
feat: create css file
florian-lefebvre Jan 23, 2025
bc11481
feat: astro add
florian-lefebvre Jan 23, 2025
83eea24
feat: example
florian-lefebvre Jan 23, 2025
8e774c9
feat: todos
florian-lefebvre Jan 23, 2025
c397877
Update .changeset/four-chairs-exercise.md
florian-lefebvre Jan 23, 2025
74f8d17
fix: typo
florian-lefebvre Jan 23, 2025
b56f2fb
fix: test
florian-lefebvre Jan 23, 2025
a2b75db
fix: test
florian-lefebvre Jan 23, 2025
8d14fee
fix: color
florian-lefebvre Jan 23, 2025
7ee87b9
Update .changeset/four-chairs-exercise.md
florian-lefebvre Jan 23, 2025
f2da6d8
fix: tests
florian-lefebvre Jan 23, 2025
bc0829b
Merge branch 'feat/tailwind-v4' of https://github.com/withastro/astro…
florian-lefebvre Jan 23, 2025
2b523d9
chore: changeset
florian-lefebvre Jan 23, 2025
1990a1d
Update curvy-penguins-act.md
florian-lefebvre Jan 24, 2025
773187e
Merge branch 'main' into feat/tailwind-v4
florian-lefebvre Jan 27, 2025
9de3c4f
Discard changes to packages/integrations/tailwind/base.css
florian-lefebvre Jan 27, 2025
93b81be
Discard changes to packages/integrations/tailwind/package.json
florian-lefebvre Jan 27, 2025
c0a90e1
Discard changes to packages/integrations/tailwind/src/index.ts
florian-lefebvre Jan 27, 2025
45e920d
Discard changes to packages/integrations/tailwind/test/basic.test.js
florian-lefebvre Jan 27, 2025
5e18866
Discard changes to packages/integrations/tailwind/test/fixtures/basic…
florian-lefebvre Jan 27, 2025
97a220a
Discard changes to packages/integrations/tailwind/test/fixtures/basic…
florian-lefebvre Jan 27, 2025
079cb5a
feat: update changeset
florian-lefebvre Jan 27, 2025
09f0542
chore: deps
florian-lefebvre Jan 27, 2025
f620e48
Update .changeset/curvy-penguins-act.md
florian-lefebvre Jan 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/curvy-penguins-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/tailwind': major
---

aaa
3 changes: 0 additions & 3 deletions packages/integrations/tailwind/base.css

This file was deleted.

17 changes: 6 additions & 11 deletions packages/integrations/tailwind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,30 @@
"homepage": "https://docs.astro.build/en/guides/integrations-guide/tailwind/",
"exports": {
".": "./dist/index.js",
"./base.css": "./base.css",
"./package.json": "./package.json"
},
"files": [
"dist",
"base.css"
"dist"
],
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
"dev": "astro-scripts dev \"src/**/*.ts\"",
"test": "astro-scripts test \"test/**/*.test.js\""
},
"dependencies": {
"autoprefixer": "^10.4.20",
"postcss": "^8.5.1",
"postcss-load-config": "^4.0.2"
},
"devDependencies": {
"astro": "workspace:*",
"astro-scripts": "workspace:*",
"tailwindcss": "^3.4.17",
"vite": "^6.0.9"
},
"peerDependencies": {
"astro": "^3.0.0 || ^4.0.0 || ^5.0.0",
"tailwindcss": "^3.0.24"
"astro": "^5.0.0",
"tailwindcss": "^4.0.0"
},
"publishConfig": {
"provenance": true
},
"dependencies": {
"@tailwindcss/vite": "^4.0.0"
}
}
101 changes: 25 additions & 76 deletions packages/integrations/tailwind/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,50 @@
import { fileURLToPath } from 'node:url';
import type { AstroIntegration } from 'astro';
import autoprefixerPlugin from 'autoprefixer';
import tailwindPlugin from 'tailwindcss';
import type { CSSOptions, UserConfig } from 'vite';

async function getPostCssConfig(
root: UserConfig['root'],
postcssInlineOptions: CSSOptions['postcss'],
) {
let postcssConfigResult;
// Check if postcss config is not inlined
if (!(typeof postcssInlineOptions === 'object' && postcssInlineOptions !== null)) {
let { default: postcssrc } = await import('postcss-load-config');
const searchPath = typeof postcssInlineOptions === 'string' ? postcssInlineOptions : root!;
try {
postcssConfigResult = await postcssrc({}, searchPath);
} catch {
postcssConfigResult = null;
}
}
return postcssConfigResult;
}

async function getViteConfiguration(
tailwindConfigPath: string | undefined,
nesting: boolean,
root: string,
postcssInlineOptions: CSSOptions['postcss'],
): Promise<Partial<UserConfig>> {
// We need to manually load postcss config files because when inlining the tailwind and autoprefixer plugins,
// that causes vite to ignore postcss config files
const postcssConfigResult = await getPostCssConfig(root, postcssInlineOptions);

const postcssOptions = postcssConfigResult?.options ?? {};
const postcssPlugins = postcssConfigResult?.plugins?.slice() ?? [];

if (nesting) {
const tailwindcssNestingPlugin = (await import('tailwindcss/nesting/index.js')).default;
postcssPlugins.push(tailwindcssNestingPlugin());
}

postcssPlugins.push(tailwindPlugin(tailwindConfigPath));
postcssPlugins.push(autoprefixerPlugin());

return {
css: {
postcss: {
...postcssOptions,
plugins: postcssPlugins,
},
},
};
}
import tailwindcss from '@tailwindcss/vite';
import { fileURLToPath } from 'node:url';
import { writeFileSync } from 'node:fs';

type TailwindOptions = {
/**
* Path to your tailwind config file
* @default 'tailwind.config.mjs'
* @deprecated It is recommended to use the `@config` directive, see https://tailwindcss.com/docs/upgrade-guide#using-a-javascript-config-file
* @default './tailwind.config.mjs'
*/
configFile?: string;
/**
* Apply Tailwind's base styles
* Disabling this is useful when further customization of Tailwind styles
* and directives is required. See {@link https://tailwindcss.com/docs/functions-and-directives#tailwind Tailwind's docs}
* for more details on directives and customization.
* @deprecated It is recommended to use a css file to configure Tailwind, see https://tailwindcss.com/docs/upgrade-guide#removed-tailwind-directives
* @default true
*/
applyBaseStyles?: boolean;
/**
* Add CSS nesting support using `tailwindcss/nesting`. See {@link https://tailwindcss.com/docs/using-with-preprocessors#nesting Tailwind's docs}
* for how this works with `postcss-nesting` and `postcss-nested`.
*/
nesting?: boolean;
};

export default function tailwindIntegration(options?: TailwindOptions): AstroIntegration {
const applyBaseStyles = options?.applyBaseStyles ?? true;
const customConfigPath = options?.configFile;
const nesting = options?.nesting ?? false;
export default function tailwindIntegration({
applyBaseStyles = true,
configFile,
}: TailwindOptions = {}): AstroIntegration {
if (applyBaseStyles && !configFile) {
configFile = './tailwind.config.mjs';
}

return {
name: '@astrojs/tailwind',
hooks: {
'astro:config:setup': async ({ config, updateConfig, injectScript }) => {
// Inject the Tailwind postcss plugin
'astro:config:setup': async ({ config, updateConfig, injectScript, createCodegenDir }) => {
updateConfig({
florian-lefebvre marked this conversation as resolved.
Show resolved Hide resolved
vite: await getViteConfiguration(
customConfigPath,
nesting,
fileURLToPath(config.root),
config.vite.css?.postcss,
),
vite: { plugins: [tailwindcss()] },
});

if (applyBaseStyles) {
// Inject the Tailwind base import
injectScript('page-ssr', `import '@astrojs/tailwind/base.css';`);
const codegenDir = createCodegenDir();
let content = '@import "tailwindcss";';
if (configFile) {
content += `\n@config ${JSON.stringify(fileURLToPath(new URL(configFile, config.root)))};`;
}

const url = new URL('tailwind.css', codegenDir);
writeFileSync(url, content, 'utf-8');

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish I could use a virtual module but it didn't work with vite nor postcss

injectScript('page-ssr', `import ${JSON.stringify(url)};`);
}
},
},
Expand Down
4 changes: 0 additions & 4 deletions packages/integrations/tailwind/test/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ describe('Basic', () => {

assert.equal(css.includes('box-sizing:border-box;'), true); // base css
assert.equal(css.includes('text-red-500'), true); // class css
assert.equal(
new RegExp(/\.a\[data-astro-cid-.*?\] \.b\[data-astro-cid-.*?\]/).test(css),
true,
); // nesting
});
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { fileURLToPath } from 'node:url';
// @ts-check
import tailwind from '@astrojs/tailwind';
import { defineConfig } from 'astro/config';

export default defineConfig({
integrations: [
tailwind({
configFile: fileURLToPath(new URL('./tailwind.config.js', import.meta.url)),
nesting: true
configFile: "./tailwind.config.js"
}),
]
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"type": "module",
"dependencies": {
"astro": "workspace:*",
"@astrojs/tailwind": "workspace:*"
"@astrojs/tailwind": "workspace:*",
"tailwindcss": "4.0.0"
}
}
Loading
Loading