Skip to content
This repository was archived by the owner on Apr 6, 2021. It is now read-only.

Commit c2551f7

Browse files
committed
WIP
This is hard, no idea if we can make this work, I can't figure out how to share contexts between Vue files that use the same config.
1 parent a3fd913 commit c2551f7

File tree

4 files changed

+78
-12
lines changed

4 files changed

+78
-12
lines changed

src/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,18 @@ module.exports = (configOrPath = {}) => {
3131
})
3232
}
3333

34-
let context = setupContext(configOrPath)(result, root)
34+
// TODO: Maybe we only set up a context + run context dependent plugins
35+
// on files that contain @tailwind rules? I don't know.
36+
let foundTailwind = false
37+
root.walkAtRules('tailwind', (rule) => {
38+
foundTailwind = true
39+
})
40+
41+
let context = null
42+
43+
if (foundTailwind) {
44+
context = setupContext(configOrPath)(result, root)
45+
}
3546

3647
if (context.configPath !== null) {
3748
registerDependency(context.configPath)

src/lib/expandTailwindAtRules.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ function expandTailwindAtRules(context, registerDependency) {
207207
console.log('Changed files: ', context.changedFiles.size)
208208
console.log('Potential classes: ', candidates.size)
209209
console.log('Active contexts: ', sharedState.contextMap.size)
210+
// console.log('Context source map: ', sharedState.contextSourcesMap)
210211
console.log('Content match entries', contentMatchCache.size)
211212
}
212213

src/lib/setupContext.js

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
const fs = require('fs')
2+
const url = require('url')
23
const os = require('os')
34
const path = require('path')
45
const crypto = require('crypto')
56
const chokidar = require('chokidar')
67
const postcss = require('postcss')
8+
const hash = require('object-hash')
79
const dlv = require('dlv')
810
const selectorParser = require('postcss-selector-parser')
911
const LRU = require('quick-lru')
@@ -21,6 +23,8 @@ const { isPlainObject } = require('./utils')
2123
const { isBuffer } = require('util')
2224

2325
let contextMap = sharedState.contextMap
26+
let configContextMap = sharedState.configContextMap
27+
let contextSourcesMap = sharedState.contextSourcesMap
2428
let env = sharedState.env
2529

2630
// Earmarks a directory for our touch files.
@@ -148,27 +152,29 @@ function getTailwindConfig(configOrPath) {
148152
let userConfigPath = resolveConfigPath(configOrPath)
149153

150154
if (userConfigPath !== null) {
151-
let [prevConfig, prevModified = -Infinity] = configPathCache.get(userConfigPath) ?? []
155+
let [prevConfig, prevModified = -Infinity, prevConfigHash] =
156+
configPathCache.get(userConfigPath) ?? []
152157
let modified = fs.statSync(userConfigPath).mtimeMs
153158

154159
// It hasn't changed (based on timestamp)
155160
if (modified <= prevModified) {
156-
return [prevConfig, userConfigPath]
161+
return [prevConfig, userConfigPath, prevConfigHash]
157162
}
158163

159164
// It has changed (based on timestamp), or first run
160165
delete require.cache[userConfigPath]
161166
let newConfig = resolveConfig(require(userConfigPath))
162-
configPathCache.set(userConfigPath, [newConfig, modified])
163-
return [newConfig, userConfigPath]
167+
let newHash = hash(newConfig)
168+
configPathCache.set(userConfigPath, [newConfig, modified, newHash])
169+
return [newConfig, userConfigPath, newHash]
164170
}
165171

166172
// It's a plain object, not a path
167173
let newConfig = resolveConfig(
168174
configOrPath.config === undefined ? configOrPath : configOrPath.config
169175
)
170176

171-
return [newConfig, null]
177+
return [newConfig, null, hash(newConfig)]
172178
}
173179

174180
let fileModifiedMap = new Map()
@@ -177,13 +183,14 @@ function trackModified(files) {
177183
let changed = false
178184

179185
for (let file of files) {
180-
let newModified = fs.statSync(file).mtimeMs
186+
let pathname = url.parse(file).pathname
187+
let newModified = fs.statSync(pathname).mtimeMs
181188

182-
if (!fileModifiedMap.has(file) || newModified > fileModifiedMap.get(file)) {
189+
if (!fileModifiedMap.has(pathname) || newModified > fileModifiedMap.get(pathname)) {
183190
changed = true
184191
}
185192

186-
fileModifiedMap.set(file, newModified)
193+
fileModifiedMap.set(pathname, newModified)
187194
}
188195

189196
return changed
@@ -538,7 +545,7 @@ function cleanupContext(context) {
538545
function setupContext(configOrPath) {
539546
return (result, root) => {
540547
let sourcePath = result.opts.from
541-
let [tailwindConfig, userConfigPath] = getTailwindConfig(configOrPath)
548+
let [tailwindConfig, userConfigPath, tailwindConfigHash] = getTailwindConfig(configOrPath)
542549

543550
let contextDependencies = new Set()
544551
contextDependencies.add(sourcePath)
@@ -557,12 +564,38 @@ function setupContext(configOrPath) {
557564
trackModified([...contextDependencies]) || userConfigPath === null
558565

559566
process.env.DEBUG && console.log('Source path:', sourcePath)
567+
568+
// If this file already has a context in the cache and we don't need to
569+
// reset the context, return the cached context.
560570
if (contextMap.has(sourcePath) && !contextDependenciesChanged) {
561571
return contextMap.get(sourcePath)
562572
}
563573

574+
// If the config file used already exists in the cache, return that.
575+
console.log('dependencies changed: ', contextDependenciesChanged)
576+
console.log(tailwindConfigHash)
577+
console.log(configContextMap.keys())
578+
console.log(configContextMap.has(tailwindConfigHash))
579+
580+
// DAMN YOU CONTEXTDEPENDENCIESCHANGED
581+
// Ideas:
582+
// - Can we incorporate the presence of @tailwind rules somehow? If it has no Tailwind rules, be
583+
// more lenient about the dependencies changing?
584+
if (!contextDependenciesChanged && configContextMap.has(tailwindConfigHash)) {
585+
let context = configContextMap.get(tailwindConfigHash)
586+
contextSourcesMap.get(context).add(sourcePath)
587+
contextMap.set(sourcePath, context)
588+
return context
589+
}
590+
591+
// TODO: Update this to no longer associate this path with its old context
592+
// and clean up that context if no one else is using it.
564593
if (contextMap.has(sourcePath)) {
565-
cleanupContext(contextMap.get(sourcePath))
594+
let oldContext = contextMap.get(sourcePath)
595+
contextSourcesMap.get(oldContext).remove(sourcePath)
596+
if (contextSourcesMap.get(oldContext).size === 0) {
597+
cleanupContext(oldContext)
598+
}
566599
}
567600

568601
process.env.DEBUG && console.log('Setting up new context...')
@@ -579,7 +612,6 @@ function setupContext(configOrPath) {
579612
newPostCssNodeCache: new Map(),
580613
candidateRuleMap: new Map(),
581614
configPath: userConfigPath,
582-
sourcePath: sourcePath,
583615
tailwindConfig: tailwindConfig,
584616
configDependencies: new Set(),
585617
candidateFiles: Array.isArray(tailwindConfig.purge)
@@ -588,8 +620,22 @@ function setupContext(configOrPath) {
588620
variantMap: new Map(),
589621
stylesheetCache: null,
590622
}
623+
624+
// ---
625+
626+
// Update all context tracking state
627+
628+
configContextMap.set(tailwindConfigHash, context)
591629
contextMap.set(sourcePath, context)
592630

631+
if (!contextSourcesMap.has(context)) {
632+
contextSourcesMap.set(context, new Set())
633+
}
634+
635+
contextSourcesMap.get(context).add(sourcePath)
636+
637+
// ---
638+
593639
if (userConfigPath !== null) {
594640
for (let dependency of getModuleDependencies(userConfigPath)) {
595641
if (dependency.file === userConfigPath) {
@@ -600,6 +646,12 @@ function setupContext(configOrPath) {
600646
}
601647
}
602648

649+
let prev = null
650+
for (let [key, value] of contextSourcesMap) {
651+
console.log(key === prev)
652+
prev = key
653+
}
654+
603655
rebootWatcher(context)
604656

605657
let corePluginList = Object.entries(corePlugins)

src/lib/sharedState.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@ module.exports = {
77
DEBUG: process.env.DEBUG !== undefined,
88
},
99
contextMap: new Map(),
10+
configContextMap: new Map(),
11+
contextSourcesMap: new Map(),
1012
contentMatchCache: new LRU({ maxSize: 25000 }),
1113
}

0 commit comments

Comments
 (0)