From 1d809e37a1bbcc6f6f20c2140c663fe28eb4f0b7 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Wed, 3 Mar 2021 11:31:20 +0000 Subject: [PATCH] delete all touch files on module load this has the effect of invalidating any caches associated with these files --- package-lock.json | 24 +++-------------------- package.json | 3 +-- src/index.js | 49 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 22fa295..f0d58ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,8 +15,7 @@ "object-hash": "^2.1.1", "postcss-selector-parser": "^6.0.4", "quick-lru": "^5.1.1", - "tailwindcss": "^2.0.3", - "tmp": "^0.2.1" + "tailwindcss": "^2.0.3" }, "devDependencies": { "@tailwindcss/aspect-ratio": "^0.2.0", @@ -7157,6 +7156,7 @@ "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" }, @@ -8307,17 +8307,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "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", @@ -14409,6 +14398,7 @@ "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" } @@ -15323,14 +15313,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "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", diff --git a/package.json b/package.json index c0b84cd..73d1403 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,7 @@ "object-hash": "^2.1.1", "postcss-selector-parser": "^6.0.4", "quick-lru": "^5.1.1", - "tailwindcss": "^2.0.3", - "tmp": "^0.2.1" + "tailwindcss": "^2.0.3" }, "peerDependencies": { "postcss": "^8.2.6" diff --git a/src/index.js b/src/index.js index 8d512dd..006eaa6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,8 @@ const fs = require('fs') const path = require('path') +const os = require('os') +const crypto = require('crypto') -const tmp = require('tmp') const postcss = require('postcss') const chokidar = require('chokidar') const fastGlob = require('fast-glob') @@ -33,6 +34,22 @@ function sign(bigIntValue) { // --- +// Earmarks a directory for our touch files. +// If the directory already exists we delete any existing touch files, +// invalidating any caches associated with them. + +const touchDir = path.join(os.homedir() || os.tmpdir(), '.tailwindcss', 'touch') + +if (fs.existsSync(touchDir)) { + for (let file of fs.readdirSync(touchDir)) { + fs.unlinkSync(path.join(touchDir, file)) + } +} 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). @@ -322,6 +339,25 @@ function cleanupContext(context) { contextSources.delete(context) } +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}`) +} + function rebootTemplateWatcher(context) { if (env.TAILWIND_MODE === 'build') { return @@ -331,7 +367,10 @@ function rebootTemplateWatcher(context) { env.TAILWIND_MODE === 'watch' || (env.TAILWIND_MODE === undefined && env.NODE_ENV === 'development') ) { - context.touchFile = context.touchFile !== null ? context.touchFile : tmp.fileSync() + if (context.touchFile === null) { + context.touchFile = generateTouchFileName() + touch(context.touchFile) + } Promise.resolve(context.watcher ? context.watcher.close() : null).then(() => { context.watcher = chokidar.watch(context.candidateFiles, { @@ -340,12 +379,12 @@ function rebootTemplateWatcher(context) { context.watcher.on('add', (file) => { context.changedFiles.add(path.resolve('.', file)) - touch(context.touchFile.name) + touch(context.touchFile) }) context.watcher.on('change', (file) => { context.changedFiles.add(path.resolve('.', file)) - touch(context.touchFile.name) + touch(context.touchFile) }) }) } @@ -951,7 +990,7 @@ module.exports = (pluginOptions = {}) => { // Register our temp file as a dependency — we write to this file // to trigger rebuilds. if (context.touchFile) { - registerDependency(context.touchFile.name) + registerDependency(context.touchFile) } // If we're not set up and watching files ourselves, we need to do