mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
remove v3 codebase
This commit is contained in:
parent
4429ab8010
commit
32cf8aa0fb
@ -1,9 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
@ -1,9 +0,0 @@
|
||||
/cli
|
||||
/lib
|
||||
/docs
|
||||
/peers
|
||||
/tests/fixtures/cli-utils.js
|
||||
/stubs/*
|
||||
/src/corePluginList.js
|
||||
/oxide/crates/node/index.js
|
||||
/oxide/crates/node/index.d.ts
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": ["prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"camelcase": ["error", { "allow": ["^unstable_"] }],
|
||||
"no-unused-vars": [2, { "args": "all", "argsIgnorePattern": "^_" }],
|
||||
"no-warning-comments": 0,
|
||||
"prettier/prettier": "error"
|
||||
}
|
||||
}
|
||||
10
.github/CODE_OF_CONDUCT.md
vendored
10
.github/CODE_OF_CONDUCT.md
vendored
@ -1,10 +0,0 @@
|
||||
# Tailwind CSS Community Guidelines
|
||||
|
||||
The following community guidelines are based on [The Ruby Community Conduct Guidelines](https://www.ruby-lang.org/en/conduct/).
|
||||
|
||||
This document provides community guidelines for a respectful, productive, and collaborative place for any person who is willing to contribute to the Tailwind CSS project. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.).
|
||||
|
||||
- Participants will be tolerant of opposing views.
|
||||
- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
||||
- When interpreting the words and actions of others, participants should always assume good intentions.
|
||||
- Behaviour which can be reasonably considered harassment will not be tolerated.
|
||||
34
.github/CONTRIBUTING.md
vendored
34
.github/CONTRIBUTING.md
vendored
@ -1,34 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for your interest in contributing to Tailwind CSS! Please take a moment to review this document **before submitting a pull request**.
|
||||
|
||||
## Pull requests
|
||||
|
||||
**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 [a feature request](https://github.com/tailwindlabs/tailwindcss/discussions/new?category=ideas) to first discuss any significant new ideas. This includes things like adding new utilities, creating new at-rules, etc.
|
||||
|
||||
## Coding standards
|
||||
|
||||
Our code formatting rules are defined in [.eslintrc](https://github.com/tailwindcss/tailwindcss/blob/master/.eslintrc.json). You can check your code against these standards by running:
|
||||
|
||||
```sh
|
||||
npm run style
|
||||
```
|
||||
|
||||
To automatically fix any style violations in your code, you can run:
|
||||
|
||||
```sh
|
||||
npm run style -- --fix
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
You can run the test suite using the following commands:
|
||||
|
||||
```sh
|
||||
npm run build && npm test
|
||||
```
|
||||
|
||||
Please ensure that the tests are passing when submitting a pull request. If you're adding new features to Tailwind, please include tests.
|
||||
|
||||
59
.github/workflows/ci-stable.yml
vendored
59
.github/workflows/ci-stable.yml
vendored
@ -1,59 +0,0 @@
|
||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: CI — Stable
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master, 3.3, 3.4]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
CACHE_PREFIX: stable
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14, 18]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Use the `stable` engine
|
||||
run: |
|
||||
node ./scripts/swap-engines.js
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
npm run test || \
|
||||
npm run test || \
|
||||
npm run test || exit 1
|
||||
|
||||
- name: Lint
|
||||
run: npm run style
|
||||
76
.github/workflows/ci.yml
vendored
76
.github/workflows/ci.yml
vendored
@ -1,76 +0,0 @@
|
||||
name: CI — Oxide
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, 3.3, 3.4]
|
||||
pull_request:
|
||||
branches: [master, 3.3, 3.4]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
CACHE_PREFIX: oxide
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npx turbo run build --filter=//
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
npx turbo run test --filter=// || \
|
||||
npx turbo run test --filter=// || \
|
||||
npx turbo run test --filter=// || exit 1
|
||||
|
||||
- name: Lint
|
||||
run: npx turbo run style --filter=//
|
||||
85
.github/workflows/integration-tests-oxide.yml
vendored
85
.github/workflows/integration-tests-oxide.yml
vendored
@ -1,85 +0,0 @@
|
||||
name: Integration Tests — Oxide
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, 3.3, 3.4]
|
||||
pull_request:
|
||||
branches: [master, 3.3, 3.4]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
CACHE_PREFIX: oxide
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
integration:
|
||||
- content-resolution
|
||||
- parcel
|
||||
- postcss-cli
|
||||
- rollup
|
||||
- rollup-sass
|
||||
- tailwindcss-cli
|
||||
- vite
|
||||
- webpack-4
|
||||
- webpack-5
|
||||
node-version: [18]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npx turbo run build --filter=//
|
||||
|
||||
- name: Test ${{ matrix.integration }}
|
||||
run: |
|
||||
npx turbo run test --filter=./integrations/${{ matrix.integration }} || \
|
||||
npx turbo run test --filter=./integrations/${{ matrix.integration }} || \
|
||||
npx turbo run test --filter=./integrations/${{ matrix.integration }} || exit 1
|
||||
83
.github/workflows/integration-tests-stable.yml
vendored
83
.github/workflows/integration-tests-stable.yml
vendored
@ -1,83 +0,0 @@
|
||||
name: Integration Tests — Stable
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, 3.3, 3.4]
|
||||
pull_request:
|
||||
branches: [master, 3.3, 3.4]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
CACHE_PREFIX: stable
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
integration:
|
||||
- content-resolution
|
||||
- parcel
|
||||
- postcss-cli
|
||||
- rollup
|
||||
- rollup-sass
|
||||
- tailwindcss-cli
|
||||
- vite
|
||||
- webpack-4
|
||||
- webpack-5
|
||||
node-version: [18]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Use the `stable` engine
|
||||
run: |
|
||||
node ./scripts/swap-engines.js
|
||||
|
||||
- name: Cache node_modules (tailwindcss)
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-${{ hashFiles('package-lock.json') }}
|
||||
|
||||
- name: Cache node_modules (integrations)
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./integrations/node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-integrations-${{ hashFiles('./integrations/package-lock.json') }}
|
||||
|
||||
- name: Cache node_modules (integration)
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ./integrations/${{ matrix.integration }}/node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-${{ env.CACHE_PREFIX }}-node_modules-integrations-${{ matrix.integration }}-${{ hashFiles('./integrations/${{ matrix.integration }}/package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Install dependencies (shared integrations)
|
||||
run: npm install --prefix ./integrations
|
||||
|
||||
- name: Install dependencies (integration)
|
||||
run: npm install --prefix ./integrations/${{ matrix.integration }}
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test ${{ matrix.integration }}
|
||||
run: |
|
||||
npm run test --prefix ./integrations/${{ matrix.integration }} || \
|
||||
npm run test --prefix ./integrations/${{ matrix.integration }} || \
|
||||
npm run test --prefix ./integrations/${{ matrix.integration }} || exit 1
|
||||
89
.github/workflows/prepare-release.yml
vendored
89
.github/workflows/prepare-release.yml
vendored
@ -1,89 +0,0 @@
|
||||
name: Prepare Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: write # for softprops/action-gh-release to create GitHub release
|
||||
|
||||
runs-on: macos-11
|
||||
timeout-minutes: 15
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: git fetch --tags -f
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "TAG_NAME=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
|
||||
|
||||
- name: Get release notes
|
||||
run: |
|
||||
RELEASE_NOTES=$(node ./scripts/release-notes.js)
|
||||
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
|
||||
echo "$RELEASE_NOTES" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Use the `stable` engine
|
||||
run: |
|
||||
node ./scripts/swap-engines.js
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Install standalone cli dependencies
|
||||
run: npm install
|
||||
working-directory: standalone-cli
|
||||
|
||||
- name: Build standalone cli
|
||||
run: npm run build
|
||||
working-directory: standalone-cli
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
npm test || \
|
||||
npm test || \
|
||||
npm test || exit 1
|
||||
working-directory: standalone-cli
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
tag_name: ${{ env.TAG_NAME }}
|
||||
body: |
|
||||
${{ env.RELEASE_NOTES }}
|
||||
files: |
|
||||
standalone-cli/dist/tailwindcss-linux-arm64
|
||||
standalone-cli/dist/tailwindcss-linux-armv7
|
||||
standalone-cli/dist/tailwindcss-linux-x64
|
||||
standalone-cli/dist/tailwindcss-macos-arm64
|
||||
standalone-cli/dist/tailwindcss-macos-x64
|
||||
standalone-cli/dist/tailwindcss-windows-x64.exe
|
||||
standalone-cli/dist/tailwindcss-windows-arm64.exe
|
||||
423
.github/workflows/release-insiders-oxide.yml
vendored
423
.github/workflows/release-insiders-oxide.yml
vendored
@ -1,423 +0,0 @@
|
||||
name: Release Insiders — Oxide
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
env:
|
||||
APP_NAME: tailwindcss-oxide
|
||||
NODE_VERSION: 16
|
||||
OXIDE_LOCATION: ./oxide/crates/node
|
||||
RELEASE_CHANNEL: oxide-insiders
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Windows
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
# Mac OS
|
||||
- os: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
strip: strip -x # Must use -x on macOS. This produces larger results on linux.
|
||||
|
||||
name: Build ${{ matrix.target }} (OXIDE)
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ env.NODE_VERSION }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: ${{ matrix.target }}
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
if: ${{ matrix.strip }}
|
||||
run: ${{ matrix.strip }} ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-${{ matrix.target }}
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ matrix.binary }}
|
||||
|
||||
build-apple-silicon:
|
||||
name: Build Apple Silicon (OXIDE)
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add aarch64-apple-darwin
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: aarch64-apple-darwin
|
||||
JEMALLOC_SYS_WITH_LG_PAGE: 14
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
run: strip -x ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-aarch64-apple-darwin
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ env.APP_NAME }}
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
strip: strip
|
||||
image: docker.io/centos/nodejs-14-centos7
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
strip: aarch64-linux-gnu-strip
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
setup: apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu -y
|
||||
- target: armv7-unknown-linux-gnueabihf
|
||||
strip: arm-linux-gnueabihf-strip
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
setup: apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
|
||||
- target: aarch64-unknown-linux-musl
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
strip: aarch64-linux-musl-strip
|
||||
- target: x86_64-unknown-linux-musl
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
strip: strip
|
||||
|
||||
name: Build ${{ matrix.target }} (OXIDE)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ env.NODE_VERSION }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup cross compile toolchain
|
||||
if: ${{ matrix.setup }}
|
||||
run: ${{ matrix.setup }}
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: ${{ matrix.target }}
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
if: ${{ matrix.strip }}
|
||||
run: ${{ matrix.strip }} ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-${{ matrix.target }}
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ env.APP_NAME }}
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
name: Build and release
|
||||
needs:
|
||||
- build
|
||||
- build-linux
|
||||
- build-apple-silicon
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Cache the `oxide` Rust build
|
||||
- name: Cache oxide build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
./oxide/target/
|
||||
./oxide/crates/node/*.node
|
||||
./oxide/crates/node/index.js
|
||||
./oxide/crates/node/index.d.ts
|
||||
key: ${{ runner.os }}-oxide-${{ hashFiles('./oxide/crates/**/*') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: ${{ env.OXIDE_LOCATION }}
|
||||
|
||||
- run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} > ~/.npmrc
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Move artifacts
|
||||
run: |
|
||||
cd ${{ env.OXIDE_LOCATION }}
|
||||
cp bindings-aarch64-apple-darwin/oxide/crates/node/* ./npm/darwin-arm64/
|
||||
cp bindings-aarch64-unknown-linux-gnu/oxide/crates/node/* ./npm/linux-arm64-gnu/
|
||||
cp bindings-aarch64-unknown-linux-musl/oxide/crates/node/* ./npm/linux-arm64-musl/
|
||||
cp bindings-armv7-unknown-linux-gnueabihf/oxide/crates/node/* ./npm/linux-arm-gnueabihf/
|
||||
cp bindings-x86_64-apple-darwin/* ./npm/darwin-x64/
|
||||
cp bindings-x86_64-pc-windows-msvc/* ./npm/win32-x64-msvc/
|
||||
cp bindings-x86_64-unknown-linux-gnu/oxide/crates/node/* ./npm/linux-x64-gnu/
|
||||
cp bindings-x86_64-unknown-linux-musl/oxide/crates/node/* ./npm/linux-x64-musl/
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "NPM_VERSION=0.0.0-${{ env.RELEASE_CHANNEL }}.$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate entry point
|
||||
run: npm run build --prefix ${{ env.OXIDE_LOCATION }}
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
for pkg in ${{ env.OXIDE_LOCATION }}/npm/*; do
|
||||
echo "Publishing $pkg..."
|
||||
cd $pkg
|
||||
npm version ${{ env.NPM_VERSION }} --force --no-git-tag-version
|
||||
npm publish --tag ${{ env.RELEASE_CHANNEL }} --access public
|
||||
cd -
|
||||
done
|
||||
|
||||
echo "Publishing ${{ env.APP_NAME }}...";
|
||||
cd ${{ env.OXIDE_LOCATION }}
|
||||
npm version ${{ env.NPM_VERSION }} --force --no-git-tag-version
|
||||
sed "s#\"0.0.0\"#\"${{ env.NPM_VERSION }}\"#g" package.json > package_updated.json
|
||||
mv package_updated.json package.json
|
||||
npm publish --tag ${{ env.RELEASE_CHANNEL }} --access public
|
||||
cd -
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
tailwind_oxide_release:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
name: Build and release Tailwind CSS
|
||||
|
||||
needs:
|
||||
- release
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "SHA_SHORT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
echo "OXIDE_NPM_VERSION=0.0.0-${{ env.RELEASE_CHANNEL }}.$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup `@tailwindcss/oxide` version
|
||||
run: |
|
||||
sed "s#\"@tailwindcss/oxide\": \".*\"#\"@tailwindcss/oxide\": \"${{ env.OXIDE_NPM_VERSION }}\"#" package.json > package_updated.json
|
||||
mv package_updated.json package.json
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
npm test || \
|
||||
npm test || \
|
||||
npm test || exit 1
|
||||
|
||||
- name: 'Version based on commit: 0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }}'
|
||||
run: npm version 0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }} --force --no-git-tag-version
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --tag ${{ env.RELEASE_CHANNEL }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
# !! Enable this, once we are cleaning up all the `stable` engine related files.
|
||||
#
|
||||
# - name: Trigger Tailwind Play update
|
||||
# uses: actions/github-script@v6
|
||||
# with:
|
||||
# github-token: ${{ secrets.TAILWIND_PLAY_TOKEN }}
|
||||
# script: |
|
||||
# await github.rest.actions.createWorkflowDispatch({
|
||||
# owner: 'tailwindlabs',
|
||||
# repo: 'play.tailwindcss.com',
|
||||
# ref: 'master',
|
||||
# workflow_id: 'upgrade-tailwindcss.yml',
|
||||
# inputs: {
|
||||
# insidersVersion: '0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }}'
|
||||
# }
|
||||
# })
|
||||
78
.github/workflows/release-insiders-stable.yml
vendored
78
.github/workflows/release-insiders-stable.yml
vendored
@ -1,78 +0,0 @@
|
||||
name: Release Insiders — Stable
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
CACHE_PREFIX: stable
|
||||
NODE_VERSION: 16
|
||||
RELEASE_CHANNEL: insiders
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Use the `stable` engine
|
||||
run: |
|
||||
node ./scripts/swap-engines.js
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-${{ env.CACHE_PREFIX }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
npm run test || \
|
||||
npm run test || \
|
||||
npm run test || exit 1
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "SHA_SHORT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: 'Version based on commit: 0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }}'
|
||||
run: npm version 0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }} --force --no-git-tag-version
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --tag ${{ env.RELEASE_CHANNEL }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Trigger Tailwind Play update
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.TAILWIND_PLAY_TOKEN }}
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: 'tailwindlabs',
|
||||
repo: 'play.tailwindcss.com',
|
||||
ref: 'master',
|
||||
workflow_id: 'upgrade-tailwindcss.yml',
|
||||
inputs: {
|
||||
insidersVersion: '0.0.0-${{ env.RELEASE_CHANNEL }}.${{ env.SHA_SHORT }}'
|
||||
}
|
||||
})
|
||||
337
.github/workflows/release-oxide.yml
vendored
337
.github/workflows/release-oxide.yml
vendored
@ -1,337 +0,0 @@
|
||||
name: Release — Oxide
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
APP_NAME: tailwindcss-oxide
|
||||
NODE_VERSION: 14
|
||||
OXIDE_LOCATION: ./oxide/crates/node
|
||||
|
||||
jobs:
|
||||
oxide-build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Windows
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
# Mac OS
|
||||
- os: macos-latest
|
||||
target: x86_64-apple-darwin
|
||||
strip: strip -x # Must use -x on macOS. This produces larger results on linux.
|
||||
|
||||
name: Build ${{ matrix.target }} (OXIDE)
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
# - name: Use cached oxide node_modules
|
||||
# id: cache-oxide
|
||||
# uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ${{ env.OXIDE_LOCATION }}/node_modules
|
||||
# key: nodeModules-${{ hashFiles('${{ env.OXIDE_LOCATION }}/package-lock.json') }}-${{ matrix.os }}-${{ matrix.target }}-${{ env.NODE_VERSION }}
|
||||
# restore-keys: |
|
||||
# nodeModules-
|
||||
|
||||
- name: Oxide — npm install
|
||||
# if: steps.cache-oxide.outputs.cache-hit != 'true'
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: ${{ matrix.target }}
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
if: ${{ matrix.strip }}
|
||||
run: ${{ matrix.strip }} ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-${{ matrix.target }}
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ matrix.binary }}
|
||||
|
||||
oxide-build-apple-silicon:
|
||||
name: Build Apple Silicon (OXIDE)
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-${{ matrix.node-version }}-node_modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
# Cargo already skips downloading dependencies if they already exist
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/bin/
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('./oxide/**/Cargo.lock') }}
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add aarch64-apple-darwin
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: aarch64-apple-darwin
|
||||
JEMALLOC_SYS_WITH_LG_PAGE: 14
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
run: strip -x ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-aarch64-apple-darwin
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ env.APP_NAME }}
|
||||
|
||||
oxide-build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
strip: strip
|
||||
image: docker.io/centos/nodejs-14-centos7
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
strip: aarch64-linux-gnu-strip
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
setup: apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu -y
|
||||
- target: armv7-unknown-linux-gnueabihf
|
||||
strip: arm-linux-gnueabihf-strip
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
setup: apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
|
||||
- target: aarch64-unknown-linux-musl
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
strip: aarch64-linux-musl-strip
|
||||
- target: x86_64-unknown-linux-musl
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
strip: strip
|
||||
|
||||
name: Build ${{ matrix.target }} (OXIDE)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.JS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Setup cross compile toolchain
|
||||
if: ${{ matrix.setup }}
|
||||
run: ${{ matrix.setup }}
|
||||
|
||||
- name: Setup rust target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
# - name: Use cached oxide node_modules
|
||||
# id: cache-oxide
|
||||
# uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ${{ env.OXIDE_LOCATION }}/node_modules
|
||||
# key: nodeModules-${{ hashFiles('${{ env.OXIDE_LOCATION }}/package-lock.json') }}-linux-${{ matrix.target }}-${{ env.NODE_VERSION }}
|
||||
# restore-keys: |
|
||||
# nodeModules-
|
||||
|
||||
- name: Oxide — npm install
|
||||
# if: steps.cache-oxide.outputs.cache-hit != 'true'
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm install
|
||||
|
||||
- name: Build release
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm run build
|
||||
env:
|
||||
RUST_TARGET: ${{ matrix.target }}
|
||||
|
||||
- name: Strip debug symbols # https://github.com/rust-lang/rust/issues/46034
|
||||
if: ${{ matrix.strip }}
|
||||
run: ${{ matrix.strip }} ${{ env.OXIDE_LOCATION }}/*.node
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bindings-${{ matrix.target }}
|
||||
path: |
|
||||
${{ env.OXIDE_LOCATION }}/*.node
|
||||
${{ env.APP_NAME }}
|
||||
|
||||
oxide-release:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
name: Build and release
|
||||
needs:
|
||||
- oxide-build
|
||||
- oxide-build-linux
|
||||
- oxide-build-apple-silicon
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# - name: Use cached oxide node_modules
|
||||
# id: cache-oxide
|
||||
# uses: actions/cache@v3
|
||||
# with:
|
||||
# path: ${{ env.OXIDE_LOCATION }}/node_modules
|
||||
# key: nodeModules-${{ hashFiles('${{ env.OXIDE_LOCATION }}/package-lock.json') }}-ubuntu-latest-${{ env.NODE_VERSION }}
|
||||
# restore-keys: |
|
||||
# nodeModules-
|
||||
|
||||
- name: Oxide — npm install
|
||||
# if: steps.cache-oxide.outputs.cache-hit != 'true'
|
||||
run: cd ${{ env.OXIDE_LOCATION }} && npm install
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: ${{ env.OXIDE_LOCATION }}
|
||||
|
||||
- run: echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} > ~/.npmrc
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Move artifacts
|
||||
run: |
|
||||
cd ${{ env.OXIDE_LOCATION }}
|
||||
cp bindings-aarch64-apple-darwin/oxide/crates/node/* ./npm/darwin-arm64/
|
||||
cp bindings-aarch64-unknown-linux-gnu/oxide/crates/node/* ./npm/linux-arm64-gnu/
|
||||
cp bindings-aarch64-unknown-linux-musl/oxide/crates/node/* ./npm/linux-arm64-musl/
|
||||
cp bindings-armv7-unknown-linux-gnueabihf/oxide/crates/node/* ./npm/linux-arm-gnueabihf/
|
||||
cp bindings-x86_64-apple-darwin/* ./npm/darwin-x64/
|
||||
cp bindings-x86_64-pc-windows-msvc/* ./npm/win32-x64-msvc/
|
||||
cp bindings-x86_64-unknown-linux-gnu/oxide/crates/node/* ./npm/linux-x64-gnu/
|
||||
cp bindings-x86_64-unknown-linux-musl/oxide/crates/node/* ./npm/linux-x64-musl/
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "NPM_VERSION=0.0.0-insiders.$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: Generate entry point
|
||||
run: npm run build --prefix ${{ env.OXIDE_LOCATION }}
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
for pkg in ${{ env.OXIDE_LOCATION }}/npm/*; do
|
||||
echo "Publishing $pkg..."
|
||||
cd $pkg
|
||||
npm version ${{ env.NPM_VERSION }} --force --no-git-tag-version
|
||||
npm publish --tag insiders --access public
|
||||
cd -
|
||||
done
|
||||
|
||||
echo "Publishing ${{ env.APP_NAME }}...";
|
||||
cd ${{ env.OXIDE_LOCATION }}
|
||||
npm version ${{ env.NPM_VERSION }} --force --no-git-tag-version
|
||||
sed "s#\"0.0.0\"#\"${{ env.NPM_VERSION }}\"#g" package.json > package_updated.json
|
||||
mv package_updated.json package.json
|
||||
npm publish --tag insiders --access public
|
||||
cd -
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
tailwind_oxide_release:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
name: Build and release Tailwind CSS
|
||||
|
||||
needs:
|
||||
- oxide-release
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Resolve version
|
||||
id: vars
|
||||
run: |
|
||||
echo "SHA_SHORT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
echo "OXIDE_NPM_VERSION=0.0.0-insiders.$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup `@tailwindcss/oxide` version
|
||||
run: |
|
||||
sed "s#\"@tailwindcss/oxide\": \".*\"#\"@tailwindcss/oxide\": \"${{ env.OXIDE_NPM_VERSION }}\"#" package.json > package_updated.json
|
||||
mv package_updated.json package.json
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test
|
||||
run: npm test
|
||||
|
||||
- name: 'Version based on commit: 0.0.0-oxide.${{ env.SHA_SHORT }}'
|
||||
run: npm version 0.0.0-oxide.${{ env.SHA_SHORT }} --force --no-git-tag-version
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --tag oxide
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
68
.github/workflows/release-stable.yml
vendored
68
.github/workflows/release-stable.yml
vendored
@ -1,68 +0,0 @@
|
||||
name: Release — Stable
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Use the `stable` engine
|
||||
run: |
|
||||
node ./scripts/swap-engines.js
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build Tailwind CSS
|
||||
run: npm run build
|
||||
|
||||
- name: Test
|
||||
run: npm run test
|
||||
|
||||
- name: Calculate environment variables
|
||||
run: |
|
||||
echo "RELEASE_CHANNEL=$(node ./scripts/release-channel.js)" >> $GITHUB_ENV
|
||||
echo "TAILWINDCSS_VERSION=$(node -e 'console.log(require(`./package.json`).version);')" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish
|
||||
run: npm publish --tag ${{ env.RELEASE_CHANNEL }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Trigger Tailwind Play update
|
||||
if: env.RELEASE_CHANNEL == 'latest'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.TAILWIND_PLAY_TOKEN }}
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: 'tailwindlabs',
|
||||
repo: 'play.tailwindcss.com',
|
||||
ref: 'master',
|
||||
workflow_id: 'upgrade-tailwindcss.yml',
|
||||
inputs: {
|
||||
version: '${{ env.TAILWINDCSS_VERSION }}'
|
||||
}
|
||||
})
|
||||
25
.gitignore
vendored
25
.gitignore
vendored
@ -1,25 +0,0 @@
|
||||
/node_modules
|
||||
/coverage
|
||||
/cli
|
||||
/lib
|
||||
/peers
|
||||
/example
|
||||
.vscode
|
||||
.DS_Store
|
||||
.parcel-cache
|
||||
tailwind.config.js
|
||||
index.html
|
||||
yarn.lock
|
||||
yarn-error.log
|
||||
types/generated/*.d.ts
|
||||
|
||||
.turbo
|
||||
|
||||
# Perf related files
|
||||
isolate*.log
|
||||
|
||||
# Generated files
|
||||
/src/corePluginList.js
|
||||
|
||||
# Generated files during tests
|
||||
/tests/evaluate-tailwind-functions.test.html
|
||||
16
.swcrc
16
.swcrc
@ -1,16 +0,0 @@
|
||||
{
|
||||
"module": {
|
||||
"type": "commonjs"
|
||||
},
|
||||
"env": {
|
||||
"targets": {
|
||||
"node": "12.13.0"
|
||||
}
|
||||
},
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": false
|
||||
}
|
||||
}
|
||||
}
|
||||
2578
CHANGELOG.md
2578
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Tailwind Labs, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
41
README.md
41
README.md
@ -1,41 +0,0 @@
|
||||
<p align="center">
|
||||
<a href="https://tailwindcss.com" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg">
|
||||
<img alt="Tailwind CSS" src="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg" width="350" height="70" style="max-width: 100%;">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
A utility-first CSS framework for rapidly building custom user interfaces.
|
||||
</p>
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci-stable.yml?branch=master" alt="Build Status"></a>
|
||||
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
|
||||
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
|
||||
<a href="https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a>
|
||||
</p>
|
||||
|
||||
------
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation, visit [tailwindcss.com](https://tailwindcss.com/).
|
||||
|
||||
## Community
|
||||
|
||||
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
|
||||
|
||||
[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions)
|
||||
|
||||
For casual chit-chat with others using the framework:
|
||||
|
||||
[Join the Tailwind CSS Discord Server](https://discord.gg/7NF8GNe)
|
||||
|
||||
## Contributing
|
||||
|
||||
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md) **before submitting a pull request**.
|
||||
3
colors.d.ts
vendored
3
colors.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
import type { DefaultColors } from './types/generated/colors'
|
||||
declare const colors: DefaultColors
|
||||
export = colors
|
||||
@ -1,2 +0,0 @@
|
||||
let colors = require('./lib/public/colors')
|
||||
module.exports = (colors.__esModule ? colors : { default: colors }).default
|
||||
@ -1 +0,0 @@
|
||||
@tailwind components;
|
||||
3
defaultConfig.d.ts
vendored
3
defaultConfig.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
import type { Config } from './types/config'
|
||||
declare const config: Config
|
||||
export = config
|
||||
@ -1,2 +0,0 @@
|
||||
let defaultConfig = require('./lib/public/default-config')
|
||||
module.exports = (defaultConfig.__esModule ? defaultConfig : { default: defaultConfig }).default
|
||||
4
defaultTheme.d.ts
vendored
4
defaultTheme.d.ts
vendored
@ -1,4 +0,0 @@
|
||||
import type { Config } from './types/config'
|
||||
import { DefaultTheme } from './types/generated/default-theme'
|
||||
declare const theme: Config['theme'] & DefaultTheme
|
||||
export = theme
|
||||
@ -1,2 +0,0 @@
|
||||
let defaultTheme = require('./lib/public/default-theme')
|
||||
module.exports = (defaultTheme.__esModule ? defaultTheme : { default: defaultTheme }).default
|
||||
1
integrations/.gitignore
vendored
1
integrations/.gitignore
vendored
@ -1 +0,0 @@
|
||||
node_modules/
|
||||
1
integrations/content-resolution/.gitignore
vendored
1
integrations/content-resolution/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.tailwind.config.js
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-content-resolution",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production postcss ./src/index.css -o ./dist/main.css --verbose",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "Content Resolution",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-cli": "^10.1.0"
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve(__dirname, '..', '..'))],
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
@tailwind utilities;
|
||||
@ -1 +0,0 @@
|
||||
// content-[real-static-negative]
|
||||
@ -1 +0,0 @@
|
||||
// content-[real-dynamic-negative]
|
||||
@ -1 +0,0 @@
|
||||
<!-- content-[real-static-positive] -->
|
||||
@ -1 +0,0 @@
|
||||
// content-[real-dynamic-positive]
|
||||
@ -1 +0,0 @@
|
||||
// content-[resolved-static-negative]
|
||||
@ -1 +0,0 @@
|
||||
// content-[resolved-dynamic-negative]
|
||||
@ -1 +0,0 @@
|
||||
<!-- content-[resolved-static-positive] -->
|
||||
@ -1 +0,0 @@
|
||||
// content-[resolved-dynamic-positive]
|
||||
@ -1,53 +0,0 @@
|
||||
// @ts-config
|
||||
|
||||
let fs = require('fs')
|
||||
let path = require('path')
|
||||
|
||||
module.exports.writeConfigs = async function writeConfigs({
|
||||
both = {},
|
||||
inRoot = {},
|
||||
inDir = {},
|
||||
} = {}) {
|
||||
let configs = [
|
||||
{
|
||||
path: '../tailwind.config.js',
|
||||
config: {
|
||||
...both,
|
||||
...inRoot,
|
||||
content: {
|
||||
files: [],
|
||||
...both.content,
|
||||
...inRoot.content,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '../src/tailwind.config.js',
|
||||
config: {
|
||||
...both,
|
||||
...inDir,
|
||||
content: {
|
||||
files: [],
|
||||
...both.content,
|
||||
...inDir.content,
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
let defaultConfig = {
|
||||
corePlugins: { preflight: false },
|
||||
}
|
||||
|
||||
for (const config of configs) {
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(__dirname, config.path),
|
||||
`module.exports = ${JSON.stringify({ ...defaultConfig, ...config.config })};`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.destroyConfigs = async function destroyConfigs() {
|
||||
await fs.promises.unlink(path.resolve(__dirname, '../tailwind.config.js'))
|
||||
await fs.promises.unlink(path.resolve(__dirname, '../src/tailwind.config.js'))
|
||||
}
|
||||
@ -1,287 +0,0 @@
|
||||
let fs = require('fs')
|
||||
let path = require('path')
|
||||
let { cwd } = require('./cwd.js')
|
||||
let { writeConfigs, destroyConfigs } = require('./config.js')
|
||||
|
||||
let $ = require('../../execute')
|
||||
let { css } = require('../../syntax')
|
||||
|
||||
let { readOutputFile } = require('../../io')({
|
||||
output: 'dist',
|
||||
input: '.',
|
||||
})
|
||||
|
||||
// Write default configs before running tests and remove them afterwards
|
||||
beforeAll(() => writeConfigs())
|
||||
afterAll(() => destroyConfigs())
|
||||
|
||||
// Create a symlink at ./src/link that points to ./src/resolved and remove it afterwards
|
||||
beforeAll(() =>
|
||||
fs.promises.symlink(
|
||||
path.resolve(__dirname, '../src/resolved'),
|
||||
path.resolve(__dirname, '../src/link')
|
||||
)
|
||||
)
|
||||
afterAll(async () => {
|
||||
try {
|
||||
await fs.promises.unlink(path.resolve(__dirname, '../src/link'))
|
||||
} catch {}
|
||||
})
|
||||
|
||||
// If we've changed directories reset the cwd back to what it was before running these tests
|
||||
afterEach(() => cwd.unwind())
|
||||
|
||||
async function build({ cwd: cwdPath } = {}) {
|
||||
let inputPath = path.resolve(__dirname, '../src/index.css')
|
||||
let outputPath = path.resolve(__dirname, '../dist/main.css')
|
||||
|
||||
await cwd.switch(cwdPath)
|
||||
|
||||
// Note that ./tailwind.config.js is hardcoded on purpose here
|
||||
// It represents a config but one that could be in different places
|
||||
await $(`postcss ${inputPath} -o ${outputPath}`, {
|
||||
env: { NODE_ENV: 'production' },
|
||||
cwd: cwdPath,
|
||||
})
|
||||
|
||||
return {
|
||||
css: await readOutputFile('main.css'),
|
||||
}
|
||||
}
|
||||
|
||||
it('looks in the CWD by default', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
files: ['./src/real/yes.html'],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
})
|
||||
|
||||
it('looks in the CWD for non-config-relative paths', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
// Turn it on by default (eventual v4 behavior)
|
||||
experimental: { relativeContentPathsByDefault: true },
|
||||
|
||||
// But then disable it anyway
|
||||
content: {
|
||||
relative: false,
|
||||
files: ['./src/real/yes.html'],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
})
|
||||
|
||||
it('can look for content files relative to the config', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
relative: true,
|
||||
files: ['./real/yes.html'],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Here `./real` doesn't exist next to the config in the root directory
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(css``)
|
||||
|
||||
// But here it `./real` does exist next to the config in the `./src` directory!
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
it('it handles ignored globs correctly when not relative to the config', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
relative: false,
|
||||
files: [
|
||||
'./src/real/yes.html', // Scanned + static
|
||||
'./src/real/*.js', // Scanned + dynamic
|
||||
'!./src/real/no.js', // Ignored + static
|
||||
'!./src/real/no-*.js', // Ignored + dynamic
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-dynamic-positive\] {
|
||||
--tw-content: real-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
|
||||
// But here it `./real` does exist next to the config in the `./src` directory!
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
})
|
||||
|
||||
it('it handles ignored globs correctly when relative to the config', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
relative: true,
|
||||
files: [
|
||||
'./real/yes.html', // Scanned + static
|
||||
'./real/*.js', // Scanned + dynamic
|
||||
'!./real/no.js', // Ignored + static
|
||||
'!./real/no-*.js', // Ignored + dynamic
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
|
||||
// But here it `./real` does exist next to the config in the `./src` directory!
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-dynamic-positive\] {
|
||||
--tw-content: real-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
it('it can resolve symlinks for files when not relative to the config', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
relative: false,
|
||||
files: [
|
||||
'./src/real/yes.html', // Scanned + static
|
||||
'./src/real/*.js', // Scanned + dynamic
|
||||
'./src/link/yes.html', // Scanned + static + symlinked
|
||||
'./src/link/*.js', // Scanned + dynamic + symlinked
|
||||
'!./src/real/no.js', // Ignored + static
|
||||
'!./src/real/no-*.js', // Ignored + dynamic
|
||||
'!./src/link/no.js', // Ignored + static + symlinked
|
||||
'!./src/link/no-*.js', // Ignored + dynamic + symlinked
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-dynamic-positive\] {
|
||||
--tw-content: real-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[resolved-dynamic-positive\] {
|
||||
--tw-content: resolved-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[resolved-static-positive\] {
|
||||
--tw-content: resolved-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
|
||||
// But here it `./real` does exist next to the config in the `./src` directory!
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
})
|
||||
|
||||
it('it can resolve symlinks for files when relative to the config', async () => {
|
||||
await writeConfigs({
|
||||
both: {
|
||||
content: {
|
||||
relative: true,
|
||||
files: [
|
||||
'./real/yes.html', // Scanned + static
|
||||
'./real/*.js', // Scanned + dynamic
|
||||
'./link/yes.html', // Scanned + static + symlinked
|
||||
'./link/*.js', // Scanned + dynamic + symlinked
|
||||
'!./real/no.js', // Ignored + static
|
||||
'!./real/no-*.js', // Ignored + dynamic
|
||||
'!./link/no.js', // Ignored + static + symlinked
|
||||
'!./link/no-*.js', // Ignored + dynamic + symlinked
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
let result = await build({ cwd: path.resolve(__dirname, '..') })
|
||||
|
||||
expect(result.css).toMatchCss(``)
|
||||
|
||||
// But here it `./real` does exist next to the config in the `./src` directory!
|
||||
result = await build({ cwd: path.resolve(__dirname, '../src') })
|
||||
|
||||
expect(result.css).toMatchCss(css`
|
||||
.content-\[real-dynamic-positive\] {
|
||||
--tw-content: real-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[real-static-positive\] {
|
||||
--tw-content: real-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[resolved-dynamic-positive\] {
|
||||
--tw-content: resolved-dynamic-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
.content-\[resolved-static-positive\] {
|
||||
--tw-content: resolved-static-positive;
|
||||
content: var(--tw-content);
|
||||
}
|
||||
`)
|
||||
})
|
||||
@ -1,24 +0,0 @@
|
||||
// @ts-config
|
||||
|
||||
let stack = []
|
||||
|
||||
module.exports.cwd = {
|
||||
get current() {
|
||||
return process.cwd()
|
||||
},
|
||||
|
||||
async switch(dir) {
|
||||
stack.push(process.cwd())
|
||||
process.chdir(dir)
|
||||
},
|
||||
|
||||
async restore() {
|
||||
process.chdir(stack.pop())
|
||||
},
|
||||
|
||||
async unwind() {
|
||||
while (stack.length) {
|
||||
this.restore()
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -1,152 +0,0 @@
|
||||
let fs = require('fs')
|
||||
let path = require('path')
|
||||
let { spawn } = require('child_process')
|
||||
let resolveToolRoot = require('./resolve-tool-root')
|
||||
|
||||
let SHOW_OUTPUT = false
|
||||
|
||||
let runningProcessess = []
|
||||
|
||||
afterEach(() => {
|
||||
runningProcessess.splice(0).forEach((runningProcess) => runningProcess.stop())
|
||||
})
|
||||
|
||||
function debounce(fn, ms) {
|
||||
let state = { timer: undefined }
|
||||
|
||||
return (...args) => {
|
||||
if (state.timer) clearTimeout(state.timer)
|
||||
state.timer = setTimeout(() => fn(...args), ms)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function $(command, options = {}) {
|
||||
let abortController = new AbortController()
|
||||
let root = resolveToolRoot()
|
||||
let cwd = options.cwd ?? root
|
||||
|
||||
let args = options.shell
|
||||
? [command]
|
||||
: (() => {
|
||||
let args = command.trim().split(/\s+/)
|
||||
command = args.shift()
|
||||
command =
|
||||
command === 'node'
|
||||
? command
|
||||
: (function () {
|
||||
let local = path.resolve(root, 'node_modules', '.bin', command)
|
||||
if (fs.existsSync(local)) {
|
||||
return local
|
||||
}
|
||||
|
||||
let hoisted = path.resolve(root, '..', '..', 'node_modules', '.bin', command)
|
||||
if (fs.existsSync(hoisted)) {
|
||||
return hoisted
|
||||
}
|
||||
|
||||
return `npx ${command}`
|
||||
})()
|
||||
return [command, args]
|
||||
})()
|
||||
|
||||
let stdoutMessages = []
|
||||
let stderrMessages = []
|
||||
|
||||
let stdoutActors = []
|
||||
let stderrActors = []
|
||||
|
||||
function notifyNext(actors, messages) {
|
||||
if (actors.length <= 0) return
|
||||
let [next] = actors
|
||||
|
||||
for (let [idx, message] of messages.entries()) {
|
||||
if (next.predicate(message)) {
|
||||
messages.splice(0, idx + 1)
|
||||
let actorIdx = actors.indexOf(next)
|
||||
actors.splice(actorIdx, 1)
|
||||
next.resolve()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let notifyNextStdoutActor = debounce(() => {
|
||||
return notifyNext(stdoutActors, stdoutMessages)
|
||||
}, 200)
|
||||
|
||||
let notifyNextStderrActor = debounce(() => {
|
||||
return notifyNext(stderrActors, stderrMessages)
|
||||
}, 200)
|
||||
|
||||
let runningProcess = new Promise((resolve, reject) => {
|
||||
let child = spawn(...args, {
|
||||
...options,
|
||||
env: {
|
||||
...process.env,
|
||||
...options.env,
|
||||
},
|
||||
signal: abortController.signal,
|
||||
cwd,
|
||||
})
|
||||
|
||||
let stdout = ''
|
||||
let stderr = ''
|
||||
let combined = ''
|
||||
|
||||
child.stdout.on('data', (data) => {
|
||||
if (SHOW_OUTPUT) {
|
||||
console.log(data.toString())
|
||||
}
|
||||
stdoutMessages.push(data.toString())
|
||||
notifyNextStdoutActor()
|
||||
stdout += data
|
||||
combined += data
|
||||
})
|
||||
|
||||
child.stderr.on('data', (data) => {
|
||||
if (SHOW_OUTPUT) {
|
||||
console.error(data.toString())
|
||||
}
|
||||
stderrMessages.push(data.toString())
|
||||
notifyNextStderrActor()
|
||||
stderr += data
|
||||
combined += data
|
||||
})
|
||||
|
||||
child.on('error', (err) => {
|
||||
if (err.name !== 'AbortError') {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
;(signal === 'SIGTERM' ? resolve : code === 0 ? resolve : reject)({
|
||||
code,
|
||||
stdout,
|
||||
stderr,
|
||||
combined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
runningProcessess.push(runningProcess)
|
||||
|
||||
return Object.assign(runningProcess, {
|
||||
stop() {
|
||||
abortController.abort()
|
||||
return runningProcess
|
||||
},
|
||||
onStdout(predicate) {
|
||||
return new Promise((resolve) => {
|
||||
stdoutActors.push({ predicate, resolve })
|
||||
notifyNextStdoutActor()
|
||||
})
|
||||
},
|
||||
onStderr(predicate) {
|
||||
return new Promise((resolve) => {
|
||||
stderrActors.push({ predicate, resolve })
|
||||
notifyNextStderrActor()
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -1,180 +0,0 @@
|
||||
let { rm, existsSync } = require('fs')
|
||||
let path = require('path')
|
||||
let fs = require('fs/promises')
|
||||
|
||||
let chokidar = require('chokidar')
|
||||
|
||||
let resolveToolRoot = require('./resolve-tool-root')
|
||||
|
||||
function getWatcherOptions() {
|
||||
return {
|
||||
usePolling: true,
|
||||
interval: 200,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 1500,
|
||||
pollInterval: 50,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function ({
|
||||
/** Output directory, relative to the tool. */
|
||||
output = 'dist',
|
||||
|
||||
/** Input directory, relative to the tool. */
|
||||
input = 'src',
|
||||
|
||||
/** Whether or not you want to cleanup the output directory. */
|
||||
cleanup = true,
|
||||
} = {}) {
|
||||
let toolRoot = resolveToolRoot()
|
||||
let fileCache = {}
|
||||
|
||||
let absoluteOutputFolder = path.resolve(toolRoot, output)
|
||||
let absoluteInputFolder = path.resolve(toolRoot, input)
|
||||
|
||||
if (cleanup) {
|
||||
beforeAll((done) => rm(absoluteOutputFolder, { recursive: true, force: true }, done))
|
||||
afterEach((done) => rm(absoluteOutputFolder, { recursive: true, force: true }, done))
|
||||
}
|
||||
|
||||
// Restore all written files
|
||||
afterEach(async () => {
|
||||
await Promise.all(
|
||||
Object.entries(fileCache).map(async ([file, content]) => {
|
||||
try {
|
||||
if (content === null) {
|
||||
return await fs.unlink(file)
|
||||
} else {
|
||||
return await fs.writeFile(file, content, 'utf8')
|
||||
}
|
||||
} catch {}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
async function readdir(start, parent = []) {
|
||||
let files = await fs.readdir(start, { withFileTypes: true })
|
||||
let resolvedFiles = await Promise.all(
|
||||
files.map((file) => {
|
||||
if (file.isDirectory()) {
|
||||
return readdir(path.resolve(start, file.name), [...parent, file.name])
|
||||
}
|
||||
return parent.concat(file.name).join(path.sep)
|
||||
})
|
||||
)
|
||||
return resolvedFiles.flat(Infinity)
|
||||
}
|
||||
|
||||
async function resolveFile(fileOrRegex, directory) {
|
||||
if (fileOrRegex instanceof RegExp) {
|
||||
let files = await readdir(directory)
|
||||
if (files.length === 0) {
|
||||
throw new Error(`No files exists in "${directory}"`)
|
||||
}
|
||||
|
||||
let filtered = files.filter((file) => fileOrRegex.test(file))
|
||||
if (filtered.length === 0) {
|
||||
throw new Error(`Not a single file matched: ${fileOrRegex}`)
|
||||
} else if (filtered.length > 1) {
|
||||
throw new Error(`Multiple files matched: ${fileOrRegex}`)
|
||||
}
|
||||
|
||||
return filtered[0]
|
||||
}
|
||||
|
||||
return fileOrRegex
|
||||
}
|
||||
|
||||
return {
|
||||
cleanupFile(file) {
|
||||
let filePath = path.resolve(toolRoot, file)
|
||||
fileCache[filePath] = null
|
||||
},
|
||||
async fileExists(file) {
|
||||
let filePath = path.resolve(toolRoot, file)
|
||||
return existsSync(filePath)
|
||||
},
|
||||
async removeFile(file) {
|
||||
let filePath = path.resolve(toolRoot, file)
|
||||
|
||||
if (!fileCache[filePath]) {
|
||||
fileCache[filePath] = await fs.readFile(filePath, 'utf8').catch(() => null)
|
||||
}
|
||||
|
||||
await fs.unlink(filePath).catch(() => null)
|
||||
},
|
||||
async readOutputFile(file) {
|
||||
file = await resolveFile(file, absoluteOutputFolder)
|
||||
return fs.readFile(path.resolve(absoluteOutputFolder, file), 'utf8')
|
||||
},
|
||||
async readInputFile(file) {
|
||||
file = await resolveFile(file, absoluteInputFolder)
|
||||
return fs.readFile(path.resolve(absoluteInputFolder, file), 'utf8')
|
||||
},
|
||||
async appendToInputFile(file, contents) {
|
||||
let filePath = path.resolve(absoluteInputFolder, file)
|
||||
if (!fileCache[filePath]) {
|
||||
fileCache[filePath] = await fs.readFile(filePath, 'utf8')
|
||||
}
|
||||
|
||||
return fs.appendFile(filePath, contents, 'utf8')
|
||||
},
|
||||
async writeInputFile(file, contents) {
|
||||
let filePath = path.resolve(absoluteInputFolder, file)
|
||||
if (!fileCache[filePath]) {
|
||||
try {
|
||||
fileCache[filePath] = await fs.readFile(filePath, 'utf8')
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
fileCache[filePath] = null // Sentinel value to `delete` the file afterwards. This also means that we are writing to a `new` file inside the test.
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fs.writeFile(path.resolve(absoluteInputFolder, file), contents, 'utf8')
|
||||
},
|
||||
async waitForOutputFileCreation(file) {
|
||||
if (file instanceof RegExp) {
|
||||
let r = file
|
||||
let watcher = chokidar.watch(absoluteOutputFolder, getWatcherOptions())
|
||||
|
||||
return new Promise((resolve) => {
|
||||
watcher.on('add', (file) => {
|
||||
if (r.test(file)) {
|
||||
watcher.close().then(() => resolve())
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
let filePath = path.resolve(absoluteOutputFolder, file)
|
||||
|
||||
return new Promise((resolve) => {
|
||||
let watcher = chokidar.watch(absoluteOutputFolder, getWatcherOptions())
|
||||
|
||||
watcher.on('add', (addedFile) => {
|
||||
if (addedFile !== filePath) return
|
||||
return watcher.close().finally(resolve)
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
async waitForOutputFileChange(file, cb = () => {}) {
|
||||
file = await resolveFile(file, absoluteOutputFolder)
|
||||
let filePath = path.resolve(absoluteOutputFolder, file)
|
||||
|
||||
return new Promise((resolve) => {
|
||||
let watcher = chokidar.watch(absoluteOutputFolder, getWatcherOptions())
|
||||
|
||||
watcher
|
||||
.on('change', (changedFile) => {
|
||||
if (changedFile !== filePath) return
|
||||
return watcher.close().finally(resolve)
|
||||
})
|
||||
.on('ready', cb)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "integrations",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 30000,
|
||||
"projects": [
|
||||
"<rootDir>/*/package.json"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jest": "^26.6.3"
|
||||
}
|
||||
}
|
||||
5
integrations/parcel/.gitignore
vendored
5
integrations/parcel/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
.parcel-cache/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-parcel",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "parcel build ./src/index.html --no-cache",
|
||||
"dev": "parcel watch ./src/index.html --no-cache",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "parcel",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel": "^2.8.3"
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve('..', '..'))],
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./index.css">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./index.css">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
content: ['./src/index.html', './src/glob/*.{js,html}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -1,481 +0,0 @@
|
||||
let $ = require('../../execute')
|
||||
let { css, html, javascript } = require('../../syntax')
|
||||
let { env } = require('../../../lib/lib/sharedState')
|
||||
|
||||
let {
|
||||
appendToInputFile,
|
||||
readOutputFile,
|
||||
removeFile,
|
||||
waitForOutputFileChange,
|
||||
waitForOutputFileCreation,
|
||||
writeInputFile,
|
||||
} = require('../../io')({ output: 'dist', input: 'src' })
|
||||
|
||||
describe('static build', () => {
|
||||
it('should be possible to generate tailwind output', async () => {
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="font-bold"></div>
|
||||
`
|
||||
)
|
||||
|
||||
await $('parcel build ./src/index.html --no-cache', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
it('can use a tailwind.config.js configuration file with ESM syntax', async () => {
|
||||
await removeFile('tailwind.config.js')
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="bg-primary"></div>
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
export default {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await $('parcel build ./src/index.html --no-cache', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
background-color: black;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('can use a tailwind.config.ts configuration file', async () => {
|
||||
await removeFile('tailwind.config.js')
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="bg-primary"></div>
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'../tailwind.config.ts',
|
||||
javascript`
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
export default {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
} satisfies Config
|
||||
`
|
||||
)
|
||||
|
||||
await $('parcel build ./src/index.html --no-cache', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
background-color: black;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('watcher', () => {
|
||||
test('classes are generated when the html file changes', async () => {
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="font-bold"></div>
|
||||
`
|
||||
)
|
||||
|
||||
let runningProcess = $('parcel watch ./src/index.html --no-cache')
|
||||
|
||||
await waitForOutputFileCreation(/index\.\w+\.css$/)
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
|
||||
})
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await appendToInputFile('index.html', html`<div class="bg-red-500"></div>`)
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test.skip('classes are generated when globbed files change', async () => {
|
||||
await writeInputFile('index.html', html` <link rel="stylesheet" href="./index.css" /> `)
|
||||
|
||||
await writeInputFile('glob/index.html', html` <div class="font-bold"></div> `)
|
||||
|
||||
let runningProcess = $('parcel watch ./src/index.html --no-cache')
|
||||
|
||||
await waitForOutputFileCreation(/index\.\w+\.css$/)
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await appendToInputFile('glob/index.html', html`<div class="font-normal"></div>`)
|
||||
})
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await appendToInputFile('glob/index.html', html`<div class="bg-red-500"></div>`)
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test('classes are generated when the tailwind.config.js file changes', async () => {
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="font-bold md:font-medium"></div>
|
||||
`
|
||||
)
|
||||
|
||||
let runningProcess = $('parcel watch ./src/index.html --no-cache')
|
||||
|
||||
await waitForOutputFileCreation(/index\.\w+\.css$/)
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
module.exports = {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
md: '800px'
|
||||
},
|
||||
fontWeight: {
|
||||
bold: 'bold'
|
||||
}
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test('classes are generated when the index.css file changes', async () => {
|
||||
await writeInputFile(
|
||||
'index.html',
|
||||
html`
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<div class="btn font-bold"></div>
|
||||
`
|
||||
)
|
||||
|
||||
let runningProcess = $('parcel watch ./src/index.html --no-cache')
|
||||
|
||||
await waitForOutputFileCreation(/index\.\w+\.css$/)
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
/* prettier-ignore */
|
||||
.btn {
|
||||
border-radius: .25rem;
|
||||
padding: .25rem .5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await waitForOutputFileChange(/index\.\w+\.css$/, async () => {
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded bg-red-500 px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
background-color: #ef4444;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
})
|
||||
4
integrations/postcss-cli/.gitignore
vendored
4
integrations/postcss-cli/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-postcss-cli",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production postcss ./src/index.css -o ./dist/main.css --verbose",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "PostCSS CLI",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-cli": "^10.1.0"
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve('..', '..'))],
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
content: ['./src/index.html', './src/glob/*.{js,html}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -1,324 +0,0 @@
|
||||
let $ = require('../../execute')
|
||||
let { css, html, javascript } = require('../../syntax')
|
||||
let { env } = require('../../../lib/lib/sharedState')
|
||||
|
||||
let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({
|
||||
output: 'dist',
|
||||
input: 'src',
|
||||
})
|
||||
|
||||
function ready(message) {
|
||||
return message.includes('Finished')
|
||||
}
|
||||
|
||||
describe('static build', () => {
|
||||
it('should be possible to generate tailwind output', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $('postcss ./src/index.css -o ./dist/main.css', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('watcher', () => {
|
||||
test('classes are generated when the html file changes', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('postcss ./src/index.css -o ./dist/main.css -w --verbose')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test('classes are generated when globbed files change', async () => {
|
||||
await writeInputFile('glob/index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('postcss ./src/index.css -o ./dist/main.css -w --verbose')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test('classes are generated when the tailwind.config.js file changes', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold md:font-medium"></div>`)
|
||||
|
||||
let runningProcess = $('postcss ./src/index.css -o ./dist/main.css -w --verbose')
|
||||
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
module.exports = {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
md: '800px'
|
||||
},
|
||||
fontWeight: {
|
||||
bold: 'bold'
|
||||
}
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test('classes are generated when the index.css file changes', async () => {
|
||||
await writeInputFile('index.html', html`<div class="btn font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('postcss ./src/index.css -o ./dist/main.css -w --verbose')
|
||||
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded bg-red-500 px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
/* prettier-ignore */
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
background-color: #ef4444;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
})
|
||||
@ -1,14 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = function resolveToolRoot() {
|
||||
let { testPath } = expect.getState()
|
||||
let separator = '/' // TODO: Does this resolve correctly on windows, or should we use `path.sep` instead.
|
||||
|
||||
return path.resolve(
|
||||
__dirname,
|
||||
testPath
|
||||
.replace(__dirname + separator, '')
|
||||
.split(separator)
|
||||
.shift()
|
||||
)
|
||||
}
|
||||
4
integrations/rollup-sass/.gitignore
vendored
4
integrations/rollup-sass/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-rollup-sass",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "rollup.js",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^3.21.0",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"sass": "^1.62.0"
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve('..', '..'))],
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
import postcss from 'rollup-plugin-postcss'
|
||||
|
||||
export default {
|
||||
input: './src/index.js',
|
||||
output: {
|
||||
file: './dist/index.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [
|
||||
postcss({
|
||||
extract: true,
|
||||
}),
|
||||
],
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@ -1 +0,0 @@
|
||||
// Stub
|
||||
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@ -1 +0,0 @@
|
||||
import './index.scss'
|
||||
@ -1,4 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "./imported";
|
||||
@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
content: ['./src/index.html', './src/glob/*.{js,html}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -1,415 +0,0 @@
|
||||
let $ = require('../../execute')
|
||||
let { css, html, javascript } = require('../../syntax')
|
||||
let { env } = require('../../../lib/lib/sharedState')
|
||||
|
||||
let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({
|
||||
output: 'dist',
|
||||
input: 'src',
|
||||
})
|
||||
|
||||
function ready(message) {
|
||||
return message.includes('created')
|
||||
}
|
||||
|
||||
describe('static build', () => {
|
||||
it('should be possible to generate tailwind output', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $('rollup -c', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('watcher', () => {
|
||||
test(`classes are generated when the html file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when globbed files change`, async () => {
|
||||
await writeInputFile('glob/index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when the tailwind.config.js file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold md:font-medium"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
module.exports = {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
md: '800px'
|
||||
},
|
||||
fontWeight: {
|
||||
bold: 'bold'
|
||||
}
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when the index.css file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="btn font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.scss',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.scss',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded bg-red-500 px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
background-color: #ef4444;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when the imported.scss file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="btn font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.scss',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import './imported';
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'imported.scss',
|
||||
css`
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'imported.scss',
|
||||
css`
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded bg-red-500 px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
background-color: #ef4444;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
}, 30000)
|
||||
})
|
||||
4
integrations/rollup/.gitignore
vendored
4
integrations/rollup/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-rollup",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "rollup.js",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^3.21.0",
|
||||
"rollup-plugin-postcss": "^4.0.2"
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve('..', '..'))],
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
import postcss from 'rollup-plugin-postcss'
|
||||
|
||||
export default {
|
||||
input: './src/index.js',
|
||||
output: {
|
||||
file: './dist/index.js',
|
||||
format: 'cjs',
|
||||
},
|
||||
plugins: [
|
||||
postcss({
|
||||
extract: true,
|
||||
}),
|
||||
],
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1 +0,0 @@
|
||||
import './index.css'
|
||||
@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
content: ['./src/index.html', './src/glob/*.{js,html}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -1,435 +0,0 @@
|
||||
let $ = require('../../execute')
|
||||
let { css, html, javascript } = require('../../syntax')
|
||||
let { env } = require('../../../lib/lib/sharedState')
|
||||
|
||||
let { readOutputFile, appendToInputFile, writeInputFile, removeFile } = require('../../io')({
|
||||
output: 'dist',
|
||||
input: 'src',
|
||||
})
|
||||
|
||||
function ready(message) {
|
||||
return message.includes('created')
|
||||
}
|
||||
|
||||
describe('static build', () => {
|
||||
it('should be possible to generate tailwind output', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $('rollup -c', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
it('can use a tailwind.config.js configuration file with ESM syntax', async () => {
|
||||
await removeFile('tailwind.config.js')
|
||||
await writeInputFile('index.html', html`<div class="bg-primary"></div>`)
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
export default {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await $('rollup -c', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
background-color: black;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('can use a tailwind.config.ts configuration file', async () => {
|
||||
await removeFile('tailwind.config.js')
|
||||
await writeInputFile('index.html', html`<div class="bg-primary"></div>`)
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
)
|
||||
await writeInputFile(
|
||||
'../tailwind.config.ts',
|
||||
javascript`
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
export default {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
} satisfies Config
|
||||
`
|
||||
)
|
||||
|
||||
await $('rollup -c', {
|
||||
env: { NODE_ENV: 'production' },
|
||||
})
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-primary {
|
||||
background-color: black;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('watcher', () => {
|
||||
test(`classes are generated when the html file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when globbed files change`, async () => {
|
||||
await writeInputFile('glob/index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="font-normal"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await appendToInputFile('glob/index.html', html`<div class="bg-red-500"></div>`)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.bg-red-500 {
|
||||
background-color: #ef4444;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
.font-normal {
|
||||
font-weight: 400;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when the tailwind.config.js file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold md:font-medium"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'../tailwind.config.js',
|
||||
javascript`
|
||||
module.exports = {
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
screens: {
|
||||
md: '800px'
|
||||
},
|
||||
fontWeight: {
|
||||
bold: 'bold'
|
||||
}
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.md\:font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
test(`classes are generated when the index.css file changes`, async () => {
|
||||
await writeInputFile('index.html', html`<div class="btn font-bold"></div>`)
|
||||
|
||||
let runningProcess = $('rollup -c --watch')
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'index.css',
|
||||
css`
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply rounded bg-red-500 px-2 py-1;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
await runningProcess.onStderr(ready)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('index.css')).toIncludeCss(
|
||||
css`
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
background-color: #ef4444;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
})
|
||||
@ -1,2 +0,0 @@
|
||||
// Small helper to allow for css, html and JavaScript highlighting / formatting in most editors.
|
||||
module.exports = { css: String.raw, html: String.raw, javascript: String.raw }
|
||||
5
integrations/tailwindcss-cli/.gitignore
vendored
5
integrations/tailwindcss-cli/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
/src/tailwind.2.config.js
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "@tailwindcss/integrations-tailwindcss-cli",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css",
|
||||
"test": "jest --runInBand --forceExit"
|
||||
},
|
||||
"dependencies": {
|
||||
"tailwindcss": "file:../../"
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 10000,
|
||||
"displayName": "Tailwind CSS CLI",
|
||||
"setupFilesAfterEnv": [
|
||||
"<rootDir>/../../jest/customMatchers.js"
|
||||
],
|
||||
"transform": {
|
||||
"\\.js$": "@swc/jest",
|
||||
"\\.ts$": "@swc/jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
let path = require('path')
|
||||
|
||||
module.exports = {
|
||||
plugins: [require(path.resolve('..', '..'))],
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,5 +0,0 @@
|
||||
@layer utilities {
|
||||
.something-cool {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
content: ['./src/index.html', './src/glob/*.{js,html}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -1,726 +0,0 @@
|
||||
let path = require('path')
|
||||
let $ = require('../../execute')
|
||||
let { css, html, javascript } = require('../../syntax')
|
||||
let resolveToolRoot = require('../../resolve-tool-root')
|
||||
let { env } = require('../../../lib/lib/sharedState')
|
||||
|
||||
let version = require('../../../package.json').version
|
||||
|
||||
let {
|
||||
cleanupFile,
|
||||
fileExists,
|
||||
readOutputFile,
|
||||
removeFile,
|
||||
waitForOutputFileCreation,
|
||||
writeInputFile,
|
||||
} = require('../../io')({
|
||||
output: 'dist',
|
||||
input: 'src',
|
||||
})
|
||||
|
||||
let EXECUTABLE = 'node ../../lib/cli.js'
|
||||
let testStable = env.ENGINE === 'stable' ? test : test.skip
|
||||
|
||||
function dedent(input) {
|
||||
let lines = input.split('\n')
|
||||
|
||||
let minIndent = lines.reduce(
|
||||
(min, line) => Math.min(min, line.trim() === '' ? Infinity : line.match(/^\s*/)[0].length),
|
||||
Infinity
|
||||
)
|
||||
|
||||
return lines
|
||||
.map((line) => line.slice(minIndent))
|
||||
.join('\n')
|
||||
.trim()
|
||||
}
|
||||
|
||||
describe('Build command', () => {
|
||||
test('--output', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold shadow"></div>`)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css`)
|
||||
|
||||
let contents = await readOutputFile('main.css')
|
||||
|
||||
// `-i` is omitted, therefore the default `@tailwind base; @tailwind
|
||||
// components; @tailwind utilities` is used. However `preflight` is
|
||||
// disabled. I still want to verify that the `base` got included.
|
||||
expect(contents).toContain('--tw-ring-offset-shadow: 0 0 #0000')
|
||||
expect(contents).toContain('--tw-ring-shadow: 0 0 #0000')
|
||||
expect(contents).toContain('--tw-shadow: 0 0 #0000')
|
||||
|
||||
// Verify `utilities` output is correct
|
||||
expect(contents).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
test('--input, --output', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $(`${EXECUTABLE} --input ./src/index.css --output ./dist/main.css`)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
test('--minify', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --minify`)
|
||||
let withMinify = await readOutputFile('main.css')
|
||||
|
||||
// Verify that we got the expected output. Note: `.toIncludeCss` formats
|
||||
// `actual` & `expected`
|
||||
expect(withMinify).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css`)
|
||||
let withoutMinify = await readOutputFile('main.css')
|
||||
|
||||
// Let's verify that the actual minified output is smaller than the not
|
||||
// minified version.
|
||||
expect(withoutMinify.length).toBeGreaterThan(withMinify.length)
|
||||
})
|
||||
|
||||
testStable('--no-autoprefixer', async () => {
|
||||
await writeInputFile('index.html', html`<div class="select-none"></div>`)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css`)
|
||||
let withAutoprefixer = await readOutputFile('main.css')
|
||||
|
||||
expect(withAutoprefixer).toIncludeCss(css`
|
||||
.select-none {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
`)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --no-autoprefixer`)
|
||||
let withoutAutoprefixer = await readOutputFile('main.css')
|
||||
|
||||
expect(withoutAutoprefixer).toIncludeCss(css`
|
||||
.select-none {
|
||||
user-select: none;
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
test('--config (non-existing config file)', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let { stderr } = await $(
|
||||
`${EXECUTABLE} --output ./dist/main.css --config ./non-existing.config.js`
|
||||
).catch((err) => err)
|
||||
|
||||
let toolRoot = resolveToolRoot()
|
||||
expect(stderr).toEqual(
|
||||
`Specified config file ${path.resolve(toolRoot, 'non-existing.config.js')} does not exist.\n`
|
||||
)
|
||||
})
|
||||
|
||||
test('--config (existing config file)', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let customConfig = `module.exports = ${JSON.stringify(
|
||||
{
|
||||
content: ['./src/index.html'],
|
||||
theme: {
|
||||
extend: {
|
||||
fontWeight: {
|
||||
bold: 'BOLD',
|
||||
},
|
||||
},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
},
|
||||
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
|
||||
await writeInputFile('../custom.config.js', customConfig)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --config ./custom.config.js`)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: BOLD;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
test('--content', async () => {
|
||||
await writeInputFile('other.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
await $(`${EXECUTABLE} --content ./src/other.html --output ./dist/main.css`)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
testStable('--postcss (postcss.config.js)', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let customConfig = javascript`
|
||||
let path = require('path')
|
||||
let postcss = require('postcss')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
function before(root, result) {
|
||||
// Inject a custom component with @apply rules to prove that we run
|
||||
// this _before_ the actual tailwind plugin.
|
||||
let btn = postcss.parse('.btn { @apply bg-red-500 px-2 py-1 }')
|
||||
root.append(btn.nodes)
|
||||
},
|
||||
function tailwindcss() {
|
||||
return require(path.resolve('..', '..'))
|
||||
},
|
||||
function after(root, result) {
|
||||
// Add '-after' to all the selectors
|
||||
root.walkRules(rule => {
|
||||
if (!rule.selector.startsWith('.')) return
|
||||
rule.selector = rule.selector + '-after'
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
await writeInputFile('../postcss.config.js', customConfig)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --postcss`)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold-after {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-after {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold-after {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-after {
|
||||
background-color: #ef4444;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
testStable('--postcss (custom.postcss.config.js)', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let customConfig = javascript`
|
||||
let path = require('path')
|
||||
let postcss = require('postcss')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
function before(root, result) {
|
||||
// Inject a custom component with @apply rules to prove that we run
|
||||
// this _before_ the actual tailwind plugin.
|
||||
let btn = postcss.parse('.btn { @apply bg-red-500 px-2 py-1 }')
|
||||
root.append(btn.nodes)
|
||||
},
|
||||
function tailwindcss() {
|
||||
return require(path.resolve('..', '..'))
|
||||
},
|
||||
function after(root, result) {
|
||||
// Add '-after' to all the selectors
|
||||
root.walkRules(rule => {
|
||||
if (!rule.selector.startsWith('.')) return
|
||||
rule.selector = rule.selector + '-after'
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
await writeInputFile('../custom.postcss.config.js', customConfig)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --postcss ./custom.postcss.config.js`)
|
||||
|
||||
if (env.ENGINE === 'stable') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold-after {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-after {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
.font-bold-after {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn-after {
|
||||
background-color: #ef4444;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
testStable('--postcss supports process options', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let customConfig = javascript`
|
||||
let path = require('path')
|
||||
let postcss = require('postcss')
|
||||
|
||||
module.exports = {
|
||||
map: { inline: true },
|
||||
plugins: [
|
||||
function tailwindcss() {
|
||||
return require(path.resolve('..', '..'))
|
||||
},
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
await writeInputFile('../postcss.config.js', customConfig)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --postcss`)
|
||||
|
||||
let contents = await readOutputFile('main.css')
|
||||
|
||||
expect(contents).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
expect(contents).toContain(`/*# sourceMappingURL`)
|
||||
})
|
||||
|
||||
testStable('--postcss supports process options with custom config', async () => {
|
||||
await writeInputFile('index.html', html`<div class="font-bold"></div>`)
|
||||
|
||||
let customConfig = javascript`
|
||||
let path = require('path')
|
||||
let postcss = require('postcss')
|
||||
|
||||
module.exports = {
|
||||
map: { inline: true },
|
||||
plugins: [
|
||||
function tailwindcss() {
|
||||
return require(path.resolve('..', '..'))
|
||||
},
|
||||
],
|
||||
}
|
||||
`
|
||||
|
||||
await writeInputFile('../custom.postcss.config.js', customConfig)
|
||||
|
||||
await $(`${EXECUTABLE} --output ./dist/main.css --postcss ./custom.postcss.config.js`)
|
||||
|
||||
let contents = await readOutputFile('main.css')
|
||||
|
||||
expect(contents).toIncludeCss(
|
||||
css`
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
expect(contents).toContain(`/*# sourceMappingURL`)
|
||||
})
|
||||
|
||||
test('postcss-import is supported by default', async () => {
|
||||
cleanupFile('src/test.css')
|
||||
|
||||
await writeInputFile('index.html', html`<div class="md:something-cool"></div>`)
|
||||
await writeInputFile(
|
||||
'test.css',
|
||||
css`
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
@import './imported.css';
|
||||
`
|
||||
)
|
||||
|
||||
await $(
|
||||
`${EXECUTABLE} --input ./src/test.css --content ./src/index.html --output ./dist/main.css`
|
||||
)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
@media (min-width: 768px) {
|
||||
.md\:something-cool {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
test('postcss-import is supported by default in watch mode', async () => {
|
||||
cleanupFile('src/test.css')
|
||||
|
||||
await writeInputFile('index.html', html`<div class="md:something-cool"></div>`)
|
||||
await writeInputFile(
|
||||
'test.css',
|
||||
css`
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
@import './imported.css';
|
||||
`
|
||||
)
|
||||
|
||||
let runningProcess = $(
|
||||
`${EXECUTABLE} --watch --input ./src/test.css --content ./src/index.html --output ./dist/main.css`
|
||||
)
|
||||
|
||||
await waitForOutputFileCreation('main.css')
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
@media (min-width: 768px) {
|
||||
.md\:something-cool {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await writeInputFile(
|
||||
'imported.css',
|
||||
css`
|
||||
@layer utilities {
|
||||
.something-cool {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
await runningProcess.onStderr(function ready(message) {
|
||||
return message.includes('Done in')
|
||||
})
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
@media (min-width: 768px) {
|
||||
.md\:something-cool {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
return runningProcess.stop()
|
||||
})
|
||||
|
||||
testStable('postcss-import is included when using a custom postcss configuration', async () => {
|
||||
cleanupFile('src/test.css')
|
||||
|
||||
await writeInputFile('index.html', html`<div class="md:something-cool"></div>`)
|
||||
await writeInputFile(
|
||||
'test.css',
|
||||
css`
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
@import './imported.css';
|
||||
`
|
||||
)
|
||||
|
||||
await $(
|
||||
`${EXECUTABLE} --input ./src/test.css --content ./src/index.html --output ./dist/main.css --postcss`
|
||||
)
|
||||
|
||||
expect(await readOutputFile('main.css')).toIncludeCss(
|
||||
css`
|
||||
@import './imported.css';
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
test('--help', async () => {
|
||||
let { combined } = await $(`${EXECUTABLE} --help`)
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(dedent(combined)).toEqual(
|
||||
dedent(`
|
||||
tailwindcss v${version}
|
||||
|
||||
Usage:
|
||||
tailwindcss build [options]
|
||||
|
||||
Options:
|
||||
-i, --input Input file
|
||||
-o, --output Output file
|
||||
-w, --watch Watch for changes and rebuild as needed
|
||||
-p, --poll Use polling instead of filesystem events when watching
|
||||
--content Content paths to use for removing unused classes
|
||||
-m, --minify Minify the output
|
||||
-c, --config Path to a custom config file
|
||||
-h, --help Display usage information
|
||||
`)
|
||||
)
|
||||
} else if (env.ENGINE === 'stable') {
|
||||
expect(dedent(combined)).toEqual(
|
||||
dedent(`
|
||||
tailwindcss v${version}
|
||||
|
||||
Usage:
|
||||
tailwindcss build [options]
|
||||
|
||||
Options:
|
||||
-i, --input Input file
|
||||
-o, --output Output file
|
||||
-w, --watch Watch for changes and rebuild as needed
|
||||
-p, --poll Use polling instead of filesystem events when watching
|
||||
--content Content paths to use for removing unused classes
|
||||
--postcss Load custom PostCSS configuration
|
||||
-m, --minify Minify the output
|
||||
-c, --config Path to a custom config file
|
||||
--no-autoprefixer Disable autoprefixer
|
||||
-h, --help Display usage information
|
||||
`)
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('Init command', () => {
|
||||
it.each([
|
||||
{ flags: [], name: 'tailwind.config.js' },
|
||||
{ flags: ['--ts'], name: 'tailwind.config.ts' },
|
||||
{ flags: ['--esm'], name: 'tailwind.config.js' },
|
||||
{ flags: ['--full'], name: 'tailwind.config.js' },
|
||||
{ flags: ['--ts', '--full'], name: 'tailwind.config.ts' },
|
||||
{ flags: ['--esm', '--full'], name: 'tailwind.config.js' },
|
||||
])('works with all these flags: %j', async ({ flags, name }) => {
|
||||
cleanupFile(name)
|
||||
await removeFile(name)
|
||||
|
||||
let { combined } = await $(`${EXECUTABLE} init ${flags.join(' ')}`)
|
||||
|
||||
expect(combined).toMatchInlineSnapshot(`
|
||||
"
|
||||
Created Tailwind CSS config file: ${name}
|
||||
"
|
||||
`)
|
||||
|
||||
expect(await fileExists(name)).toBe(true)
|
||||
|
||||
let content = await readOutputFile(`../${name}`)
|
||||
|
||||
if (flags.includes('--ts') || flags.includes('--esm')) {
|
||||
expect(content).toContain('export default')
|
||||
expect(content).not.toContain('module.exports =')
|
||||
} else {
|
||||
expect(content).toContain('module.exports =')
|
||||
expect(content).not.toContain('export default')
|
||||
}
|
||||
|
||||
if (flags.includes('--ts')) {
|
||||
expect(content).toContain('satisfies Config')
|
||||
}
|
||||
|
||||
if (flags.includes('--full')) {
|
||||
expect(content.split('\n').length).toBeGreaterThan(50)
|
||||
}
|
||||
})
|
||||
|
||||
test('--full', async () => {
|
||||
cleanupFile('full.config.js')
|
||||
|
||||
let { combined } = await $(`${EXECUTABLE} init full.config.js --full`)
|
||||
|
||||
expect(combined).toMatchInlineSnapshot(`
|
||||
"
|
||||
Created Tailwind CSS config file: full.config.js
|
||||
"
|
||||
`)
|
||||
|
||||
// Not a clean way to test this. We could require the file and verify that
|
||||
// multiple keys in `theme` exists. However it loads `tailwindcss/colors`
|
||||
// which doesn't exists in this context.
|
||||
expect((await readOutputFile('../full.config.js')).split('\n').length).toBeGreaterThan(50)
|
||||
})
|
||||
|
||||
testStable('--postcss', async () => {
|
||||
expect(await fileExists('postcss.config.js')).toBe(true)
|
||||
await removeFile('postcss.config.js')
|
||||
expect(await fileExists('postcss.config.js')).toBe(false)
|
||||
|
||||
let { combined } = await $(`${EXECUTABLE} init --postcss`)
|
||||
|
||||
expect(await fileExists('postcss.config.js')).toBe(true)
|
||||
|
||||
expect(combined).toMatchInlineSnapshot(`
|
||||
"
|
||||
tailwind.config.js already exists.
|
||||
Created PostCSS config file: postcss.config.js
|
||||
"
|
||||
`)
|
||||
})
|
||||
|
||||
test('--help', async () => {
|
||||
let { combined } = await $(`${EXECUTABLE} init --help`)
|
||||
|
||||
if (env.ENGINE === 'oxide') {
|
||||
expect(dedent(combined)).toEqual(
|
||||
dedent(`
|
||||
tailwindcss v${version}
|
||||
|
||||
Usage:
|
||||
tailwindcss init [options]
|
||||
|
||||
Options:
|
||||
--esm Initialize configuration file as ESM
|
||||
--ts Initialize configuration file as TypeScript
|
||||
-f, --full Include the default values for all options in the generated configuration file
|
||||
-h, --help Display usage information
|
||||
`)
|
||||
)
|
||||
} else if (env.ENGINE === 'stable') {
|
||||
expect(dedent(combined)).toEqual(
|
||||
dedent(`
|
||||
tailwindcss v${version}
|
||||
|
||||
Usage:
|
||||
tailwindcss init [options]
|
||||
|
||||
Options:
|
||||
--esm Initialize configuration file as ESM
|
||||
--ts Initialize configuration file as TypeScript
|
||||
-p, --postcss Initialize a \`postcss.config.js\` file
|
||||
-f, --full Include the default values for all options in the generated configuration file
|
||||
-h, --help Display usage information
|
||||
`)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
test('ESM config is created by default in an ESM project', async () => {
|
||||
cleanupFile('tailwind.config.js')
|
||||
await removeFile('tailwind.config.js')
|
||||
|
||||
let pkg = await readOutputFile('../package.json')
|
||||
|
||||
await writeInputFile(
|
||||
'../package.json',
|
||||
JSON.stringify({
|
||||
...JSON.parse(pkg),
|
||||
type: 'module',
|
||||
})
|
||||
)
|
||||
|
||||
let { combined } = await $(`${EXECUTABLE} init`)
|
||||
|
||||
expect(combined).toMatchInlineSnapshot(`
|
||||
"
|
||||
Created Tailwind CSS config file: tailwind.config.js
|
||||
"
|
||||
`)
|
||||
|
||||
expect(await fileExists('./tailwind.config.js')).toBe(true)
|
||||
|
||||
// Not a clean way to test this.
|
||||
expect(await readOutputFile('../tailwind.config.js')).toContain('export default')
|
||||
|
||||
await writeInputFile('../package.json', pkg)
|
||||
})
|
||||
|
||||
test('CJS config is created by default in a non-ESM project', async () => {
|
||||
cleanupFile('tailwind.config.js')
|
||||
await removeFile('tailwind.config.js')
|
||||
|
||||
let pkg = await readOutputFile('../package.json')
|
||||
|
||||
await writeInputFile(
|
||||
'../package.json',
|
||||
JSON.stringify({
|
||||
...JSON.parse(pkg),
|
||||
})
|
||||
)
|
||||
|
||||
let { combined } = await $(`${EXECUTABLE} init`)
|
||||
|
||||
expect(combined).toMatchInlineSnapshot(`
|
||||
"
|
||||
Created Tailwind CSS config file: tailwind.config.js
|
||||
"
|
||||
`)
|
||||
|
||||
expect(await fileExists('./tailwind.config.js')).toBe(true)
|
||||
|
||||
// Not a clean way to test this.
|
||||
expect(await readOutputFile('../tailwind.config.js')).toContain('module.exports')
|
||||
|
||||
await writeInputFile('../package.json', pkg)
|
||||
})
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
4
integrations/vite/.gitignore
vendored
4
integrations/vite/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
dist/
|
||||
node_modules/
|
||||
!tailwind.config.js
|
||||
!index.html
|
||||
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./index.css">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./index.css">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1 +0,0 @@
|
||||
import './index.css'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user