60 Commits

Author SHA1 Message Date
Robin Malfait
c9dfe17cac
Prepare v4.0.0-beta.8 release (#15418) 2024-12-17 13:31:28 +01:00
Robin Malfait
0072f01376
Prepare v4.0.0-beta.7 release (#15392)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-12-13 14:18:21 +00:00
Robin Malfait
bcf70990a7
Improve debug logs (#15303)
This PR improves the debug logs for the `@tailwindcss/postcss`
integration. It uses custom instrumentation to provide a nested but
detailed overview of where time is spent during the build process.

The updated logs look like this:
```
[0.15ms] [@tailwindcss/postcss] src/app/geistsans_9fc57718.module.css
[0.14ms]   ↳ Quick bail check
[0.02ms] [@tailwindcss/postcss] src/app/geistsans_9fc57718.module.css
[0.01ms]   ↳ Quick bail check

[0.03ms] [@tailwindcss/postcss] src/app/geistmono_b9f59162.module.css
[0.02ms]   ↳ Quick bail check
[0.12ms] [@tailwindcss/postcss] src/app/geistmono_b9f59162.module.css
[0.11ms]   ↳ Quick bail check

[42.09ms] [@tailwindcss/postcss] src/app/globals.css
[ 0.01ms]   ↳ Quick bail check
[12.12ms]   ↳ Setup compiler
[ 0.11ms]     ↳ PostCSS AST -> Tailwind CSS AST
[11.99ms]     ↳ Create compiler
[ 0.07ms]   ↳ Register full rebuild paths
[ 0.06ms]   ↳ Setup scanner
[ 7.51ms]   ↳ Scan for candidates
[ 5.86ms]   ↳ Register dependency messages
[ 5.88ms]   ↳ Build utilities
[ 8.34ms]   ↳ Optimization
[ 0.23ms]     ↳ AST -> CSS
[ 4.20ms]     ↳ Lightning CSS
[ 3.89ms]     ↳ CSS -> PostCSS AST
[ 1.97ms]   ↳ Update PostCSS AST
```
2024-12-11 15:27:20 +01:00
Jordan Pittman
3d0b86c7d2
Prepare v4.0.0-beta.6 release (#15325) 2024-12-06 14:32:21 -05:00
Philipp Spiess
85da88f851
Prepare v4.0.0-beta.5 (#15285)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-12-04 16:28:16 +01:00
Robin Malfait
408fa99849
Use AST transformations in @tailwindcss/postcss (#15297)
This PR improves the `@tailwindcss/postcss` integration by using direct
AST transformations between our own AST and PostCSS's AST. This allows
us to skip a step where we convert our AST into a string, then parse it
back into a PostCSS AST.

The only downside is that we still have to print the AST into a string
if we want to optimize the CSS using Lightning CSS. Luckily this only
happens in production (`NODE_ENV=production`).

This also introduces a new private `compileAst` API, that allows us to
accept an AST as the input. This allows us to skip the PostCSS AST ->
string -> parse into our own AST step.

To summarize:

Instead of:
- Input: `PostCSS AST` -> `.toString()` -> `CSS.parse(…)` -> `Tailwind
CSS AST`
- Output: `Tailwind CSS AST` -> `toCSS(ast)` -> `postcss.parse(…)` ->
`PostCSS AST`

We will now do this instead:
- Input: `PostCSS AST` -> `transform(…)` -> `Tailwind CSS AST`
- Output: `Tailwind CSS AST` -> `transform(…)` -> `PostCSS AST`


---

Running this on Catalyst, the time spent in the `@tailwindcss/postcss`
looks like this:
- Before: median time per run: 19.407687 ms
- After: median time per run: 11.8796455 ms

This is tested on Catalyst which roughly generates ~208kb worth of CSS
in dev mode.

While it's not a lot, skipping the stringification and parsing seems to
improve this step by ~40%.

Note: these times exclude scanning the actual candidates and only time
the work needed for parsing/stringifying the CSS from and into ASTs. The
actual numbers are a bit higher because of the Oxide scanner reading
files from disk. But since that part is going to be there no matter
what, it's not fair to include it in this benchmark.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-12-04 15:43:59 +01:00
Robin Malfait
6af483547e
Improve performance of scanning source files (#15270)
This PR improves scanning files by scanning chunks of the files in
parallel. Each chunk is separated by new lines since we can't use
whitespace in classes anyway.

This also means that we can use the power of your CPU to scan files
faster. The extractor itself also has less state to worry about on these
smaller chunks.

On a dedicated benchmark machine: Mac Mini, M1, 16 GB RAM
```shellsession
❯ hyperfine --warmup 15 --runs 50 \
  -n NEW 'bun --bun /Users/ben/github.com/tailwindlabs/tailwindcss/packages/@tailwindcss-cli/src/index.ts -i ./tailwind.css -o out.css' \
  -n CURRENT 'bun --bun /Users/ben/github.com/tailwindlabs/tailwindcss--next/packages/@tailwindcss-cli/src/index.ts -i ./tailwind.css -o out.css'
Benchmark 1: NEW
  Time (mean ± σ):     337.2 ms ±   2.9 ms    [User: 1376.6 ms, System: 80.9 ms]
  Range (min … max):   331.0 ms … 345.3 ms    50 runs

Benchmark 2: CURRENT
  Time (mean ± σ):     730.3 ms ±   3.8 ms    [User: 978.9 ms, System: 78.7 ms]
  Range (min … max):   722.0 ms … 741.8 ms    50 runs

Summary
  NEW ran
    2.17 ± 0.02 times faster than CURRENT
```


On a more powerful machine, MacBook Pro M1 Max, 64 GB RAM, the results
look even more promising:
```shellsession
❯ hyperfine --warmup 15 --runs 50 \
  -n NEW 'bun --bun /Users/robin/github.com/tailwindlabs/tailwindcss/packages/@tailwindcss-cli/src/index.ts -i ./tailwind.css -o out.css' \
  -n CURRENT 'bun --bun /Users/robin/github.com/tailwindlabs/tailwindcss--next/packages/@tailwindcss-cli/src/index.ts -i ./tailwind.css -o out.css'
Benchmark 1: NEW
  Time (mean ± σ):     307.8 ms ±  24.5 ms    [User: 1124.8 ms, System: 187.9 ms]
  Range (min … max):   291.7 ms … 397.9 ms    50 runs

Benchmark 2: CURRENT
  Time (mean ± σ):     754.7 ms ±  27.2 ms    [User: 934.9 ms, System: 217.6 ms]
  Range (min … max):   735.5 ms … 845.6 ms    50 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  NEW ran
    2.45 ± 0.21 times faster than CURRENT
```

> Note: This last benchmark is running on my main machine which is more
"busy" compared to my benchmark machine. Because of this I had to
increase the `--runs` to get statistically better results. There is
still a warning present, but the overall numbers are still very
promising.

---

These benchmarks are running on our Tailwind UI project where we have
>1000 files, and >750 000 lines of code in those files.


| Before | After |
| --- | --- |
| <img width="385" alt="image"
src="https://github.com/user-attachments/assets/4786b842-bedc-4456-a9ca-942f72ca738c">
| <img width="382" alt="image"
src="https://github.com/user-attachments/assets/fb43cff8-95e7-453e-991e-d036c64659ba">
|

---

I am sure there is more we can do here, because reading all of these
1000 files only takes ~10ms, whereas parsing all these files takes
~180ms. But I'm still happy with these results as an incremental
improvement.

For good measure, I also wanted to make sure that we didn't regress on
smaller projects. Running this on Catalyst, we only have to deal with
~100 files and ~18 000 lines of code. In this case reading all the files
takes ~890µs and parsing takes about ~4ms.

| Before | After |
| --- | --- |
| <img width="381" alt="image"
src="https://github.com/user-attachments/assets/25d4859f-d058-4f57-a2f6-219d8c4b1804">
| <img width="390" alt="image"
src="https://github.com/user-attachments/assets/f06d7536-337b-4dc0-a460-6a9f141c65f5">
|

Not a huge difference, still better and definitely no regressions which
sounds like a win to me.

---

**Edit:** after talking to @thecrypticace, instead of splitting on any
whitespace we just split on newlines. This makes the chunks a bit
larger, but it reduces the overhead of the extractor itself. This now
results in a 2.45x speedup in Tailwind UI compared to 1.94x speedup.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-12-02 14:03:10 -05:00
Robin Malfait
973650624d
Prepare v4.0.0-beta.4 (#15245) 2024-11-29 17:18:42 +01:00
Philipp Spiess
6abd8086c3 Prepare v4.0.0-beta.3 (#15217)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-27 18:25:37 +01:00
Robin Malfait
4bdc724a22
Fix scanning classes delimited by tab characters (#15169)
This PR fixes an issue where multi-line candidates in Svelte files
couldn't be found as reported in #15148

After digging in, the real culprit seems to be that the reproduction
used tab `\t` characters instead of spaces and we only delimited
explicitly on spaces.

Initially I couldn't reproduce this in an integration test until we
(@thecrypticace and I) realised that `\t` was being used.

## Test plan:

This PR adds an integration test that fails before the fix happens. The
fix itself is easy in the sense that we just use all ascii whitespace
characters instead of just spaces.

Fixes: #15148
2024-11-26 18:22:18 +00:00
Jordan Pittman
bd43d63df2
Prepare v4.0.0-beta.2 release (#15104)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-22 11:17:21 -05:00
Jordan Pittman
8122837dde
Allow simple utilities with numbers in Oxide (#15110)
Fixes #15072

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
2024-11-22 11:05:24 -05:00
Jordan Pittman
5e4f565fe4
Prepare v4.0.0-beta.1 release (#15070) 2024-11-21 13:20:30 -05:00
Robin Malfait
11dce5af48
v4.0.0-alpha.36 (#15062)
Prepare v4.0.0-alpha.36
2024-11-21 14:20:56 +01:00
Robin Malfait
3cf5c2df79
Disallow empty arbitrary values (#15055)
This PR makes the candidate parser more strict by not allowing empty
arbitrary values.

Examples that are not allowed anymore:

- `bg-[]` — arbitrary value
- `bg-()` — arbitrary value, var shorthand
- `bg-[length:]` — arbitrary value, with typehint
- `bg-(length:)` — arbitrary value, with typehint, var shorthand
- `bg-red-500/[]` — arbitrary modifier
- `bg-red-500/()` — arbitrary modifier, var shorthand
- `data-[]:flex` — arbitrary value for variant
- `data-():flex` — arbitrary value for variant, var shorthand
- `group-visible/[]:flex` — arbitrary modifier for variant
- `group-visible/():flex` — arbitrary modifier for variant, var
shorthand

If you are trying to trick the parser by injecting some spaces like
this:

- `bg-[_]`

Then that is also not allowed.
2024-11-21 13:47:13 +01:00
Robin Malfait
8b098fc83d
Prepare v4.0.0-alpha.35 release (#15052) 2024-11-20 11:12:32 +00:00
Robin Malfait
3dc3bad781
Re-introduce automatic var injection shorthand (#15020)
This PR re-introduces the automatic var injection feature.

For some backstory, we used to support classes such as `bg-[--my-color]`
that resolved as-if you wrote `bg-[var(--my-color)]`.

The is issue is that some newer CSS properties accepts dashed-idents
(without the `var(…)`). This means that some properties accept
`view-timeline-name: --my-name;` (see:
https://developer.mozilla.org/en-US/docs/Web/CSS/view-timeline-name).

To make this a tiny bit worse, these properties _also_ accept
`var(--my-name-reference)` where the variable `--my-name-reference`
could reference a dashed-ident such as `--my-name`.

This makes the `bg-[--my-color]` ambiguous because we don't know if you
want `var(--my-color)` or `--my-color`.

With this PR, we bring back the automatic var injection feature as
syntactic sugar, but we use a different syntax to avoid the ambiguity.
Instead of `bg-[--my-color]`, you can now write `bg-(--my-color)` to get
the same effect as `bg-[var(--my-color)]`.

This also applies to modifiers, so `bg-red-500/[var(--my-opacity)]` can
be written as `bg-red-500/(--my-opacity)`. To go full circle, you can
rewrite `bg-[var(--my-color)]/[var(--my-opacity)]` as
`bg-(--my-color)/(--my-opacity)`.

---

This is implemented as syntactical sugar at the parsing stage and
handled when re-printing. Internally the system (and every plugin) still
see the proper `var(--my-color)` value.

Since this is also handled during printing of the candidate, codemods
don't need to be changed but they will provide the newly updated syntax.

E.g.: running this on the Catalyst codebase, you'll now see changes like
this:
<img width="542" alt="image"
src="https://github.com/user-attachments/assets/8f0e26f8-f4c9-4cdc-9f28-52307c38610e">

Whereas before we converted this to the much longer
`min-w-[var(--button-width)]`.

---

Additionally, this required some changes to the Oxide scanner to make
sure that `(` and `)` are valid characters for arbitrary-like values.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-18 15:47:48 +01:00
Philipp Spiess
953ecd2d19
Prepare v4.0.0-alpha.34 (#15002) 2024-11-14 18:23:40 +01:00
Adam Wathan
437579d3f0
Prepare v4.0.0-alpha.33 release (#14967)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 20:28:41 -05:00
Adam Wathan
7da9272d0f
Prepare v4.0.0-alpha.32 (#14954)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 11:05:22 -05:00
Robin Malfait
92007a5b23
Fix crash when using @source containing .. (#14831)
This PR fixes an issue where a `@source` crashes when the path
eventually resolves to a path ending in `..`.

We have to make sure that we canonicalize the path to make sure that we
are working with the real directory.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-10-30 16:24:48 -04:00
Jordan Pittman
3b2ca85138
Fix new file detection in PostCSS plugin (#14829)
We broke this at some point — probably when we tried to optimize
rebuilds in PostCSS by not performing a full auto-source detection scan.

This PR addresses this problem by:
1. Storing a list of found directories
2. Comparing their mod times on every scan
3. If the mod time has changed we scan the directory for new files which
we then store and scan
2024-10-30 15:56:55 +01:00
Robin Malfait
94ea5e225b
Prepare v4.0.0-alpha.31 release (#14823)
Prepare v4.0.0-alpha.31 release
2024-10-30 07:53:51 -04:00
Robin Malfait
f3786253f2
Fix integration tests on Windows (#14824)
This PR fixes Windows related path issues after merging #14820

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-10-30 11:26:29 +00:00
Robin Malfait
d68a780f98
Auto source detection improvements (#14820)
This PR introduces a new `source(…)` argument and improves on the
existing `@source`. The goal of this PR is to make the automatic source
detection configurable, let's dig in.

By default, we will perform automatic source detection starting at the
current working directory. Auto source detection will find plain text
files (no binaries, images, ...) and will ignore git-ignored files.

If you want to start from a different directory, you can use the new
`source(…)` next to the `@import "tailwindcss/utilities"
layer(utilities) source(…)`.

E.g.:

```css
/* ./src/styles/index.css */
@import 'tailwindcss/utilities' layer(utilities) source('../../');
```

Most people won't split their source files, and will just use the simple
`@import "tailwindcss";`, because of this reason, you can use
`source(…)` on the import as well:

E.g.:

```css
/* ./src/styles/index.css */
@import 'tailwindcss' source('../../');
```

Sometimes, you want to rely on auto source detection, but also want to
look in another directory for source files. In this case, yuo can use
the `@source` directive:

```css
/* ./src/index.css */
@import 'tailwindcss';

/* Look for `blade.php` files in `../resources/views` */
@source '../resources/views/**/*.blade.php';
```

However, you don't need to specify the extension, instead you can just
point the directory and all the same automatic source detection rules
will apply.

```css
/* ./src/index.css */
@import 'tailwindcss';

@source '../resources/views';
```

If, for whatever reason, you want to disable the default source
detection feature entirely, and only want to rely on very specific glob
patterns you define, then you can disable it via `source(none)`.

```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);

/* Only look at .blade.php files, nothing else  */
@source "../resources/views/**/*.blade.php";
```

Note: even with `source(none)`, if your `@source` points to a directory,
then auto source detection will still be performed in that directory. If
you don't want that, then you can simply add explicit files in the globs
as seen in the previous example.

```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);

/* Run auto source detection in `../resources/views` */
@source "../resources/views";
```

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-29 20:33:34 +00:00
Jordan Pittman
10a8f1a725
Prepare v4.0.0-alpha.30 release (#14789) 2024-10-24 16:22:08 -04:00
Philipp Spiess
2327e68bc7
Prepare v4.0.0-alpha.29 release (#14761) 2024-10-23 15:30:26 +02:00
Adam Wathan
b701ed6916
Prepare v4.0.0-alpha.28 release (#14709)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-17 17:03:28 -04:00
Jordan Pittman
92a43d6904
Speed up template migrations (#14679)
This PR does two things:
- Computes UTF-16 string positions in Rust rather than in JS —
eliminating a significant number of traversals of the input string
- Applies replacements to the content in ascending order so we only ever
move forward through the source string — this lets v8 optimize string
concatenation
2024-10-16 13:13:48 +02:00
Philipp Spiess
a75152d162
Release v4.0.0-alpha.27 (#14671) 2024-10-15 10:28:34 +00:00
Philipp Spiess
1467dab59e
Fix template migration issues (#14600)
This PR fixes two issues we found when testing the candidate codemodes:

1. Sometimes, core would emit the same candidate twice. This would
result into rewriting a range multiple times, without realizing that
this change might already be applied, causing it to swallow or duplicate
some bytes.
2. The codemods were mutating the `Candidate` object, however since the
`Candidate` parsing is _cached_ in core, it would sometimes return the
same instance. This is an issue especially since we monkey patch the
prefix to `null` when migrating prefixed candidates. This means that a
candidate would be cached that would be _invalid relative to the real
design system_. We fixed this by making sure the mutations would only be
applied to clones of the `Candidate` and I changed the `DesignSystem`
API to return `ReadOnly<T>` versions of these candidates. A better
solution would maybe be to disable the cache at all but this requires
broader changes in Core.
2024-10-08 18:06:43 +02:00
Robin Malfait
39e108d5f5
release v4.0.0-alpha.26 2024-10-03 16:39:59 +02:00
Robin Malfait
35b84cc313
Improve @tailwindcss/postcss performance for initial builds (#14565)
This PR improves the performance of the `@tailwindcss/postcss` plugin.
Before this change we created 2 compiler instances instead of a single
one. On a project where a `tailwindcss.config.ts` file is used, this
means that the timings look like this:

```
[@tailwindcss/postcss] Setup compiler: 137.525ms
⋮
[@tailwindcss/postcss] Setup compiler: 43.95ms
```

This means that with this small change, we can easily shave of ~50ms for
initial PostCSS builds.

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-10-03 16:21:54 +02:00
Philipp Spiess
bbe08c3b84
Add binary extensions found in macOS traces (#14584)
While we were doing some tracing for Rust memory issues, we noticed that
the builds became slower and slower. Turns out we did store the macOS
`.trace` dirs within the auto content directory of the Tailwind CSS
instance we were profiling and that _some of the files were massive
binary files that we were now scanning_.

Here's the anatomy of a single trace:


```
[ 320]  .
├── [497K]  form.template
├── [5.1K]  open.creq
├── [ 261]  UI_state_metadata.bin
├── [ 160]  corespace
│   ├── [1.2K]  MANIFEST.plist
│   ├── [  96]  currentRun
│   │   └── [  96]  core
│   │       └── [ 128]  uniquing
│   │           ├── [ 128]  arrayUniquer
│   │           │   ├── [10.0K]  integeruniquer.data
│   │           │   └── [   0]  integeruniquer.index
│   │           └── [ 128]  typedArrayUniquer
│   │               ├── [10.0K]  integeruniquer.data
│   │               └── [   0]  integeruniquer.index
│   └── [  96]  run1
│       └── [ 192]  core
│           ├── [ 224]  uniquing
│           │   ├── [6.5K]  EngineeringTypes.etypes
│           │   ├── [3.5K]  strings
│           │   ├── [ 344]  TOC
│           │   ├── [ 128]  arrayUniquer
│           │   │   ├── [1.1K]  integeruniquer.data
│           │   │   └── [  96]  integeruniquer.index
│           │   └── [ 128]  typedArrayUniquer
│           │       ├── [1.0K]  integeruniquer.data
│           │       └── [  28]  integeruniquer.index
│           ├── [ 192]  stores
│           │   ├── [ 224]  indexed-store-0
│           │   │   ├── [1.6K]  bulkstore
│           │   │   ├── [1.2K]  spindex.0
│           │   │   ├── [1.1K]  bulkstore_descriptor
│           │   │   ├── [ 433]  spec.plist
│           │   │   └── [ 188]  schema.xml
│           │   ├── [ 224]  indexed-store-1
│           │   │   ├── [7.5K]  bulkstore
│           │   │   ├── [7.0K]  spindex.0
│           │   │   ├── [1.6K]  bulkstore_descriptor
│           │   │   ├── [ 522]  spec.plist
│           │   │   └── [ 352]  schema.xml
│           │   ├── [ 224]  indexed-store-2
│           │   │   ├── [ 17K]  bulkstore
│           │   │   ├── [7.2K]  spindex.0
│           │   │   ├── [2.0K]  bulkstore_descriptor
│           │   │   ├── [ 532]  spec.plist
│           │   │   └── [ 412]  schema.xml
│           │   └── [ 192]  indexed-store-3
│           │       ├── [1.8K]  bulkstore_descriptor
│           │       ├── [ 426]  spec.plist
│           │       ├── [ 399]  schema.xml
│           │       └── [  50]  bulkstore
│           ├── [  96]  core-config
│           │   └── [2.0K]  exposedTableInfo.plist
│           └── [  96]  table-manager
│               └── [1.6K]  tables.plist
├── [ 128]  Trace1.run
│   ├── [966M]  event_data_52237.oa
│   └── [ 52K]  RunIssues.storedata
├── [ 128]  instrument_data
│   ├── [  96]  EF4DC038-8A17-421A-8050-39DD0980C06F
│   │   └── [  96]  run_data
│   │       └── [ 17K]  1.run.zip
│   └── [  96]  F9F2B147-A042-43F0-A791-EA6D63C7C1E8
│       └── [  96]  run_data
│           └── [2.2K]  1.run.zip
├── [ 128]  symbols
│   ├── [ 608]  stores
│   │   ├── [453K]  D14A8304-5F09-385D-9AA6-1B0C815B6356.symbolsarchive
│   │   ├── [ 36K]  4E9DB999-EFF4-3C83-B4E8-E1914D2C331E.symbolsarchive
│   │   ├── [3.7K]  B5D897DF-D536-3668-BBAD-A17119439EF0.symbolsarchive
│   │   ├── [3.1K]  57FFCB9D-A6C9-3E9A-AA82-40F192626527.symbolsarchive
│   │   ├── [2.9K]  69AA9AB7-C5DE-3CAE-BF1A-384F9F36A3E0.symbolsarchive
│   │   ├── [2.8K]  F453C5AE-3568-3AAA-AAA0-D2FDFBB9BC7A.symbolsarchive
│   │   ├── [2.6K]  62D27203-665F-3AA7-8BE9-7E3C3A847353.symbolsarchive
│   │   ├── [2.4K]  9896C713-054D-377D-88B4-45E1DE3FB6C5.symbolsarchive
│   │   ├── [2.1K]  249D8F21-72A2-3A80-ADC1-7BEAF24B5B58.symbolsarchive
│   │   ├── [2.1K]  FA954AC0-FCC5-3711-800B-432011ACD89E.symbolsarchive
│   │   ├── [2.0K]  E7ED11EE-AFB0-3B96-90A8-F1835726B9B8.symbolsarchive
│   │   ├── [1.3K]  5B476F9B-DF8B-356A-8582-615D4AD08504.symbolsarchive
│   │   ├── [1.3K]  6102110F-7ED8-34C2-95D3-C5ACCB41497E.symbolsarchive
│   │   ├── [1.1K]  EC86EDBF-30B9-3BF8-A358-C8D51805B016.symbolsarchive
│   │   ├── [1.0K]  6740FF57-8D20-3FC7-97F5-B2AFB6E5F48A.symbolsarchive
│   │   ├── [ 963]  9A72FD37-D827-3D6D-B6F4-422621E36C94.symbolsarchive
│   │   └── [ 948]  67A46592-439B-36DA-8A08-A7CD777A43A8.symbolsarchive
│   └── [ 290]  MANIFEST.plist
└── [  96]  shared_data
    └── [  96]  1.run
        └── [ 14M]  533F36D4-2C90-4030-95CA-74077F2E26D7.zip

29 directories, 59 files
```

Note that the biggest binary file is a `.oa` but I've also added
`.storedata` and `.symbolsarchive` as binary extensions to this PR.
2024-10-03 14:40:07 +02:00
Bartłomiej Maryńczak
fad5c81045
Use official FxHash crate (#14530) 2024-09-26 17:50:31 -04:00
Philipp Spiess
732147a761
Add setup for template migrations (#14502)
This PR adds the initial setup and a first codemod for the template
migrations. These are a new set of migrations that operate on files
defined in the Tailwind v3 config as part of the `content` option (so
your HTML, JavaScript, TSX files etc.).

The migration for this is integrated in the new `@tailwindcss/upgrade`
package and will require pointing the migration to an input JavaScript
config file, like this:

```
npx @tailwindcss/upgrade --config tailwind.config.js
```

The idea of template migrations is to apply breaking changes from the v3
to v4 migration within your template files.

## Migrating !important syntax

The first migration that I’m adding with this PR is to ensure we use the
v4 important syntax that has the exclamation mark at the end of the
utility.

For example, this:

```html
<div class="!flex sm:!block"></div>
```

Will now turn into:

```html
<div class="flex! sm:block!"></div>
```

## Architecture considerations

Implementation wise, we make use of Oxide to scan the content files fast
and efficiently. By relying on the same scanner als Tailwind v4, we
guarantee that all candidates that are part of the v4 output will have
gone through a migration.

Migrations itself operate on the abstract `Candidate` type, similar to
the type we use in the v4 codebase. It will parse the candidate into its
parts so they can easily be introspected/modified. Migrations are typed
as:

```ts
type TemplateMigration = (candidate: Candidate) => Candidate | null
``` 

`null` should be returned if the `Candidate` does not need a migration. 

We currently use the v4 `parseCandidate` function to get an abstract
definition of the candidate rule that we can operate on. _This will
likely need to change in the future as we need to fork `parseCandidate`
for v3 specific syntax_.

Additionally, we're inlining a `printCandidate` function that can
stringify the abstract `Candidate` type. It is not guaranteed that this
is an identity function since some information can be lost during the
parse step. This is not a problem though, because migrations will only
run selectively and if none of the selectors trigger, the candidates are
not updated. h/t to @RobinMalfait for providing the printer.

So the overall flow of a migration looks like this:

- Scan the config file for `content` files
- Use Oxide to extract a list of candidate and their positions from
these `content` files
- Run a few migrations that operate on the `Candidate` abstract type.
- Print the updated `Candidate` back into the original `content` file.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-09-25 16:20:14 +02:00
Robin Malfait
c094fadbbc
Release v4.0.0-alpha.25 (#14507) 2024-09-24 17:03:00 +00:00
Philipp Spiess
2ef87ab7fb
Release v4.0.0-alpha.24 (#14395) 2024-09-12 16:10:56 +02:00
Jordan Pittman
15d1714c33 v4.0.0-alpha.23 2024-09-05 10:43:07 -04:00
Adam Wathan
d9558bbc4c v4.0.0-alpha.22 2024-09-04 15:50:57 -04:00
Adam Wathan
dcfaaac8f6
Prepare v4.0.0-alpha.21 (#14313)
<!--

👋 Hey, thanks for your interest in contributing to Tailwind!

**Please ask first before starting work on any significant new
features.**

It's never a fun experience to have your pull request declined after
investing a lot of time and effort into a new feature. To avoid this
from happening, we request that contributors create an issue to first
discuss any significant new features. This includes things like adding
new utilities, creating new at-rules, or adding new component examples
to the documentation.


https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md

-->

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-02 15:43:28 -04:00
Philipp Spiess
d5f563b746
Prepare v4.0.0-alpha.20 (#14244)
Prepare next `4.0.0-alpha.20` release
2024-08-23 15:51:53 +02:00
Robin Malfait
a902128640
Improve Oxide scanner API (#14187)
This PR updates the API for interacting with the Oxide API. Until now,
we used the name `scanDir(…)` which is fine, but we do way more work
right now.

We now have features such as:

1. Auto source detection (can be turned off, e.g.: `@tailwindcss/vite`
doesn't need it)
2. Scan based on `@source`s found in CSS files
3. Do "incremental" rebuilds (which means that the `scanDir(…)` result
was stateful).

To solve these issues, this PR introduces a new `Scanner` class where
you can pass in the `detectSources` and `sources` options. E.g.:

```ts
let scanner = new Scanner({
  // Optional, omitting `detectSources` field disables automatic source detection
  detectSources: { base: __dirname }, 

  // List of glob entries to scan. These come from `@source` directives in CSS.
  sources: [
    { base: __dirname, pattern: "src/**/*.css" },
    // …
  ],
});
```

The scanner object has the following API:

```ts
export interface ChangedContent {
  /** File path to the changed file */
  file?: string
  /** Contents of the changed file */
  content?: string
  /** File extension */
  extension: string
}
export interface DetectSources {
  /** Base path to start scanning from */
  base: string
}
export interface GlobEntry {
  /** Base path of the glob */
  base: string
  /** Glob pattern */
  pattern: string
}
export interface ScannerOptions {
  /** Automatically detect sources in the base path */
  detectSources?: DetectSources
  /** Glob sources */
  sources?: Array<GlobEntry>
}
export declare class Scanner {
  constructor(opts: ScannerOptions)
  scan(): Array<string>
  scanFiles(input: Array<ChangedContent>): Array<string>
  get files(): Array<string>
  get globs(): Array<GlobEntry>
}
```

The `scanFiles(…)` method is used for incremental rebuilds. It takes the
`ChangedContent` array for all the new/changes files. It returns whether
we scanned any new candidates or not.

Note that the `scanner` object is stateful, this means that we don't
have to track candidates in a `Set` anymore. We can just call
`getCandidates()` when we need it.

This PR also removed some unused code that we had in the `scanDir(…)`
function to allow for sequential or parallel `IO`, and sequential or
parallel `Parsing`. We only used the same `IO` and `Parsing` strategies
for all files, so I just got rid of it.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-08-16 15:05:42 +02:00
Martin Feckie
cc4689deef
Add Glimmer template extensions to Oxide content detection (#14199)
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-08-15 09:34:19 -04:00
Philipp Spiess
fbf877aa0a
Fix Rust build by passing through RUSTUP_HOME variable (#14171)
While rebasing on the latest changes on `next`, especially #14160, I
noticed that my local `pnpm build` step was no longer working and erring
with the following:

```
│ > @tailwindcss/oxide@4.0.0-alpha.19 build /Users/philipp/dev/tailwindcss/crates/node
│ > npx napi build --platform --release --no-const-enum
│
│ Type Error: Could not parse the Cargo.toml: Error: Command failed: cargo metadata --format-version 1 --manifest-path "/Users/philipp/dev/
│ tailwindcss/crates/node/Cargo.toml"
│ error: rustup could not choose a version of cargo to run, because one wasn't specified explicitly, and no default is configured.
│ help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.
│
│ error: rustup could not choose a version of cargo to run, because one wasn't specified explicitly, and no default is configured.
│ help: run 'rustup default stable' to download the latest stable release of Rust and set it as your default toolchain.
```

It turns out that with the changes in turbo v2, env variables no longer
propagate to the individual tasks automatically but since I installed
rustup outside of the default `~/.rustup` directory, the task was no
longer able to find it.

To fix this, we now define `RUSTUP_HOME` as a global env to always pass
through.
2024-08-12 11:37:45 +02:00
Robin Malfait
f5f91ce9de
Prepare v4.0.0-alpha.19 (#14162)
Prepare next `4.0.0-alpha.19` release
2024-08-09 17:58:30 +02:00
Robin Malfait
d223112162
Bump dependencies (#14160)
This PR bumps dependencies

We also make some dependencies `catalog:` dependencies, which allows us
to keep
the version in sync. E.g.: `lightningcss` and `@types/node`.

Bumped `turbo` to the latest version + enabled the new UI

Fixed a bug in the tests now that `lightningcss` outputs the correct
value.
2024-08-09 16:12:24 +02:00
Robin Malfait
541d84a3bb
Add @source support (#14078)
This PR is an umbrella PR where we will add support for the new
`@source` directive. This will allow you to add explicit content glob
patterns if you want to look for Tailwind classes in other files that
are not automatically detected yet.

Right now this is an addition to the existing auto content detection
that is automatically enabled in the `@tailwindcss/postcss` and
`@tailwindcss/cli` packages. The `@tailwindcss/vite` package doesn't use
the auto content detection, but uses the module graph instead.

From an API perspective there is not a lot going on. There are only a
few things that you have to know when using the `@source` directive, and
you probably already know the rules:

1. You can use multiple `@source` directives if you want.
2. The `@source` accepts a glob pattern so that you can match multiple
files at once
3. The pattern is relative to the current file you are in
4. The pattern includes all files it is matching, even git ignored files
1. The motivation for this is so that you can explicitly point to a
`node_modules` folder if you want to look at `node_modules` for whatever
reason.
6. Right now we don't support negative globs (starting with a `!`) yet,
that will be available in the near future.

Usage example:

```css
/* ./src/input.css */
@import "tailwindcss";
@source "../laravel/resources/views/**/*.blade.php";
@source "../../packages/monorepo-package/**/*.js";
```

It looks like the PR introduced a lot of changes, but this is a side
effect of all the other plumbing work we had to do to make this work.
For example:

1. We added dedicated integration tests that run on Linux and Windows in
CI (just to make sure that all the `path` logic is correct)
2. We Have to make sure that the glob patterns are always correct even
if you are using `@import` in your CSS and use `@source` in an imported
file. This is because we receive the flattened CSS contents where all
`@import`s are inlined.
3. We have to make sure that we also listen for changes in the files
that match any of these patterns and trigger a rebuild.

PRs:

- [x] https://github.com/tailwindlabs/tailwindcss/pull/14063
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14085
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14079
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14067
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14076
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14080
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14127
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14135

Once all the PRs are merged, then this umbrella PR can be merged. 

> [!IMPORTANT]  
> Make sure to merge this without rebasing such that each individual PR
ends up on the main branch.

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-08-07 16:38:44 +02:00
Philipp Spiess
a2159e80f5
Add Windows CI (#14065)
This PR changes the GitHub action workflow for V4 to start running all
unit tests and build on both Ubuntu (our current default) _and_ Windows.
This is to ensure we catch issues with paths and other Windows-specific
things sooner. It does, however, not replace testing on Windows.
2024-07-29 16:50:06 +02:00
Adam Wathan
50a6a37dc9
Prepare for v4.0.0-alpha.18 release (#14057)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-25 10:19:13 -04:00