tailwindcss 0.0.0-insiders.ea10bb9 → 0.0.0-insiders.ea4e1cd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/cli/build/deps.js +17 -9
- package/lib/cli/build/index.js +20 -10
- package/lib/cli/build/plugin.js +86 -70
- package/lib/cli/build/utils.js +18 -8
- package/lib/cli/build/watching.js +16 -12
- package/lib/cli/help/index.js +6 -4
- package/lib/cli/index.js +222 -10
- package/lib/cli/init/index.js +29 -12
- package/lib/cli-peer-dependencies.js +12 -4
- package/lib/cli.js +4 -226
- package/lib/corePluginList.js +7 -1
- package/lib/corePlugins.js +348 -75
- package/lib/css/preflight.css +2 -0
- package/lib/featureFlags.js +27 -15
- package/lib/index.js +1 -47
- package/lib/lib/cacheInvalidation.js +7 -5
- package/lib/lib/collapseAdjacentRules.js +5 -3
- package/lib/lib/collapseDuplicateDeclarations.js +12 -10
- package/lib/lib/content.js +34 -30
- package/lib/lib/defaultExtractor.js +15 -8
- package/lib/lib/detectNesting.js +10 -2
- package/lib/lib/evaluateTailwindFunctions.js +22 -20
- package/lib/lib/expandApplyAtRules.js +43 -35
- package/lib/lib/expandTailwindAtRules.js +46 -19
- package/lib/lib/findAtConfigPath.js +9 -7
- package/lib/lib/generateRules.js +157 -92
- package/lib/lib/getModuleDependencies.js +85 -37
- package/lib/lib/load-config.js +42 -0
- package/lib/lib/normalizeTailwindDirectives.js +5 -3
- package/lib/lib/offsets.js +93 -4
- package/lib/lib/partitionApplyAtRules.js +3 -1
- package/lib/lib/regex.js +21 -7
- package/lib/lib/remap-bitfield.js +89 -0
- package/lib/lib/resolveDefaultsAtRules.js +28 -24
- package/lib/lib/setupContextUtils.js +190 -131
- package/lib/lib/setupTrackingContext.js +49 -26
- package/lib/lib/sharedState.js +37 -10
- package/lib/lib/substituteScreenAtRules.js +5 -3
- package/lib/oxide/cli/build/deps.js +89 -0
- package/lib/oxide/cli/build/index.js +53 -0
- package/lib/oxide/cli/build/plugin.js +375 -0
- package/lib/oxide/cli/build/utils.js +87 -0
- package/lib/oxide/cli/build/watching.js +179 -0
- package/lib/oxide/cli/help/index.js +72 -0
- package/lib/oxide/cli/index.js +214 -0
- package/lib/oxide/cli/init/index.js +52 -0
- package/lib/oxide/cli.js +5 -0
- package/lib/oxide/postcss-plugin.js +2 -0
- package/lib/plugin.js +98 -0
- package/lib/postcss-plugins/nesting/index.js +3 -1
- package/lib/postcss-plugins/nesting/plugin.js +10 -8
- package/lib/processTailwindFeatures.js +14 -12
- package/lib/public/colors.js +49 -25
- package/lib/public/create-plugin.js +5 -3
- package/lib/public/default-config.js +6 -4
- package/lib/public/default-theme.js +6 -4
- package/lib/public/load-config.js +12 -0
- package/lib/public/resolve-config.js +6 -4
- package/lib/util/applyImportantSelector.js +36 -0
- package/lib/util/bigSign.js +3 -1
- package/lib/util/buildMediaQuery.js +3 -1
- package/lib/util/cloneDeep.js +3 -1
- package/lib/util/cloneNodes.js +5 -3
- package/lib/util/color.js +30 -12
- package/lib/util/colorNames.js +752 -0
- package/lib/util/configurePlugins.js +3 -1
- package/lib/util/createPlugin.js +3 -1
- package/lib/util/createUtilityPlugin.js +7 -5
- package/lib/util/dataTypes.js +74 -17
- package/lib/util/defaults.js +9 -7
- package/lib/util/escapeClassName.js +10 -8
- package/lib/util/escapeCommas.js +3 -1
- package/lib/util/flattenColorPalette.js +3 -1
- package/lib/util/formatVariantSelector.js +138 -160
- package/lib/util/getAllConfigs.js +8 -6
- package/lib/util/hashConfig.js +6 -4
- package/lib/util/isKeyframeRule.js +3 -1
- package/lib/util/isPlainObject.js +3 -1
- package/lib/util/isSyntacticallyValidPropertyValue.js +3 -1
- package/lib/util/log.js +8 -4
- package/lib/util/nameClass.js +12 -6
- package/lib/util/negateValue.js +4 -2
- package/lib/util/normalizeConfig.js +28 -27
- package/lib/util/normalizeScreens.js +12 -4
- package/lib/util/parseAnimationValue.js +3 -1
- package/lib/util/parseBoxShadowValue.js +6 -2
- package/lib/util/parseDependency.js +3 -1
- package/lib/util/parseGlob.js +6 -4
- package/lib/util/parseObjectStyles.js +9 -7
- package/lib/util/pluginUtils.js +54 -54
- package/lib/util/prefixSelector.js +27 -11
- package/lib/util/pseudoElements.js +229 -0
- package/lib/util/removeAlphaVariables.js +3 -1
- package/lib/util/resolveConfig.js +17 -15
- package/lib/util/resolveConfigPath.js +26 -10
- package/lib/util/responsive.js +6 -4
- package/lib/util/splitAtTopLevelOnly.js +10 -2
- package/lib/util/tap.js +3 -1
- package/lib/util/toColorValue.js +3 -1
- package/lib/util/toPath.js +3 -1
- package/lib/util/transformThemeValue.js +6 -4
- package/lib/util/validateConfig.js +16 -3
- package/lib/util/validateFormalSyntax.js +3 -1
- package/lib/util/withAlphaVariable.js +6 -2
- package/loadConfig.d.ts +4 -0
- package/loadConfig.js +2 -0
- package/package.json +45 -37
- package/peers/index.js +63324 -46417
- package/resolveConfig.d.ts +11 -2
- package/scripts/swap-engines.js +40 -0
- package/src/cli/build/index.js +13 -9
- package/src/cli/build/plugin.js +42 -32
- package/src/cli/build/watching.js +4 -2
- package/src/cli/index.js +216 -3
- package/src/cli/init/index.js +37 -8
- package/src/cli.js +4 -220
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +207 -32
- package/src/css/preflight.css +2 -0
- package/src/featureFlags.js +6 -0
- package/src/index.js +1 -47
- package/src/lib/content.js +12 -17
- package/src/lib/defaultExtractor.js +9 -3
- package/src/lib/detectNesting.js +9 -1
- package/src/lib/expandApplyAtRules.js +8 -1
- package/src/lib/expandTailwindAtRules.js +36 -7
- package/src/lib/generateRules.js +124 -42
- package/src/lib/getModuleDependencies.js +70 -30
- package/src/lib/load-config.ts +31 -0
- package/src/lib/offsets.js +104 -1
- package/src/lib/remap-bitfield.js +82 -0
- package/src/lib/setupContextUtils.js +103 -54
- package/src/lib/setupTrackingContext.js +36 -11
- package/src/lib/sharedState.js +15 -4
- package/src/oxide/cli/build/deps.ts +91 -0
- package/src/oxide/cli/build/index.ts +47 -0
- package/src/oxide/cli/build/plugin.ts +442 -0
- package/src/oxide/cli/build/utils.ts +74 -0
- package/src/oxide/cli/build/watching.ts +225 -0
- package/src/oxide/cli/help/index.ts +69 -0
- package/src/oxide/cli/index.ts +204 -0
- package/src/oxide/cli/init/index.ts +59 -0
- package/src/oxide/cli.ts +1 -0
- package/src/oxide/postcss-plugin.ts +1 -0
- package/src/plugin.js +107 -0
- package/src/public/colors.js +22 -0
- package/src/public/default-config.js +1 -1
- package/src/public/default-theme.js +2 -2
- package/src/public/load-config.js +2 -0
- package/src/util/applyImportantSelector.js +27 -0
- package/src/util/color.js +18 -3
- package/src/util/colorNames.js +150 -0
- package/src/util/dataTypes.js +33 -4
- package/src/util/formatVariantSelector.js +160 -163
- package/src/util/getAllConfigs.js +2 -2
- package/src/util/negateValue.js +1 -1
- package/src/util/normalizeConfig.js +2 -1
- package/src/util/pluginUtils.js +16 -31
- package/src/util/prefixSelector.js +28 -10
- package/src/util/pseudoElements.js +170 -0
- package/src/util/resolveConfigPath.js +12 -1
- package/src/util/splitAtTopLevelOnly.js +8 -1
- package/src/util/validateConfig.js +13 -0
- package/stubs/.gitignore +1 -0
- package/stubs/.prettierrc.json +6 -0
- package/stubs/{defaultConfig.stub.js → config.full.js} +183 -146
- package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -1
- package/stubs/postcss.config.js +6 -0
- package/stubs/tailwind.config.cjs +2 -0
- package/stubs/tailwind.config.js +2 -0
- package/stubs/tailwind.config.ts +3 -0
- package/types/config.d.ts +15 -9
- package/types/generated/colors.d.ts +22 -0
- package/types/generated/corePluginList.d.ts +1 -1
- package/types/generated/default-theme.d.ts +108 -79
- package/CHANGELOG.md +0 -2336
- package/lib/cli/shared.js +0 -12
- package/lib/constants.js +0 -44
- package/scripts/install-integrations.js +0 -27
- package/scripts/rebuildFixtures.js +0 -68
- package/src/cli/shared.js +0 -5
- package/src/constants.js +0 -17
- /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* We must remap all the old bits to new bits for each set variant
|
|
5
|
+
* Only arbitrary variants are considered as those are the only
|
|
6
|
+
* ones that need to be re-sorted at this time
|
|
7
|
+
*
|
|
8
|
+
* An iterated process that removes and sets individual bits simultaneously
|
|
9
|
+
* will not work because we may have a new bit that is also a later old bit
|
|
10
|
+
* This means that we would be removing a previously set bit which we don't
|
|
11
|
+
* want to do
|
|
12
|
+
*
|
|
13
|
+
* For example (assume `bN` = `1<<N`)
|
|
14
|
+
* Given the "total" mapping `[[b1, b3], [b2, b4], [b3, b1], [b4, b2]]`
|
|
15
|
+
* The mapping is "total" because:
|
|
16
|
+
* 1. Every input and output is accounted for
|
|
17
|
+
* 2. All combinations are unique
|
|
18
|
+
* 3. No one input maps to multiple outputs and vice versa
|
|
19
|
+
* And, given an offset with all bits set:
|
|
20
|
+
* V = b1 | b2 | b3 | b4
|
|
21
|
+
*
|
|
22
|
+
* Let's explore the issue with removing and setting bits simultaneously:
|
|
23
|
+
* V & ~b1 | b3 = b2 | b3 | b4
|
|
24
|
+
* V & ~b2 | b4 = b3 | b4
|
|
25
|
+
* V & ~b3 | b1 = b1 | b4
|
|
26
|
+
* V & ~b4 | b2 = b1 | b2
|
|
27
|
+
*
|
|
28
|
+
* As you can see, we end up with the wrong result.
|
|
29
|
+
* This is because we're removing a bit that was previously set.
|
|
30
|
+
* And, thus the final result is missing b3 and b4.
|
|
31
|
+
*
|
|
32
|
+
* Now, let's explore the issue with removing the bits first:
|
|
33
|
+
* V & ~b1 = b2 | b3 | b4
|
|
34
|
+
* V & ~b2 = b3 | b4
|
|
35
|
+
* V & ~b3 = b4
|
|
36
|
+
* V & ~b4 = 0
|
|
37
|
+
*
|
|
38
|
+
* And then setting the bits:
|
|
39
|
+
* V | b3 = b3
|
|
40
|
+
* V | b4 = b3 | b4
|
|
41
|
+
* V | b1 = b1 | b3 | b4
|
|
42
|
+
* V | b2 = b1 | b2 | b3 | b4
|
|
43
|
+
*
|
|
44
|
+
* We get the correct result because we're not removing any bits that were
|
|
45
|
+
* previously set thus properly remapping the bits to the new order
|
|
46
|
+
*
|
|
47
|
+
* To collect this into a single operation that can be done simultaneously
|
|
48
|
+
* we must first create a mask for the old bits that are set and a mask for
|
|
49
|
+
* the new bits that are set. Then we can remove the old bits and set the new
|
|
50
|
+
* bits simultaneously in a "single" operation like so:
|
|
51
|
+
* OldMask = b1 | b2 | b3 | b4
|
|
52
|
+
* NewMask = b3 | b4 | b1 | b2
|
|
53
|
+
*
|
|
54
|
+
* So this:
|
|
55
|
+
* V & ~oldMask | newMask
|
|
56
|
+
*
|
|
57
|
+
* Expands to this:
|
|
58
|
+
* V & ~b1 & ~b2 & ~b3 & ~b4 | b3 | b4 | b1 | b2
|
|
59
|
+
*
|
|
60
|
+
* Which becomes this:
|
|
61
|
+
* b1 | b2 | b3 | b4
|
|
62
|
+
*
|
|
63
|
+
* Which is the correct result!
|
|
64
|
+
*
|
|
65
|
+
* @param {bigint} num
|
|
66
|
+
* @param {[bigint, bigint][]} mapping
|
|
67
|
+
*/
|
|
68
|
+
export function remapBitfield(num, mapping) {
|
|
69
|
+
// Create masks for the old and new bits that are set
|
|
70
|
+
let oldMask = 0n
|
|
71
|
+
let newMask = 0n
|
|
72
|
+
for (let [oldBit, newBit] of mapping) {
|
|
73
|
+
if (num & oldBit) {
|
|
74
|
+
oldMask = oldMask | oldBit
|
|
75
|
+
newMask = newMask | newBit
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Remove all old bits
|
|
80
|
+
// Set all new bits
|
|
81
|
+
return (num & ~oldMask) | newMask
|
|
82
|
+
}
|
|
@@ -54,32 +54,50 @@ function normalizeOptionTypes({ type = 'any', ...options }) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function parseVariantFormatString(input) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
57
|
+
/** @type {string[]} */
|
|
58
|
+
let parts = []
|
|
59
|
+
|
|
60
|
+
// When parsing whitespace around special characters are insignificant
|
|
61
|
+
// However, _inside_ of a variant they could be
|
|
62
|
+
// Because the selector could look like this
|
|
63
|
+
// @media { &[data-name="foo bar"] }
|
|
64
|
+
// This is why we do not skip whitespace
|
|
65
|
+
|
|
66
|
+
let current = ''
|
|
67
|
+
let depth = 0
|
|
68
|
+
|
|
69
|
+
for (let idx = 0; idx < input.length; idx++) {
|
|
70
|
+
let char = input[idx]
|
|
71
|
+
|
|
72
|
+
if (char === '\\') {
|
|
73
|
+
// Escaped characters are not special
|
|
74
|
+
current += '\\' + input[++idx]
|
|
75
|
+
} else if (char === '{') {
|
|
76
|
+
// Nested rule: start
|
|
77
|
+
++depth
|
|
78
|
+
parts.push(current.trim())
|
|
79
|
+
current = ''
|
|
75
80
|
} else if (char === '}') {
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
// Nested rule: end
|
|
82
|
+
if (--depth < 0) {
|
|
83
|
+
throw new Error(`Your { and } are unbalanced.`)
|
|
78
84
|
}
|
|
85
|
+
|
|
86
|
+
parts.push(current.trim())
|
|
87
|
+
current = ''
|
|
88
|
+
} else {
|
|
89
|
+
// Normal character
|
|
90
|
+
current += char
|
|
79
91
|
}
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
|
|
94
|
+
if (current.length > 0) {
|
|
95
|
+
parts.push(current.trim())
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
parts = parts.filter((part) => part !== '')
|
|
99
|
+
|
|
100
|
+
return parts
|
|
83
101
|
}
|
|
84
102
|
|
|
85
103
|
function insertInto(list, value, { before = [] } = {}) {
|
|
@@ -253,25 +271,18 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
253
271
|
}
|
|
254
272
|
|
|
255
273
|
function resolveThemeValue(path, defaultValue, opts = {}) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return transformThemeValue(
|
|
274
|
+
let parts = toPath(path)
|
|
275
|
+
let value = getConfigValue(['theme', ...parts], defaultValue)
|
|
276
|
+
return transformThemeValue(parts[0])(value, opts)
|
|
259
277
|
}
|
|
260
278
|
|
|
261
|
-
const theme = Object.assign(
|
|
262
|
-
(path, defaultValue = undefined) => resolveThemeValue(path, defaultValue),
|
|
263
|
-
{
|
|
264
|
-
withAlpha: (path, opacityValue) => resolveThemeValue(path, undefined, { opacityValue }),
|
|
265
|
-
}
|
|
266
|
-
)
|
|
267
|
-
|
|
268
279
|
let variantIdentifier = 0
|
|
269
280
|
let api = {
|
|
270
281
|
postcss,
|
|
271
282
|
prefix: applyConfiguredPrefix,
|
|
272
283
|
e: escapeClassName,
|
|
273
284
|
config: getConfigValue,
|
|
274
|
-
theme,
|
|
285
|
+
theme: resolveThemeValue,
|
|
275
286
|
corePlugins: (path) => {
|
|
276
287
|
if (Array.isArray(tailwindConfig.corePlugins)) {
|
|
277
288
|
return tailwindConfig.corePlugins.includes(path)
|
|
@@ -639,6 +650,7 @@ export function getFileModifiedMap(context) {
|
|
|
639
650
|
|
|
640
651
|
function trackModified(files, fileModifiedMap) {
|
|
641
652
|
let changed = false
|
|
653
|
+
let mtimesToCommit = new Map()
|
|
642
654
|
|
|
643
655
|
for (let file of files) {
|
|
644
656
|
if (!file) continue
|
|
@@ -659,10 +671,10 @@ function trackModified(files, fileModifiedMap) {
|
|
|
659
671
|
changed = true
|
|
660
672
|
}
|
|
661
673
|
|
|
662
|
-
|
|
674
|
+
mtimesToCommit.set(file, newModified)
|
|
663
675
|
}
|
|
664
676
|
|
|
665
|
-
return changed
|
|
677
|
+
return [changed, mtimesToCommit]
|
|
666
678
|
}
|
|
667
679
|
|
|
668
680
|
function extractVariantAtRules(node) {
|
|
@@ -919,12 +931,19 @@ function registerPlugins(plugins, context) {
|
|
|
919
931
|
prefix(context, 'peer'),
|
|
920
932
|
]
|
|
921
933
|
context.getClassOrder = function getClassOrder(classes) {
|
|
934
|
+
// Sort classes so they're ordered in a deterministic manner
|
|
935
|
+
let sorted = [...classes].sort((a, z) => {
|
|
936
|
+
if (a === z) return 0
|
|
937
|
+
if (a < z) return -1
|
|
938
|
+
return 1
|
|
939
|
+
})
|
|
940
|
+
|
|
922
941
|
// Non-util classes won't be generated, so we default them to null
|
|
923
|
-
let sortedClassNames = new Map(
|
|
942
|
+
let sortedClassNames = new Map(sorted.map((className) => [className, null]))
|
|
924
943
|
|
|
925
944
|
// Sort all classes in order
|
|
926
945
|
// Non-tailwind classes won't be generated and will be left as `null`
|
|
927
|
-
let rules = generateRules(new Set(
|
|
946
|
+
let rules = generateRules(new Set(sorted), context)
|
|
928
947
|
rules = context.offsets.sort(rules)
|
|
929
948
|
|
|
930
949
|
let idx = BigInt(parasiteUtilities.length)
|
|
@@ -950,23 +969,35 @@ function registerPlugins(plugins, context) {
|
|
|
950
969
|
|
|
951
970
|
// Generate a list of strings for autocompletion purposes, e.g.
|
|
952
971
|
// ['uppercase', 'lowercase', ...]
|
|
953
|
-
context.getClassList = function getClassList() {
|
|
972
|
+
context.getClassList = function getClassList(options = {}) {
|
|
954
973
|
let output = []
|
|
955
974
|
|
|
956
975
|
for (let util of classList) {
|
|
957
976
|
if (Array.isArray(util)) {
|
|
958
|
-
let [utilName,
|
|
977
|
+
let [utilName, utilOptions] = util
|
|
959
978
|
let negativeClasses = []
|
|
960
979
|
|
|
961
|
-
|
|
980
|
+
let modifiers = Object.keys(utilOptions?.modifiers ?? {})
|
|
981
|
+
|
|
982
|
+
if (utilOptions?.types?.some(({ type }) => type === 'color')) {
|
|
983
|
+
modifiers.push(...Object.keys(context.tailwindConfig.theme.opacity ?? {}))
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
let metadata = { modifiers }
|
|
987
|
+
let includeMetadata = options.includeMetadata && modifiers.length > 0
|
|
988
|
+
|
|
989
|
+
for (let [key, value] of Object.entries(utilOptions?.values ?? {})) {
|
|
962
990
|
// Ignore undefined and null values
|
|
963
991
|
if (value == null) {
|
|
964
992
|
continue
|
|
965
993
|
}
|
|
966
994
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
995
|
+
let cls = formatClass(utilName, key)
|
|
996
|
+
output.push(includeMetadata ? [cls, metadata] : cls)
|
|
997
|
+
|
|
998
|
+
if (utilOptions?.supportsNegativeValues && negateValue(value)) {
|
|
999
|
+
let cls = formatClass(utilName, `-${key}`)
|
|
1000
|
+
negativeClasses.push(includeMetadata ? [cls, metadata] : cls)
|
|
970
1001
|
}
|
|
971
1002
|
}
|
|
972
1003
|
|
|
@@ -1087,20 +1118,38 @@ function registerPlugins(plugins, context) {
|
|
|
1087
1118
|
})
|
|
1088
1119
|
}
|
|
1089
1120
|
|
|
1090
|
-
let
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
isArbitraryVariant
|
|
1096
|
-
})
|
|
1121
|
+
let isArbitraryVariant = !(value in (options.values ?? {}))
|
|
1122
|
+
|
|
1123
|
+
formatStrings = formatStrings.map((format) =>
|
|
1124
|
+
format.map((str) => ({
|
|
1125
|
+
format: str,
|
|
1126
|
+
isArbitraryVariant,
|
|
1127
|
+
}))
|
|
1128
|
+
)
|
|
1129
|
+
|
|
1130
|
+
manualFormatStrings = manualFormatStrings.map((format) => ({
|
|
1131
|
+
format,
|
|
1132
|
+
isArbitraryVariant,
|
|
1133
|
+
}))
|
|
1134
|
+
|
|
1135
|
+
let opts = {
|
|
1136
|
+
candidate,
|
|
1137
|
+
context,
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
let result = formatStrings.map((formats) =>
|
|
1141
|
+
finalizeSelector(`.${candidate}`, formatVariantSelector(formats, opts), opts)
|
|
1097
1142
|
.replace(`.${candidate}`, '&')
|
|
1098
1143
|
.replace('{ & }', '')
|
|
1099
1144
|
.trim()
|
|
1100
1145
|
)
|
|
1101
1146
|
|
|
1102
1147
|
if (manualFormatStrings.length > 0) {
|
|
1103
|
-
result.push(
|
|
1148
|
+
result.push(
|
|
1149
|
+
formatVariantSelector(manualFormatStrings, opts)
|
|
1150
|
+
.toString()
|
|
1151
|
+
.replace(`.${candidate}`, '&')
|
|
1152
|
+
)
|
|
1104
1153
|
}
|
|
1105
1154
|
|
|
1106
1155
|
return result
|
|
@@ -1219,12 +1268,12 @@ export function getContext(
|
|
|
1219
1268
|
// If there's already a context in the cache and we don't need to
|
|
1220
1269
|
// reset the context, return the cached context.
|
|
1221
1270
|
if (existingContext) {
|
|
1222
|
-
let contextDependenciesChanged = trackModified(
|
|
1271
|
+
let [contextDependenciesChanged, mtimesToCommit] = trackModified(
|
|
1223
1272
|
[...contextDependencies],
|
|
1224
1273
|
getFileModifiedMap(existingContext)
|
|
1225
1274
|
)
|
|
1226
1275
|
if (!contextDependenciesChanged && !cssDidChange) {
|
|
1227
|
-
return [existingContext, false]
|
|
1276
|
+
return [existingContext, false, mtimesToCommit]
|
|
1228
1277
|
}
|
|
1229
1278
|
}
|
|
1230
1279
|
|
|
@@ -1259,7 +1308,7 @@ export function getContext(
|
|
|
1259
1308
|
userConfigPath,
|
|
1260
1309
|
})
|
|
1261
1310
|
|
|
1262
|
-
trackModified([...contextDependencies], getFileModifiedMap(context))
|
|
1311
|
+
let [, mtimesToCommit] = trackModified([...contextDependencies], getFileModifiedMap(context))
|
|
1263
1312
|
|
|
1264
1313
|
// ---
|
|
1265
1314
|
|
|
@@ -1274,5 +1323,5 @@ export function getContext(
|
|
|
1274
1323
|
|
|
1275
1324
|
contextSourcesMap.get(context).add(sourcePath)
|
|
1276
1325
|
|
|
1277
|
-
return [context, true]
|
|
1326
|
+
return [context, true, mtimesToCommit]
|
|
1278
1327
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import fs from 'fs'
|
|
2
|
-
import LRU from 'quick-lru'
|
|
4
|
+
import LRU from '@alloc/quick-lru'
|
|
3
5
|
|
|
4
6
|
import hash from '../util/hashConfig'
|
|
5
|
-
import getModuleDependencies from '../lib/getModuleDependencies'
|
|
6
7
|
import resolveConfig from '../public/resolve-config'
|
|
7
8
|
import resolveConfigPath from '../util/resolveConfigPath'
|
|
8
9
|
import { getContext, getFileModifiedMap } from './setupContextUtils'
|
|
9
10
|
import parseDependency from '../util/parseDependency'
|
|
10
11
|
import { validateConfig } from '../util/validateConfig.js'
|
|
11
12
|
import { parseCandidateFiles, resolvedChangedContent } from './content.js'
|
|
13
|
+
import { loadConfig } from '../lib/load-config'
|
|
14
|
+
import getModuleDependencies from './getModuleDependencies'
|
|
12
15
|
|
|
13
16
|
let configPathCache = new LRU({ maxSize: 100 })
|
|
14
17
|
|
|
@@ -32,7 +35,7 @@ function getTailwindConfig(configOrPath) {
|
|
|
32
35
|
let [prevConfig, prevConfigHash, prevDeps, prevModified] =
|
|
33
36
|
configPathCache.get(userConfigPath) || []
|
|
34
37
|
|
|
35
|
-
let newDeps = getModuleDependencies(userConfigPath)
|
|
38
|
+
let newDeps = getModuleDependencies(userConfigPath)
|
|
36
39
|
|
|
37
40
|
let modified = false
|
|
38
41
|
let newModified = new Map()
|
|
@@ -53,8 +56,7 @@ function getTailwindConfig(configOrPath) {
|
|
|
53
56
|
for (let file of newDeps) {
|
|
54
57
|
delete require.cache[file]
|
|
55
58
|
}
|
|
56
|
-
let newConfig = resolveConfig(
|
|
57
|
-
newConfig = validateConfig(newConfig)
|
|
59
|
+
let newConfig = validateConfig(resolveConfig(loadConfig(userConfigPath)))
|
|
58
60
|
let newHash = hash(newConfig)
|
|
59
61
|
configPathCache.set(userConfigPath, [newConfig, newHash, newDeps, newModified])
|
|
60
62
|
return [newConfig, userConfigPath, newHash, newDeps]
|
|
@@ -101,7 +103,7 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
let [context] = getContext(
|
|
106
|
+
let [context, , mTimesToCommit] = getContext(
|
|
105
107
|
root,
|
|
106
108
|
result,
|
|
107
109
|
tailwindConfig,
|
|
@@ -110,6 +112,8 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
110
112
|
contextDependencies
|
|
111
113
|
)
|
|
112
114
|
|
|
115
|
+
let fileModifiedMap = getFileModifiedMap(context)
|
|
116
|
+
|
|
113
117
|
let candidateFiles = getCandidateFiles(context, tailwindConfig)
|
|
114
118
|
|
|
115
119
|
// If there are no @tailwind or @apply rules, we don't consider this CSS file or it's
|
|
@@ -118,8 +122,6 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
118
122
|
// because it's impossible for a layer in one file to end up in the actual @tailwind rule
|
|
119
123
|
// in another file since independent sources are effectively isolated.
|
|
120
124
|
if (tailwindDirectives.size > 0) {
|
|
121
|
-
let fileModifiedMap = getFileModifiedMap(context)
|
|
122
|
-
|
|
123
125
|
// Add template paths as postcss dependencies.
|
|
124
126
|
for (let contentPath of candidateFiles) {
|
|
125
127
|
for (let dependency of parseDependency(contentPath)) {
|
|
@@ -127,12 +129,28 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
|
|
130
|
-
|
|
132
|
+
let [changedContent, contentMTimesToCommit] = resolvedChangedContent(
|
|
131
133
|
context,
|
|
132
134
|
candidateFiles,
|
|
133
135
|
fileModifiedMap
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
for (let content of changedContent) {
|
|
139
|
+
context.changedContent.push(content)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Add the mtimes of the content files to the commit list
|
|
143
|
+
// We can overwrite the existing values because unconditionally
|
|
144
|
+
// This is because:
|
|
145
|
+
// 1. Most of the files here won't be in the map yet
|
|
146
|
+
// 2. If they are that means it's a context dependency
|
|
147
|
+
// and we're reading this after the context. This means
|
|
148
|
+
// that the mtime we just read is strictly >= the context
|
|
149
|
+
// mtime. Unless the user / os is doing something weird
|
|
150
|
+
// in which the mtime would be going backwards. If that
|
|
151
|
+
// happens there's already going to be problems.
|
|
152
|
+
for (let [path, mtime] of contentMTimesToCommit.entries()) {
|
|
153
|
+
mTimesToCommit.set(path, mtime)
|
|
136
154
|
}
|
|
137
155
|
}
|
|
138
156
|
|
|
@@ -140,6 +158,13 @@ export default function setupTrackingContext(configOrPath) {
|
|
|
140
158
|
registerDependency({ type: 'dependency', file })
|
|
141
159
|
}
|
|
142
160
|
|
|
161
|
+
// "commit" the new modified time for all context deps
|
|
162
|
+
// We do this here because we want content tracking to
|
|
163
|
+
// read the "old" mtime even when it's a context dependency.
|
|
164
|
+
for (let [path, mtime] of mTimesToCommit.entries()) {
|
|
165
|
+
fileModifiedMap.set(path, mtime)
|
|
166
|
+
}
|
|
167
|
+
|
|
143
168
|
return context
|
|
144
169
|
}
|
|
145
170
|
}
|
package/src/lib/sharedState.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import pkg from '../../package.json'
|
|
2
|
+
|
|
3
|
+
export const env =
|
|
4
|
+
typeof process !== 'undefined'
|
|
5
|
+
? {
|
|
6
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
7
|
+
DEBUG: resolveDebug(process.env.DEBUG),
|
|
8
|
+
ENGINE: pkg.tailwindcss.engine,
|
|
9
|
+
}
|
|
10
|
+
: {
|
|
11
|
+
NODE_ENV: 'production',
|
|
12
|
+
DEBUG: false,
|
|
13
|
+
ENGINE: pkg.tailwindcss.engine,
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
export const contextMap = new Map()
|
|
6
17
|
export const configContextMap = new Map()
|
|
7
18
|
export const contextSourcesMap = new Map()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import packageJson from '../../../../package.json'
|
|
2
|
+
import browserslist from 'browserslist'
|
|
3
|
+
import { Result } from 'postcss'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
lazyPostcss,
|
|
8
|
+
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
lazyPostcssImport,
|
|
11
|
+
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
lazyCssnano,
|
|
14
|
+
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
} from '../../../../peers/index'
|
|
17
|
+
|
|
18
|
+
export function lazyLightningCss() {
|
|
19
|
+
// TODO: Make this lazy/bundled
|
|
20
|
+
return require('lightningcss')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let lightningCss
|
|
24
|
+
|
|
25
|
+
function loadLightningCss() {
|
|
26
|
+
if (lightningCss) {
|
|
27
|
+
return lightningCss
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Try to load a local version first
|
|
31
|
+
try {
|
|
32
|
+
return (lightningCss = require('lightningcss'))
|
|
33
|
+
} catch {}
|
|
34
|
+
|
|
35
|
+
return (lightningCss = lazyLightningCss())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function lightningcss(shouldMinify: boolean, result: Result) {
|
|
39
|
+
let css = loadLightningCss()
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
let transformed = css.transform({
|
|
43
|
+
filename: result.opts.from || 'input.css',
|
|
44
|
+
code: Buffer.from(result.css, 'utf-8'),
|
|
45
|
+
minify: shouldMinify,
|
|
46
|
+
sourceMap: !!result.map,
|
|
47
|
+
inputSourceMap: result.map ? result.map.toString() : undefined,
|
|
48
|
+
targets: css.browserslistToTargets(browserslist(packageJson.browserslist)),
|
|
49
|
+
drafts: {
|
|
50
|
+
nesting: true,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
return Object.assign(result, {
|
|
55
|
+
css: transformed.code.toString('utf8'),
|
|
56
|
+
map: result.map
|
|
57
|
+
? Object.assign(result.map, {
|
|
58
|
+
toString() {
|
|
59
|
+
return transformed.map.toString()
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
: result.map,
|
|
63
|
+
})
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error('Unable to use Lightning CSS. Using raw version instead.')
|
|
66
|
+
console.error(err)
|
|
67
|
+
|
|
68
|
+
return result
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @returns {import('postcss')}
|
|
74
|
+
*/
|
|
75
|
+
export function loadPostcss() {
|
|
76
|
+
// Try to load a local `postcss` version first
|
|
77
|
+
try {
|
|
78
|
+
return require('postcss')
|
|
79
|
+
} catch {}
|
|
80
|
+
|
|
81
|
+
return lazyPostcss()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function loadPostcssImport() {
|
|
85
|
+
// Try to load a local `postcss-import` version first
|
|
86
|
+
try {
|
|
87
|
+
return require('postcss-import')
|
|
88
|
+
} catch {}
|
|
89
|
+
|
|
90
|
+
return lazyPostcssImport()
|
|
91
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { resolveDefaultConfigPath } from '../../../util/resolveConfigPath'
|
|
4
|
+
import { createProcessor } from './plugin'
|
|
5
|
+
|
|
6
|
+
export async function build(args) {
|
|
7
|
+
let input = args['--input']
|
|
8
|
+
let shouldWatch = args['--watch']
|
|
9
|
+
|
|
10
|
+
// TODO: Deprecate this in future versions
|
|
11
|
+
if (!input && args['_'][1]) {
|
|
12
|
+
console.error('[deprecation] Running tailwindcss without -i, please provide an input file.')
|
|
13
|
+
input = args['--input'] = args['_'][1]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) {
|
|
17
|
+
console.error(`Specified input file ${args['--input']} does not exist.`)
|
|
18
|
+
process.exit(9)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) {
|
|
22
|
+
console.error(`Specified config file ${args['--config']} does not exist.`)
|
|
23
|
+
process.exit(9)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// TODO: Reference the @config path here if exists
|
|
27
|
+
let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath()
|
|
28
|
+
|
|
29
|
+
let processor = await createProcessor(args, configPath)
|
|
30
|
+
|
|
31
|
+
if (shouldWatch) {
|
|
32
|
+
// Abort the watcher if stdin is closed to avoid zombie processes
|
|
33
|
+
// You can disable this behavior with --watch=always
|
|
34
|
+
if (args['--watch'] !== 'always') {
|
|
35
|
+
process.stdin.on('end', () => process.exit(0))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
process.stdin.resume()
|
|
39
|
+
|
|
40
|
+
await processor.watch()
|
|
41
|
+
} else {
|
|
42
|
+
await processor.build().catch((e) => {
|
|
43
|
+
console.error(e)
|
|
44
|
+
process.exit(1)
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|