* replace `env.OXIDE` with global `__OXIDE__`
This will allow us to replace the `__OXIDE__` at build time, and fully
remove the branches from the final code so that there is not even any
reference to `@tailwindcss/oxide` on the stable engine.
* update changelog
* use `env.ENGINE` in integration tests
* drop oxide branching for the PostCSS plugin for now
This is currently a redirect to the same file, so doesn't hurt.
* Enable better dead-code elimination
* Update CLI tests
Fix indentation
* Fix indentation
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* try to use `config.default` before using `config`
* update changelog
* add quick `SHOW_OUTPUT` toggle for integration tests
Setting this to `true` shows the output of the executed commands.
* add integration tests for `tailwind.config.ts` and `tailwind.config.js` with ESM syntax
* add `jiti` and `detective-typescript` dependencies
* use `jiti` and `detective-typescript`
Instead of `detective`, this way we will be able to support
`tailwind.config.ts` files and `ESM` files.
* use `@swc/core` instead of the built-in `babel` form `jiti`
* update changelog
* add `jiti` and `detective-typescript` dependencies to `stable`
* use `sucrase` to transform the configs
* add `sucrase` dependency to `stable` engine
* make loading the config easier
* use abstracted loading config utils
* WIP: make `load` related files public API
* use new config loader in PostCSS plugin
* add list of default config files to look for
* cleanup unused arguments
* find default config path when using CLI
* improve `init` command
* make eslint happy
* keep all files in `stubs` folder
* add `tailwind.config.js` stub file
* Initialize PostCSS config using the same format as Tailwind config
* Rename config content stubs to config.*.js
* Improve option descriptions for init options
* Remove unused code, remove `constants` file
* Fix TS warning
* apply CLI changes to the Oxide version
* update `--help` output in CLI tests
* WIP: make tests work on CI
TODO: Test all combinations of `--full`, `--ts`, `--postcss`, and `--esm`.
* wip
* remove unused `fs`
* Fix init tests
Did you know you could pass an empty args to a command? No? Me neither. ¯\_(ツ)_/¯
* bump `napi-derive`
* list extensions we are interested in
* no-op the `removeFile` if file doesn't exist
* ensure all `init` flags work
* ensure we cleanup the new files
* test ESM/CJS generation based on package.json
* remove unnecessary test
We are not displaying output in the `--help` anymore based on whether
`type: module` is present or not.
Therefore this test is unneeded.
* only look for `TypeScript` files when the entryFile is `TypeScript` as well
* refactor `load` to be `loadConfig`
This will allow you to use:
```js
import loadConfig from 'tailwindcss/loadConfig'
let config = loadConfig("/Users/xyz/projects/my-app/tailwind.config.ts")
```
The `loadConfig` function will return the configuration object based on
the given absolute path of a tailwind configuration file.
The given path can be a CJS, an ESM or a TS file.
* use the `config.full.js` stub instead of the `defaultConfig.stub.js` file
The root `defaultConfig` is still there for backwards compatibilty
reasons. But the `module.exports = requrie('./config.full.js')` was
causing some problems when actually using tailwindcss.
So dropped it instead.
* apply `load` -> `loadConfig` changes to `Oxide` engine CLI
* ensure we write the config file in the Oxide engine
* improve type in Oxide engine CLI
* catch errors instead of checking if the file exists
A little smaller but just for tests so doesn't matter too much here 👍
* ensure we publish the correct stub files
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Nate Moore <nate@natemoo.re>
Co-authored-by: Enzo Innocenzi <enzo@innocenzi.dev>
* disable color opacity plugins by default for the `oxide` engine
* update tests to reflect this change in the `oxide` engine
* update changelog
* reflect changes in integration tests
* bump lightningcss
* use `lightningcss` in the main PostCss Plugin
* use lightningcss in our custom matchers
Now that we are using `lightningcss` and nesting in the new `oxide`
engine, the generated output _will_ be different in the majority of test
cases.
Using a combination of `prettier` and `lightningcss` will make the
output consistent.
The moment we are fully using the `oxide` engine, we can drop
`lightningcss` or `prettier` again to improve the performance of the
tests.
* update tests to apply `lightningcss` related changes
* update changelog
* add `lightningcss` and `browserslist` as dev dependencies to stable package.json
* only use `lightningcss` in tests (without prettier)
We will only fallback to prettier if lightningcss fails somehow.
* apply side effect chagnes due to only using lightningcss for tests
* make CI happy (integration tests)
Apply changes to integration tests now that we are using lightningcss
* transform `lightningcss` for Node 12 when running tests
* run prettier on failing tests for `toMatchFormattedCss`
This will result in better diffs because diffs are typically per block
and/or per line. But lightningcss will simplify certain selectors and
the diff won't be as clear.
We will only apply the prettier formatting for failing tests in the diff
view so that diffs are cleaner and we don't pay for the additional
prettier calls when tests pass.
* temporarily disable workflows
* add oxide
Our Rust related parts
* use oxide
- Setup the codebase to be able to use the Rust parts based on an
environment variable: `OXIDE=1`.
- Setup some tests that run both the non-Rust and Rust version in the
same test.
- Sort the candidates in a consistent way, to guarantee the order for
now (especially in tests).
- Reflect sorting related changes in tests.
- Ensure tests run in both the Rust and non-Rust version. (Some tests
are explicitly skipped when using the Rust version since we haven't
implemented those features yet. These include: custom prefix,
transformers and extractors).
- `jest`
-`OXIDE=1 jest`
* remove into_par_iter where it doesn't make sense
* cargo fmt
* wip
* enable tracing based on `DEBUG` env
* improve CI for the Oxide build
* sort test output
This happened because the sorting happens in this branch, but changes
happened on the `master` branch.
* add failing tests
I noticed that some of the tests were failing, and while looking at
them, it happened because the tests were structured like this:
```html
<div
class="
backdrop-filter
backdrop-filter-none
backdrop-blur-lg
backdrop-brightness-50
backdrop-contrast-0
backdrop-grayscale
backdrop-hue-rotate-90
backdrop-invert
backdrop-opacity-75
backdrop-saturate-150
backdrop-sepia
"
></div>
```
This means that the class names themselves eventually end up like this: `backdrop-filter-none\n`
-> (Notice the `\n`)
/cc @thecrypticace
* fix range to include `\n`
* Include only unique values for tests
Really, what we care about most is that the list contains every expected candidate. Not necessarily how many times it shows up because while many candidates will show up A LOT in a source text we’ll unique them before passing them back to anything that needs them
* Fix failing tests
* Don’t match empty arbitrary values
* skip tests in oxide mode regarding custom separators in arbitrary variants
* re-enable workflows
* use `@tailwindcss/oxide` dependency
* publish `tailwindcss@oxide`
* drop prepublishOnly
I don't think we actually need this anymore (or even want because this
is trying to do things in CI that we don't want to happen. Aka, build
the Oxide Rust code, it is already a dependency).
* WIP
* Defer to existing CLI for Oxide
* Include new compiled typescript stuff when publishing
* Move TS to ./src/oxide
* Update scripts
* Clean up tests for TS
* copy `cli` to `oxide/cli`
* make CLI files TypeScript files
* drop --postcss flag
* setup lightningcss
* Remove autoprefixer and cssnano from oxide CLI
* cleanup Rust code a little bit
- Drop commented out code
- Drop 500 fixture templates
* sort test output
* re-add `prepublishOnly` script
* bump SWC dependencies in package-lock.json
* pin `@swc` dependencies
* ensure to install and build oxide
* update all GitHub Workflows to reflect Oxide required changes
* sort `content-resolution` integration tests
* add `Release Insiders — Oxide`
* setup turbo repo + remote caching
* use `npx` to invoke `turbo`
* setup unique/proper package names for integration tests
* add missing `isomorphic-fetch` dependency
* setup integration tests to use `turborepo`
* scope tailwind tasks to root workspace
* re-enable `node_modules` cache for integration tests
* re-enable `node_modules` cache for main CI workflow
* split cache for `main` and `oxide` node_modules
* fix indent
* split install dependencies so that they can be cached individually
* improve GitHub actions caching
* use correct path for oxide node_modules (crates/node)
* ensure that `cargo install` always succeeds
cargo install X, on CI will fail if it already exists.
* figure out integration tests with turbo
* tmp: use `npm` instead of `turbo`
* disable `fail-fast`
This will allow us to run integration tests so that it still caches the
succesful ones.
* YAML OH YAML, Y U WHITESPACE SENSITIVE
* copy the oxide-ci workflow to release-oxide
* make `oxide-ci` a normal CI workflow
Without publishing
* try to cache cargo and node_modules for the oxide build
* configure turbo to run scripts in the root
* explicitly skip failing test for the Oxide version
* run oxide tests in CI
* only use build script for root package
* sync package-lock.json
* do not cache node_modules for each individual integration
* look for hoisted `.bin`
* use turbo for caching build tailwind css in integration tests
* Robin...
* try to use the local binary first
* skip installing integration test dependencies
Should already be installed due to workspace usage
* Robin...
* drop `output.clean`
* explicitly add `mini-css-extract-plugin`
* drop oxide-ci, this is tested by proxy
* ensure oxide build is used in integration tests
This will ensure the `@tailwindcss/oxide` dependency is available
(whether we use it or not).
* setup Oxide shim in insiders release
* add browserslist dependency
* use `install:all` script name
Just using `install` as a script name will be called when running
`npm install`.
Now that we marked the repo as a `workspace`, `npm install` will run
install in all workspaces which is... not ideal.
* tmp: enable insiders release in PRs
Just to check if everything works before merging. Can be removed once
tested.
* don't cache node_modules?
I feel there is some catch 22 going on here.
We require `npm install` to build the `oxide/crates/node` version.
But we also require `oxide/crates/node` for the `npm install` becaus of
the dependency: `"@tailwindcss/oxide": "file:oxide/creates/node"`
* try to use `oxide/crates/node` as part of the workspace
* let's think about this
Let's try and cache the `node_modules` and share as much as possible.
However, some scripts still need to be installed specific to the OS.
Running `npm install` locally doesn't throw away your `node_modules`,
so if we just cache `node_modules` but also run `npm install` that
should keep as much as possible and still improve install times since
`node_modules` is already there.
I think.
* ensure generated `index.js` and `index.d.ts` files are considered outputs
* use `npx napi` instead of `napi` directly
* include all `package-lock.json` files
* normalize caching further in all workflows
* drop nested `package-lock.json` files
* `npm uninstall mini-css-extract-plugin && npm install mini-css-extract-plugin --save-dev`
* bump webpack-5 integration tests dependencies
* only release insiders on `master` branch
* tmp: let's figure out release insiders oxide
* fix little typo
* use Node 18 for Oxide Insiders
* syncup package-lock.json
* let's try node 16
Node 18 currently fails on `Build x86_64-unknown-linux-gnu (OXIDE)`
Workflow.
Install Node.JS output:
```
Environment details
Warning: /__t/node/18.13.0/x64/bin/node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /__t/node/18.13.0/x64/bin/node)
/__t/node/18.13.0/x64/bin/node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /__t/node/18.13.0/x64/bin/node)
/__t/node/18.13.0/x64/bin/node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /__t/node/18.13.0/x64/bin/node)
/__t/node/18.13.0/x64/bin/node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /__t/node/18.13.0/x64/bin/node)
/__t/node/18.13.0/x64/bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /__t/node/18.13.0/x64/bin/node)
/__t/node/18.13.0/x64/bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /__t/node/18.13.0/x64/bin/node)
Warning: node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by node)
node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by node)
```
* bump some Node versions
* only release oxide insiders on `master` branch
* don't cache `npm`
* bump napi-rs
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Record and watch PostCSS dependencies in the CLI
* ensure `changedContent` gets cleared
Otherwise this list gets bigger and bigger, not only that there is a
subtle bug. The moment you save a `.css` file we want to create a new
context and start from scratch. However, since the list was never
cleared, it meant that every subsequent save to *any* file (not only
config / css files) creates a new context...
By clearing the least we should work around this problem.
* add test that verifies an odd bug
The story goes like this:
1. add `underline` to html file
-> css contains `underline` rule
2. add `font-bold` to html file
-> css contains `underline` and `font-bold`
3. remove `underline` from html file
-> css still contains `underline` and `font-bold` for performance reasons
4. Save a css file (! RED FLAG)
-> css contains `font-bold` because we started from scratch
5. add `underline` to html file
-> css contains `underline` and `font-bold`
6. remove `underline` from html file
-> css only contains `font-bold`... (UH OH)
This is because the moment we did step 4, every single save in any file created a new context. Every. Single. Time.
* use a property that doesn't require `autoprefixer`
* update changelog
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* update changelog
* ensure `--content` is taken into account
* cleanup tests
- Use `rm` instead of deprecated `rmdir`
- Type the returnType correctly
* use a file not included in `content` of your tailwind.config.js file
* Update lockfile
* Tweak formatting
* Refactor content path parsing
* Allow resolving content paths relative to the config file
* Include resolved symlinks as additional content paths
* Update changelog
* Work on suite of tests for content resolution
* reformat integration test list
* Move content resolution tests to integration
* Update future and experimental types
* Add support for postcss-import in watch mode
* Add regression test
* Extract shared logic
* restructure test a little bit
Instead of relying on a arbitrary setTimout value, let's wait for the
file to be created instead.
* update changelog
Co-authored-by: Adam Bergman <adam@fransvilhelm.com>
* Add content glob integration tests
* Use tagged version in parcel integration tests
* Upgrade postcss-cli integration tests
* upgrade integration test deps
* Fix CS
* Fix tests
* Update lockfile
* Fix vite test in CI
* add generate-types script
This script will generate the full list of core plugins, which will
allow you to get code completion for the `corePlugins` section.
It will also generate all the colors (and deprecated colors) which is
used in multiple places in the config.
* add types for the `tailwind.config.js` config file
* annotate stubs with a JSDoc pointing to the types
* add types to package.json
- Updated the files to make sure that the types are being published
- Add a `types` section in the `package.json`, otherwise your editor by
default will look for the `DefinitelyTyped` types which got me really
confused for a second.
- Added some scripts to make sure that the generation of types happens
when needed (before tests and before building). This way you never
ever have to think about generating them when working on Tailwind CSS
internals.
* re-export types top-level
Having a `colors.d.ts` next to the `colors.js` file allows us to type
the `colors.js` file and your editor will pickup the types from
`colors.d.ts`.
* also publish generated types
* update changelog
* enable TypeScript only when using `init --types` for now
* update tests to verify that `--types` works
* add prettier-plugin-tailwindcss
This will use the prettier plugin in our tests as well, yay consistency!
* ensure that both `group` and `peer` can't be used in `@apply`
This was only configured for `group`
* expose `sortClassList` on the context
This function will be used by the `prettier-plugin-tailwindcss` plugin,
this way the sorting happens within Tailwind CSS itself adn the
`prettier-plugin-tailwindcss` plugin doesn't have to use internal /
private APIs.
The signature looks like this:
```ts
function sortClassList(classes: string[]): string[]
```
E.g.:
```js
let sortedClasses = context.sortClassList(['p-1', 'm-1', 'container'])
```
* update changelog
* add sort test for utilities with the important modifier e.g.: `!p-4`
* use outputFile instead of direct writeFile
This is an improvement we introduced earlier but forgot this part.
* allow to pipe in data to the CLI
* add integration tests to validate piping to the CLI
* update changelog
* use String.raw for css escapes
This will allow us to write code like:
```css
.mobile\:font-bold {}
```
Instead of
```css
.mobile\\:font-bold {}
```
Which resembles "real" css way better in our tests.
* use String.raw in integration tests as well
* enabled `optimizeUniversalDefaults` by default
This PR is done in a way so that the default is set to `true`, but you
can still disable it if it causes issues. In this case we do appreciate
an issue in that case 😅.
* update tests to use optimized universal selector
* update integration tests
* add dedicated tests for the optimized universal selector
* improve minimumImpactSelector algorithm
I think I cracked the algorithm, but I will probably need another pair
of eyes on the subject.
The current implementation works like this:
Prerequisites:
- The selector should already have been parsed using the selectorParser
from 'postcss-selector-parser'.
Algorithm:
1. Remove all of the pseudo classes from the list of nodes.
1.1. We do want to keep pseudo elements (E.g.: `::before`, `::first-line`, ...)
1.2. We do want to keep pseudo classes that contain nodes (E.g.:
`:not(...)`)
2. Reverse the list of nodes.
This will make it easier to search from the end to the start. For
example `.group:hover .group-hover` should result in `.group-hover`
not `.group`.
2.1. Find the index of the best match (class, id, attribute), and
convert the node if required. (E.g.: `span#app` -> `#app` => `[id="app"]`)
2.2. Remove the rest of the selector that is not important anymore
2.3. Re-join the left-over nodes together
* update tests using new algorithm
* also look for `tag` types
* take `tag` into account
* simplify logic
* add test to prove `rest.reverse()` in first case is required
In case we don't find a match (idx === -1), we use `rest.reverse()`.
However, it looks like you can just use `nodes` instead.
This is not entirely true, because the `rest` variable will contain only
the nodes that are not pseudo elements.
`*:hover` would result in `*:hover` instead of just `*`
* replace all nodes after > with a single universal selector
* immediately take the `safelist` values into account
Currently we had to manually add them in the `setupTrackingContext`,
`setupWatchingContext` and the `cli`.
This was a bit cumbersome, because the `safelist` function (to resolve
regex patterns) was implemented on the context. This means that we had
to do something like this:
```js
let changedContent = []
let context = createContext(config, changedContent)
for (let content of context.safelist()) {
changedContent.push(content)
}
```
This just feels wrong in general, so now it is handled internally for
you which means that we can't mess it up anymore in those 3 spots.
* drop the dot from the extension
Our transformers and extractors are implemented for `html` for example.
However the `path.extname()` returns `.html`.
This isn't an issue by default, but it could be for with custom
extractors / transformers.
* normalize the configuration
* make shared cache local per extractor
* ensure we always have an `extension`
Defaults to `html`
* splitup custom-extractors test
* update old config structure to new structure
* ensure we validate the "old" structure, and warn if invalid
* add tests with "old" config, to ensure it keeps working
* add missing `content` object
* inline unnecessary function abstraction
* setup integration tests
* fix rgb color syntax
* ensure integration tests always exit
If for any reason the integration tests fail, then it will run forever
on CI (~2hours or something). The `--forceExit` is not ideal but it will
prevent long running processes.
* fix incorrect test
We were never properly waiting for the command to finish.
* handle AbortError properly
In CI, when an AbortController gets aborted an error is thrown
(AbortError). If we don't catch it properly then it will "leak" and the
test will fail.
* improve IO functions
* quit integration tests after 10seconds
* only test a few integrations
* test all integrations using matrix
This will cancel other builds when one fails, it will also separate the
output per integration which can be useful especially now that we are
still figuring things out.
* rename `build` to `test`
* add --verbose flag to receive output in the console
* when reading stdout or stderr, wait a certain about to ensure stability
Debouncing for 200ms means that if another message comes in within those
200ms we delay the execution of the callback.
* simplify workflow
* use terminal output instead of disk events
* cache node_modules for integrations
* empty commit, to test cache hits
* make `jit` mode the default when no mode is specified
* unify JIT and AOT codepaths
* ensure `Object.entries` on undefined doesn't break
It could be that sometimes you don't have values in your config (e.g.: `presets: []`), this in turn will break some plugins where we assume we have a value.
* drop AOT specific tests
These tests are all covered by JIT mode already and were AOT specific.
* simplify tests, and add a few
Some of the tests were written for AOT specifically, some were missing. We also updated the way we write those tests, essentially making Tailwind a blackbox, by testing against the final output.
Now that JIT mode is the default, this is super fast because we only generate what is used, instead of partially testing in a 3MB file or building it all, then purging.
* add some todo's to make sure we warn in a few cases
* make `darkMode: 'media'`, the default
This also includes moving dark mode tests to its own dedicated file.
* remove PostCSS 7 compat mode
* update CLI to be JIT-first
* fix integration tests
This is not a _real_ fix, but it does solve the broken test for now.
* warn when using @responsive or @variants
* remove the JIT preview warning
* remove AOT-only code paths
* remove all `mode: 'jit'` blocks
Also remove `variants: {}` since they are not useful in `JIT` mode
anymore.
* drop unused dependencies
* rename `purge` to `content`
* remove static CDN builds
* mark `--purge` as deprecated in the CLI
This will still work, but a warning will be printed and it won't show up
in the `--help` output.
* cleanup nesting plugin
We don't have to duplicate it anymore since there is no PostCSS 7
version anymore.
* make sure integration tests run in band
* cleanup folder structure
* make sure nesting folder is available
* simplify resolving of purge/content information
* update (old) incorrect snapshots
The version changed, so it is save to update these.
* add `shadow` so that we can test `@tailwind base`
We were only using `font-bold`, but that doesn't require any base rules.
We try to only inject rules that are required, even for `base` related
rules.
Adding `shadow` will ensure that we can test that `base` rules have been
added.
* use `~/.cache/tailwindcss` as default touch dir
When more tools catch up with the latest postcss dependency tracking,
then we probably don't even need this anymore. However, it is a good
practice to put (global) caches in ~/.cache and (global) configs in
~/.config
Fixes: #4569
* change test to verify @tailwind base slightly
Because of some changes in tailwind itself, the base selector contains a
ton of new --tw-* custom properties. Keeping this up to date might be a
bit of an annoying challenge. So instead we now check for the selector
to be present.
* add `tmp` package
* use a (simple) temporary file, instead of a full cache dir
* add tests for the --postcss option in the new CLI
* add `oneOf` ability to the `arg()` functionality
By default, `arg()` doesn't have a way to define multiple types. We want
the possibility of using `--postcss` (Boolean) or `--postcss
./custom-path.js`. But by default this is not possible.
This commit will allow us to do a few things, mainly:
- Keep the same API using the `{ type: oneOf(String, Boolean), description: '...' }`
- Keep the `--help` output similar
What we did behind the scenes is make sure to put the non recognized
flags in the `_` arguments list. This is possible by doing `permissive:
true`. We then manually parse those and resolve the correct value.
* ensure that we can use a custom `--postcss ./with-custom-path.js`
* fix --help output in tests
* add tests to ensure we can use `purge.safelist`
* implement the `purge.safelist` for strings
* proxy `purge.safelist` to `purge.options.safelist`
This allows us to have a similar API in `AOT` and `JIT` mode.
* only proxy `purge.safelist` to `purge.options.safelist` if
`purge.options.safelist` doesn't exists yet.
* remove unused file
using syntax.js instead
* add a way to remove files that are generated from the tests
Essentially setting the restore cache contents to `null` as a special
value.
* combine the stdout and stderr output
* add jest-diff instead of relying on it existing *somewhere*
This also came with a small API change.
* add `--runInBand` to the test script
* add dedicated cli tests for the new Tailwind CLI