Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
import dedent from 'dedent'
|
2024-03-05 14:23:26 +01:00
|
|
|
import { unlink, writeFile } from 'node:fs/promises'
|
|
|
|
|
import postcss from 'postcss'
|
|
|
|
|
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
|
2024-08-08 17:49:06 +02:00
|
|
|
// @ts-ignore
|
2024-03-05 14:23:26 +01:00
|
|
|
import tailwindcss from './index'
|
|
|
|
|
|
|
|
|
|
// We give this file path to PostCSS for processing.
|
|
|
|
|
// This file doesn't exist, but the path is used to resolve imports.
|
|
|
|
|
// We place it in packages/ because Vitest runs in the monorepo root,
|
|
|
|
|
// and packages/tailwindcss must be a sub-folder for
|
|
|
|
|
// @import 'tailwindcss' to work.
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
function inputCssFilePath() {
|
|
|
|
|
// Including the current test name to ensure that the cache is invalidated per
|
|
|
|
|
// test otherwise the cache will be used across tests.
|
|
|
|
|
return `${__dirname}/fixtures/example-project/input.css?test=${expect.getState().currentTestName}`
|
|
|
|
|
}
|
2024-03-05 14:23:26 +01:00
|
|
|
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
const css = dedent
|
2024-03-05 14:23:26 +01:00
|
|
|
|
|
|
|
|
test("`@import 'tailwindcss'` is replaced with the generated CSS", async () => {
|
2024-03-08 18:36:07 +01:00
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
2024-03-05 14:23:26 +01:00
|
|
|
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
let result = await processor.process(`@import 'tailwindcss'`, { from: inputCssFilePath() })
|
2024-03-05 14:23:26 +01:00
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchSnapshot()
|
|
|
|
|
|
|
|
|
|
// Check for dependency messages
|
|
|
|
|
expect(result.messages).toContainEqual({
|
|
|
|
|
type: 'dependency',
|
|
|
|
|
file: expect.stringMatching(/index.html$/g),
|
|
|
|
|
parent: expect.any(String),
|
|
|
|
|
plugin: expect.any(String),
|
|
|
|
|
})
|
|
|
|
|
expect(result.messages).toContainEqual({
|
|
|
|
|
type: 'dependency',
|
|
|
|
|
file: expect.stringMatching(/index.js$/g),
|
|
|
|
|
parent: expect.any(String),
|
|
|
|
|
plugin: expect.any(String),
|
|
|
|
|
})
|
|
|
|
|
expect(result.messages).toContainEqual({
|
|
|
|
|
type: 'dir-dependency',
|
2024-07-29 16:50:06 +02:00
|
|
|
dir: expect.stringMatching(/example-project[\/|\\]src$/g),
|
2024-03-05 14:23:26 +01:00
|
|
|
glob: expect.stringMatching(/^\*\*\/\*/g),
|
|
|
|
|
parent: expect.any(String),
|
|
|
|
|
plugin: expect.any(String),
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('output is optimized by Lightning CSS', async () => {
|
2024-03-08 18:36:07 +01:00
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
2024-03-05 14:23:26 +01:00
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
|
|
|
|
@layer utilities {
|
|
|
|
|
.foo {
|
|
|
|
|
@apply text-[black];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@layer utilities {
|
|
|
|
|
.bar {
|
|
|
|
|
color: red;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`,
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
{ from: inputCssFilePath() },
|
2024-03-05 14:23:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
"@layer utilities {
|
|
|
|
|
.foo {
|
|
|
|
|
color: #000;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.bar {
|
|
|
|
|
color: red;
|
|
|
|
|
}
|
|
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('@apply can be used without emitting the theme in the CSS file', async () => {
|
2024-03-08 18:36:07 +01:00
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
2024-03-05 14:23:26 +01:00
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
Add support for `inline` option when defining `@theme` values (#14095)
This PR adds support for a new `inline` option when defining a `@theme`
block that tells Tailwind to use raw theme values for utilities instead
of referencing the corresponding generated CSS variable.
```css
/* Input */
@theme inline {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
:root {
--color-red-500: #ef4444;
}
.text-red-500 {
color: #ef4444;
}
```
This can be composed with the existing `reference` option in case you
want to define a `@theme` block as both `reference` (so the variables
aren't generated) and `inline`:
```css
/* Input */
@theme inline reference {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
.text-red-500 {
color: #ef4444;
}
```
Since you can have multiple `@theme` blocks, you can even define some
values normally and some as inline based on how you're using them. For
example you might want to use `inline` for defining literal tokens like
`--color-red-500`, but include the variable for tokens that you want to
be able to theme like `--color-primary`:
```css
/* Input */
@theme inline {
--color-red-500: #ef4444;
/* ... */
}
@theme {
--color-primary: var(--color-red-500);
}
/* Example output */
:root {
--color-red-500: #ef4444;
--color-primary: var(--color-red-500);
}
.text-red-500 {
color: #ef4444;
}
.text-primary {
color: var(--color-primary, var(--color-red-500));
}
```
## Breaking changes
Prior to this PR, you could `@import` a stylesheet that contained
`@theme` blocks as reference by adding the `reference` keyword to your
import:
```css
@import "./my-theme.css" reference;
```
Now that `reference` isn't the only possible option when declaring your
`@theme`, this syntax has changed to a new `theme(…)` function that
accepts `reference` and `inline` as potential space-separated values:
```css
@import "./my-theme.css";
@import "./my-theme.css" theme(reference);
@import "./my-theme.css" theme(inline);
@import "./my-theme.css" theme(reference inline);
```
If you are using the `@import … reference` option with an earlier alpha
release, you'll need to update your code to `@import … theme(reference)`
once this PR lands in a release.
## Motivation
This PR is designed to solve an issue pointed out in #14091.
Prior to this PR, generated utilities would always reference variables
directly, with the raw value as a fallback:
```css
/* Input */
@theme {
--color-red-500: #ef4444;
/* ... */
}
/* Example output */
:root {
--color-red-500: #ef4444;
}
.text-red-500 {
color: var(--color-red-500, #ef4444);
}
```
But this can create issues with variables resolving to an unexpected
value when a theme value is referencing another variable defined on
`:root`.
For example, say you have a CSS file like this:
```css
:root, .light {
--text-fg: #000;
}
.dark {
--text-fg: #fff;
}
@theme {
--color-fg: var(--text-fg);
}
```
Without `@theme inline`, we'd generate this output if you used the
`text-fg` utility:
```css
:root, .light {
--text-fg: #000;
}
.dark {
--text-fg: #fff;
}
:root {
--color-fg: var(--text-fg);
}
.text-fg {
color: var(--color-fg, var(--text-fg));
}
```
Now if you wrote this HTML, you're probably expecting your text to be
the dark mode color:
```html
<div class="dark">
<h1 class="text-fg">Hello world</h1>
</div>
```
But you'd actually get the light mode color because of this rule:
```css
:root {
--color-fg: var(--text-fg);
}
.text-fg {
color: var(--color-fg, var(--text-fg));
}
```
The browser will try to resolve the `--color-fg` variable, which is
defined on `:root`. When it tries to resolve the value, _it uses the
value of `var(--text-fg)` as it would resolve at `:root`_, not what it
would resolve to based on the element that has the `text-fg` class.
So `var(--color-fg)` resolves to `#000` because `var(--text-fg)`
resolved to `#000` at the point in the tree where the browser resolved
the value of `var(--color-fg)`.
By using `@theme inline`, the `.text-fg` class looks like this:
```css
.text-fg {
color: var(--text-fg);
}
```
With this definition, the browser doesn't try to resolve `--color-fg` at
all and instead resolves `--text-fg` directly which correctly resolves
to `#fff` as expected.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-02 09:37:30 -04:00
|
|
|
@import 'tailwindcss/theme.css' theme(reference);
|
2024-03-05 14:23:26 +01:00
|
|
|
.foo {
|
|
|
|
|
@apply text-red-500;
|
|
|
|
|
}
|
|
|
|
|
`,
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
{ from: inputCssFilePath() },
|
2024-03-05 14:23:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
".foo {
|
2024-11-05 15:44:21 -05:00
|
|
|
color: var(--color-red-500);
|
2024-03-05 14:23:26 +01:00
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
describe('processing without specifying a base path', () => {
|
|
|
|
|
let filepath = `${process.cwd()}/my-test-file.html`
|
|
|
|
|
|
|
|
|
|
beforeEach(() =>
|
|
|
|
|
writeFile(filepath, `<div class="md:[&:hover]:content-['testing_default_base_path']">`),
|
|
|
|
|
)
|
|
|
|
|
afterEach(() => unlink(filepath))
|
|
|
|
|
|
|
|
|
|
test('the current working directory is used by default', async () => {
|
2024-03-08 18:36:07 +01:00
|
|
|
let processor = postcss([tailwindcss({ optimize: { minify: false } })])
|
2024-03-05 14:23:26 +01:00
|
|
|
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
let result = await processor.process(`@import "tailwindcss"`, { from: inputCssFilePath() })
|
2024-03-05 14:23:26 +01:00
|
|
|
|
|
|
|
|
expect(result.css).toContain(
|
|
|
|
|
".md\\:\\[\\&\\:hover\\]\\:content-\\[\\'testing_default_base_path\\'\\]",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.messages).toContainEqual({
|
|
|
|
|
type: 'dependency',
|
|
|
|
|
file: expect.stringMatching(/my-test-file.html$/g),
|
|
|
|
|
parent: expect.any(String),
|
|
|
|
|
plugin: expect.any(String),
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
2024-07-11 09:47:26 -04:00
|
|
|
|
|
|
|
|
describe('plugins', () => {
|
|
|
|
|
test('local CJS plugin', async () => {
|
|
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
|
|
|
|
@import 'tailwindcss/utilities';
|
2024-08-07 16:38:44 +02:00
|
|
|
@plugin './plugin.js';
|
2024-07-11 09:47:26 -04:00
|
|
|
`,
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
{ from: inputCssFilePath() },
|
2024-07-11 09:47:26 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
".underline {
|
2024-08-07 16:38:44 +02:00
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (inverted-colors: inverted) {
|
|
|
|
|
.inverted\\:flex {
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hocus\\:underline:focus, .hocus\\:underline:hover {
|
|
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('local CJS plugin from `@import`-ed file', async () => {
|
|
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
|
|
|
|
@import 'tailwindcss/utilities';
|
|
|
|
|
@import '../example-project/src/relative-import.css';
|
|
|
|
|
`,
|
|
|
|
|
{ from: `${__dirname}/fixtures/another-project/input.css` },
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
".underline {
|
2024-07-11 09:47:26 -04:00
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (inverted-colors: inverted) {
|
|
|
|
|
.inverted\\:flex {
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hocus\\:underline:focus, .hocus\\:underline:hover {
|
|
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('published CJS plugin', async () => {
|
|
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
|
|
|
|
@import 'tailwindcss/utilities';
|
2024-07-29 16:58:07 +02:00
|
|
|
@plugin 'internal-example-plugin';
|
2024-07-11 09:47:26 -04:00
|
|
|
`,
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
{ from: inputCssFilePath() },
|
2024-07-11 09:47:26 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
".underline {
|
|
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (inverted-colors: inverted) {
|
|
|
|
|
.inverted\\:flex {
|
|
|
|
|
display: flex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.hocus\\:underline:focus, .hocus\\:underline:hover {
|
|
|
|
|
text-decoration-line: underline;
|
|
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|
|
|
|
|
})
|
Improve performance of `@tailwindcss/postcss` and `@tailwindcss/vite` (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 16:59:29 +01:00
|
|
|
|
|
|
|
|
test('bail early when Tailwind is not used', async () => {
|
|
|
|
|
let processor = postcss([
|
|
|
|
|
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
let result = await processor.process(
|
|
|
|
|
css`
|
|
|
|
|
.custom-css {
|
|
|
|
|
color: red;
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
{ from: inputCssFilePath() },
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// `fixtures/example-project` includes an `underline` candidate. But since we
|
|
|
|
|
// didn't use `@tailwind utilities` we didn't scan for utilities.
|
|
|
|
|
expect(result.css).not.toContain('.underline {')
|
|
|
|
|
|
|
|
|
|
expect(result.css.trim()).toMatchInlineSnapshot(`
|
|
|
|
|
".custom-css {
|
|
|
|
|
color: red;
|
|
|
|
|
}"
|
|
|
|
|
`)
|
|
|
|
|
})
|