mirror of
https://github.com/withastro/astro.git
synced 2025-02-17 22:44:24 -05:00
Add tailwindcss nesting support (#9529)
* Add tailwindcss nesting support * Update lockfile
This commit is contained in:
parent
cf993bc263
commit
d252fc61b0
9 changed files with 121 additions and 4 deletions
5
.changeset/rude-deers-turn.md
Normal file
5
.changeset/rude-deers-turn.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/tailwind': minor
|
||||
---
|
||||
|
||||
Adds `nesting` option to enable `tailwindcss/nesting` support
|
|
@ -29,7 +29,8 @@
|
|||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\""
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
||||
"test": "mocha --exit --timeout 20000 test/"
|
||||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "^10.4.15",
|
||||
|
@ -39,6 +40,8 @@
|
|||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"chai": "^4.3.7",
|
||||
"mocha": "^10.2.0",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"vite": "^5.0.10"
|
||||
},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import type { AstroIntegration } from 'astro';
|
||||
import autoprefixerPlugin from 'autoprefixer';
|
||||
import tailwindPlugin from 'tailwindcss';
|
||||
|
@ -23,15 +24,22 @@ async function getPostCssConfig(
|
|||
|
||||
async function getViteConfiguration(
|
||||
tailwindConfigPath: string | undefined,
|
||||
viteConfig: UserConfig
|
||||
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(viteConfig.root, viteConfig.css?.postcss);
|
||||
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());
|
||||
|
||||
|
@ -59,18 +67,30 @@ type TailwindOptions = {
|
|||
* @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;
|
||||
|
||||
return {
|
||||
name: '@astrojs/tailwind',
|
||||
hooks: {
|
||||
'astro:config:setup': async ({ config, updateConfig, injectScript }) => {
|
||||
// Inject the Tailwind postcss plugin
|
||||
updateConfig({
|
||||
vite: await getViteConfiguration(customConfigPath, config.vite),
|
||||
vite: await getViteConfiguration(
|
||||
customConfigPath,
|
||||
nesting,
|
||||
fileURLToPath(config.root),
|
||||
config.vite.css?.postcss
|
||||
),
|
||||
});
|
||||
|
||||
if (applyBaseStyles) {
|
||||
|
|
33
packages/integrations/tailwind/test/basic.test.js
Normal file
33
packages/integrations/tailwind/test/basic.test.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { expect } from 'chai';
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
|
||||
describe('Basic', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: new URL('./fixtures/basic/', import.meta.url),
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('works', async () => {
|
||||
const astroChunkDir = await fixture.readdir('/_astro');
|
||||
|
||||
let css = '';
|
||||
for (const file of astroChunkDir) {
|
||||
if (file.endsWith('.css')) {
|
||||
css += await fixture.readFile(`/_astro/${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
expect(css).to.include('box-sizing:border-box;'); // base css
|
||||
expect(css).to.include('text-red-500'); // class css
|
||||
expect(css).to.match(/\.a\[data-astro-cid-.*?\] \.b\[data-astro-cid-.*?\]/); // nesting
|
||||
});
|
||||
});
|
||||
});
|
12
packages/integrations/tailwind/test/fixtures/basic/astro.config.js
vendored
Normal file
12
packages/integrations/tailwind/test/fixtures/basic/astro.config.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { fileURLToPath } from 'node:url';
|
||||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
tailwind({
|
||||
configFile: fileURLToPath(new URL('./tailwind.config.js', import.meta.url)),
|
||||
nesting: true
|
||||
}),
|
||||
]
|
||||
});
|
10
packages/integrations/tailwind/test/fixtures/basic/package.json
vendored
Normal file
10
packages/integrations/tailwind/test/fixtures/basic/package.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "@test/tailwind-basic",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/tailwind": "workspace:*"
|
||||
}
|
||||
}
|
13
packages/integrations/tailwind/test/fixtures/basic/src/pages/index.astro
vendored
Normal file
13
packages/integrations/tailwind/test/fixtures/basic/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<div class="text-red-500">red</div>
|
||||
|
||||
<div class="a">
|
||||
<div class="b">nested blue</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.a {
|
||||
.b {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
</style>
|
6
packages/integrations/tailwind/test/fixtures/basic/tailwind.config.js
vendored
Normal file
6
packages/integrations/tailwind/test/fixtures/basic/tailwind.config.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
import path from 'node:path';
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [path.join(__dirname, 'src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}')],
|
||||
};
|
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
|
@ -4566,6 +4566,12 @@ importers:
|
|||
astro-scripts:
|
||||
specifier: workspace:*
|
||||
version: link:../../../scripts
|
||||
chai:
|
||||
specifier: ^4.3.7
|
||||
version: 4.3.10
|
||||
mocha:
|
||||
specifier: ^10.2.0
|
||||
version: 10.2.0
|
||||
tailwindcss:
|
||||
specifier: ^3.3.5
|
||||
version: 3.3.5
|
||||
|
@ -4573,6 +4579,15 @@ importers:
|
|||
specifier: ^5.0.10
|
||||
version: 5.0.10(@types/node@18.18.6)(sass@1.69.5)
|
||||
|
||||
packages/integrations/tailwind/test/fixtures/basic:
|
||||
dependencies:
|
||||
'@astrojs/tailwind':
|
||||
specifier: workspace:*
|
||||
version: link:../../..
|
||||
astro:
|
||||
specifier: workspace:*
|
||||
version: link:../../../../../astro
|
||||
|
||||
packages/integrations/vercel:
|
||||
dependencies:
|
||||
'@astrojs/internal-helpers':
|
||||
|
|
Loading…
Add table
Reference in a new issue