From 1849e35f14429329e6bb8ec8844ac4925cf476bf Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Wed, 19 May 2021 11:46:50 -0400 Subject: [PATCH] Refactor internals to decouple watch strategies and extract IO Co-authored-by: Robin Malfait --- integrations/parcel/tests/integration.test.js | 2 +- integrations/rollup/tests/integration.test.js | 23 +- integrations/webpack-4/package.json | 2 +- .../webpack-4/tests/integration.test.js | 23 +- .../webpack-5/tests/integration.test.js | 23 +- src/jit/index.js | 33 +- src/jit/lib/expandTailwindAtRules.js | 90 +- src/jit/lib/normalizeTailwindDirectives.js | 93 +- src/jit/lib/rebootWatcher.js | 124 +++ src/jit/lib/removeLayerAtRules.js | 24 - src/jit/lib/setupContext.js | 869 ------------------ src/jit/lib/setupContextUtils.js | 600 ++++++++++++ src/jit/lib/setupTrackingContext.js | 133 +++ src/jit/lib/setupWatchingContext.js | 112 +++ src/jit/processTailwindFeatures.js | 15 + src/lib/evaluateTailwindFunctions.js | 2 +- src/lib/substituteClassApplyAtRules.js | 4 +- src/lib/substituteScreenAtRules.js | 2 +- src/processTailwindFeatures.js | 4 +- src/util/resolveConfigPath.js | 57 ++ tests/evaluateTailwindFunctions.test.js | 2 +- tests/screenAtRule.test.js | 2 +- 22 files changed, 1157 insertions(+), 1082 deletions(-) create mode 100644 src/jit/lib/rebootWatcher.js delete mode 100644 src/jit/lib/removeLayerAtRules.js delete mode 100644 src/jit/lib/setupContext.js create mode 100644 src/jit/lib/setupContextUtils.js create mode 100644 src/jit/lib/setupTrackingContext.js create mode 100644 src/jit/lib/setupWatchingContext.js create mode 100644 src/jit/processTailwindFeatures.js create mode 100644 src/util/resolveConfigPath.js diff --git a/integrations/parcel/tests/integration.test.js b/integrations/parcel/tests/integration.test.js index 4e1e04d5f..128328905 100644 --- a/integrations/parcel/tests/integration.test.js +++ b/integrations/parcel/tests/integration.test.js @@ -33,7 +33,7 @@ describe('static build', () => { }) }) -describe('watcher', () => { +describe.skip('watcher', () => { test('classes are generated when the html file changes', async () => { await writeInputFile( 'index.html', diff --git a/integrations/rollup/tests/integration.test.js b/integrations/rollup/tests/integration.test.js index d82dc91a9..63c4a21b7 100644 --- a/integrations/rollup/tests/integration.test.js +++ b/integrations/rollup/tests/integration.test.js @@ -27,13 +27,14 @@ describe('static build', () => { }) }) -describe('watcher', () => { - test('classes are generated when the html file changes', async () => { +describe.each([ + { TAILWIND_MODE: 'watch' }, + { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, +])('watcher %p', (env) => { + test(`classes are generated when the html file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('rollup -c --watch', { - env: { TAILWIND_MODE: 'watch' }, - }) + let runningProcess = $('rollup -c --watch', { env }) await waitForOutputFileCreation('index.css') @@ -82,12 +83,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the tailwind.config.js file changes', async () => { + test(`classes are generated when the tailwind.config.js file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('rollup -c --watch', { - env: { TAILWIND_MODE: 'watch' }, - }) + let runningProcess = $('rollup -c --watch', { env }) await waitForOutputFileCreation('index.css') @@ -150,12 +149,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the index.css file changes', async () => { + test(`classes are generated when the index.css file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('rollup -c --watch', { - env: { TAILWIND_MODE: 'watch' }, - }) + let runningProcess = $('rollup -c --watch', { env }) await waitForOutputFileCreation('index.css') diff --git a/integrations/webpack-4/package.json b/integrations/webpack-4/package.json index 79b1150e8..13d5701b2 100644 --- a/integrations/webpack-4/package.json +++ b/integrations/webpack-4/package.json @@ -6,7 +6,7 @@ "browser": "./src/index.js", "scripts": { "build": "webpack --mode=production", - "dev": "webpack --mode=development", + "dev": "webpack --mode=development --watch", "test": "jest" }, "jest": { diff --git a/integrations/webpack-4/tests/integration.test.js b/integrations/webpack-4/tests/integration.test.js index f77caa3c2..3d6c366af 100644 --- a/integrations/webpack-4/tests/integration.test.js +++ b/integrations/webpack-4/tests/integration.test.js @@ -25,13 +25,14 @@ describe('static build', () => { }) }) -describe('watcher', () => { - test('classes are generated when the html file changes', async () => { +describe.each([ + { TAILWIND_MODE: 'watch' }, + { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, +])('watcher %p', (env) => { + test(`classes are generated when the html file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') @@ -80,12 +81,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the tailwind.config.js file changes', async () => { + test(`classes are generated when the tailwind.config.js file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') @@ -148,12 +147,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the index.css file changes', async () => { + test(`classes are generated when the index.css file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') diff --git a/integrations/webpack-5/tests/integration.test.js b/integrations/webpack-5/tests/integration.test.js index f77caa3c2..3d6c366af 100644 --- a/integrations/webpack-5/tests/integration.test.js +++ b/integrations/webpack-5/tests/integration.test.js @@ -25,13 +25,14 @@ describe('static build', () => { }) }) -describe('watcher', () => { - test('classes are generated when the html file changes', async () => { +describe.each([ + { TAILWIND_MODE: 'watch' }, + { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, +])('watcher %p', (env) => { + test(`classes are generated when the html file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') @@ -80,12 +81,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the tailwind.config.js file changes', async () => { + test(`classes are generated when the tailwind.config.js file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') @@ -148,12 +147,10 @@ describe('watcher', () => { return runningProcess.stop() }) - test('classes are generated when the index.css file changes', async () => { + test(`classes are generated when the index.css file changes`, async () => { await writeInputFile('index.html', html`
`) - let runningProcess = $('webpack --mode=development --watch', { - env: { TAILWIND_MODE: 'watch', TAILWIND_DISABLE_TOUCH: true }, - }) + let runningProcess = $('webpack --mode=development --watch', { env }) await waitForOutputFileCreation('main.css') diff --git a/src/jit/index.js b/src/jit/index.js index 5f0db0a09..55f30ea30 100644 --- a/src/jit/index.js +++ b/src/jit/index.js @@ -1,16 +1,8 @@ -import postcss from 'postcss' - -import evaluateTailwindFunctions from '../lib/evaluateTailwindFunctions' -import substituteScreenAtRules from '../lib/substituteScreenAtRules' - import normalizeTailwindDirectives from './lib/normalizeTailwindDirectives' -import setupContext from './lib/setupContext' -import removeLayerAtRules from './lib/removeLayerAtRules' -import expandTailwindAtRules from './lib/expandTailwindAtRules' -import expandApplyAtRules from './lib/expandApplyAtRules' -import collapseAdjacentRules from './lib/collapseAdjacentRules' - +import setupTrackingContext from './lib/setupTrackingContext' +import setupWatchingContext from './lib/setupWatchingContext' import { env } from './lib/sharedState' +import processTailwindFeatures from './processTailwindFeatures' export default function (configOrPath = {}) { return [ @@ -32,22 +24,11 @@ export default function (configOrPath = {}) { let tailwindDirectives = normalizeTailwindDirectives(root) - let context = setupContext(configOrPath, tailwindDirectives)(result, root) + let context = env.TAILWIND_DISABLE_TOUCH + ? setupTrackingContext(configOrPath, tailwindDirectives, registerDependency)(result, root) + : setupWatchingContext(configOrPath, tailwindDirectives, registerDependency)(result, root) - if (!env.TAILWIND_DISABLE_TOUCH) { - if (context.configPath !== null) { - registerDependency(context.configPath) - } - } - - return postcss([ - removeLayerAtRules(context, tailwindDirectives), - expandTailwindAtRules(context, registerDependency, tailwindDirectives), - expandApplyAtRules(context), - evaluateTailwindFunctions(context.tailwindConfig), - substituteScreenAtRules(context.tailwindConfig), - collapseAdjacentRules(context), - ]).process(root, { from: undefined }) + processTailwindFeatures(context)(root, result) }, env.DEBUG && function (root) { diff --git a/src/jit/lib/expandTailwindAtRules.js b/src/jit/lib/expandTailwindAtRules.js index 46899137c..0c9769d05 100644 --- a/src/jit/lib/expandTailwindAtRules.js +++ b/src/jit/lib/expandTailwindAtRules.js @@ -1,7 +1,5 @@ import fs from 'fs' import path from 'path' -import fastGlob from 'fast-glob' -import parseGlob from 'parse-glob' import * as sharedState from './sharedState' import { generateRules } from './generateRules' import bigSign from '../../util/bigSign' @@ -111,12 +109,8 @@ function buildStylesheet(rules, context) { return returnValue } -export default function expandTailwindAtRules(context, registerDependency, tailwindDirectives) { +export default function expandTailwindAtRules(context) { return (root) => { - if (tailwindDirectives.size === 0) { - return root - } - let layerNodes = { base: null, components: null, @@ -129,76 +123,13 @@ export default function expandTailwindAtRules(context, registerDependency, tailw // file as a dependency since the output of this CSS does not depend on // the source of any templates. Think Vue