From ba73b0c62c3a3993db965ca4cc808f577f04a1ca Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 15 Jun 2021 13:33:37 +0200 Subject: [PATCH 1/4] use `~/.cache/tailwindcss` as default touch dir When more tools catch up with the latest postcss dependency tracking, then we probably don't even need this anymore. However, it is a good practice to put (global) caches in ~/.cache and (global) configs in ~/.config Fixes: #4569 --- src/jit/lib/setupWatchingContext.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jit/lib/setupWatchingContext.js b/src/jit/lib/setupWatchingContext.js index 84c661c52df8..9f61f0c40f54 100644 --- a/src/jit/lib/setupWatchingContext.js +++ b/src/jit/lib/setupWatchingContext.js @@ -20,7 +20,7 @@ import { env } from './sharedState' // If the directory already exists we delete any existing touch files, // invalidating any caches associated with them. let touchDir = - env.TAILWIND_TOUCH_DIR || path.join(os.homedir() || os.tmpdir(), '.tailwindcss', 'touch') + env.TAILWIND_TOUCH_DIR || path.join(os.homedir() || os.tmpdir(), '.cache', 'tailwindcss', 'touch') if (env.TAILWIND_MODE === 'watch') { if (fs.existsSync(touchDir)) { From 49e996aebd1e07ef370d43b7c9b6e92ec670d881 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 11 Jun 2021 16:16:35 +0200 Subject: [PATCH 2/4] change test to verify @tailwind base slightly Because of some changes in tailwind itself, the base selector contains a ton of new --tw-* custom properties. Keeping this up to date might be a bit of an annoying challenge. So instead we now check for the selector to be present. --- integrations/tailwindcss-cli/tests/cli.test.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/integrations/tailwindcss-cli/tests/cli.test.js b/integrations/tailwindcss-cli/tests/cli.test.js index 85c9316262cd..bf76f461baa4 100644 --- a/integrations/tailwindcss-cli/tests/cli.test.js +++ b/integrations/tailwindcss-cli/tests/cli.test.js @@ -21,16 +21,10 @@ describe('Build command', () => { // `-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).toIncludeCss( - css` - *, - ::before, - ::after { - --tw-border-opacity: 1; - border-color: rgba(229, 231, 235, var(--tw-border-opacity)); - } - ` - ) + expect(contents).toContain('*') + expect(contents).toContain('::before') + expect(contents).toContain('::after') + expect(contents).toContain('--tw-shadow') // Verify `utilities` output is correct expect(contents).toIncludeCss( From 9c93a51b57a7145725223ed7b1946ac8271ba5d3 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 15 Jun 2021 15:22:40 +0200 Subject: [PATCH 3/4] add `tmp` package --- package-lock.json | 58 +++++++++++++++++++++++++++++++++++------------ package.json | 3 ++- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index e0033bbf2625..4a4c833cd90c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "tailwindcss", "version": "2.1.2", "license": "MIT", "dependencies": { @@ -38,7 +37,8 @@ "pretty-hrtime": "^1.0.3", "quick-lru": "^5.1.1", "reduce-css-calc": "^2.1.8", - "resolve": "^1.20.0" + "resolve": "^1.20.0", + "tmp": "^0.2.1" }, "bin": { "tailwind": "lib/cli.js", @@ -8775,7 +8775,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -9543,6 +9542,17 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -11785,7 +11795,8 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/@tailwindcss/aspect-ratio/-/aspect-ratio-0.2.1.tgz", "integrity": "sha512-aDFi80aHQ3JM3symJ5iKU70lm151ugIGFCI0yRZGpyjgQSDS+Fbe93QwypC1tCEllQE8p0S7TUu20ih1b9IKLA==", - "dev": true + "dev": true, + "requires": {} }, "@tootallnate/once": { "version": "1.1.2", @@ -11941,7 +11952,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "acorn-node": { "version": "1.8.2", @@ -12927,7 +12939,8 @@ "cssnano-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-2.0.1.tgz", - "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==" + "integrity": "sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==", + "requires": {} }, "csso": { "version": "4.2.0", @@ -13401,7 +13414,8 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-prettier": { "version": "3.4.0", @@ -15030,7 +15044,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "27.0.1", @@ -16239,22 +16254,26 @@ "postcss-discard-comments": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz", - "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==" + "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==", + "requires": {} }, "postcss-discard-duplicates": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz", - "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==" + "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==", + "requires": {} }, "postcss-discard-empty": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz", - "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==" + "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==", + "requires": {} }, "postcss-discard-overridden": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz", - "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==" + "integrity": "sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==", + "requires": {} }, "postcss-js": { "version": "3.0.3", @@ -16346,7 +16365,8 @@ "postcss-normalize-charset": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz", - "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==" + "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==", + "requires": {} }, "postcss-normalize-display-values": { "version": "5.0.1", @@ -16864,7 +16884,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -17478,6 +17497,14 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -17905,7 +17932,8 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index 1e64035ca8d5..bb2737073261 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,8 @@ "pretty-hrtime": "^1.0.3", "quick-lru": "^5.1.1", "reduce-css-calc": "^2.1.8", - "resolve": "^1.20.0" + "resolve": "^1.20.0", + "tmp": "^0.2.1" }, "browserslist": [ "> 1%", From cc0efb0dbc8e3f084c1adb926f96a60687dbc5a4 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Tue, 15 Jun 2021 15:22:58 +0200 Subject: [PATCH 4/4] use a (simple) temporary file, instead of a full cache dir --- src/jit/lib/setupWatchingContext.js | 43 ++--------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/src/jit/lib/setupWatchingContext.js b/src/jit/lib/setupWatchingContext.js index 9f61f0c40f54..b7f5c198981f 100644 --- a/src/jit/lib/setupWatchingContext.js +++ b/src/jit/lib/setupWatchingContext.js @@ -1,8 +1,7 @@ import fs from 'fs' import path from 'path' -import crypto from 'crypto' -import os from 'os' +import tmp from 'tmp' import chokidar from 'chokidar' import fastGlob from 'fast-glob' import LRU from 'quick-lru' @@ -14,25 +13,6 @@ import getModuleDependencies from '../../lib/getModuleDependencies' import resolveConfig from '../../../resolveConfig' import resolveConfigPath from '../../util/resolveConfigPath' import { getContext } from './setupContextUtils' -import { env } from './sharedState' - -// Earmarks a directory for our touch files. -// If the directory already exists we delete any existing touch files, -// invalidating any caches associated with them. -let touchDir = - env.TAILWIND_TOUCH_DIR || path.join(os.homedir() || os.tmpdir(), '.cache', 'tailwindcss', 'touch') - -if (env.TAILWIND_MODE === 'watch') { - if (fs.existsSync(touchDir)) { - for (let file of fs.readdirSync(touchDir)) { - try { - fs.unlinkSync(path.join(touchDir, file)) - } catch (_err) {} - } - } else { - fs.mkdirSync(touchDir, { recursive: true }) - } -} // This is used to trigger rebuilds. Just updating the timestamp // is significantly faster than actually writing to the file (10x). @@ -89,7 +69,7 @@ function rebootWatcher(context, configPath, configDependencies, candidateFiles) let touchFile = getTouchFile(context) if (touchFile === null) { - touchFile = generateTouchFileName() + touchFile = tmp.fileSync().name setTouchFile(context, touchFile) touch(touchFile) } @@ -148,25 +128,6 @@ function rebootWatcher(context, configPath, configDependencies, candidateFiles) }) } -function generateTouchFileName() { - let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' - let randomChars = '' - let randomCharsLength = 12 - let bytes = null - - try { - bytes = crypto.randomBytes(randomCharsLength) - } catch (_error) { - bytes = crypto.pseudoRandomBytes(randomCharsLength) - } - - for (let i = 0; i < randomCharsLength; i++) { - randomChars += chars[bytes[i] % chars.length] - } - - return path.join(touchDir, `touch-${process.pid}-${randomChars}`) -} - let configPathCache = new LRU({ maxSize: 100 }) let configDependenciesCache = new WeakMap()