tailwindcss 3.2.4 → 3.2.6
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/CHANGELOG.md +51 -1
- package/README.md +1 -1
- package/lib/cli/build/index.js +5 -1
- package/lib/cli/build/plugin.js +39 -34
- package/lib/cli/index.js +231 -10
- package/lib/cli/init/index.js +2 -2
- package/lib/cli.js +4 -226
- package/lib/corePlugins.js +45 -27
- package/lib/featureFlags.js +8 -8
- package/lib/index.js +4 -46
- package/lib/lib/collapseAdjacentRules.js +2 -2
- package/lib/lib/collapseDuplicateDeclarations.js +2 -2
- package/lib/lib/content.js +16 -16
- package/lib/lib/defaultExtractor.js +10 -5
- package/lib/lib/detectNesting.js +7 -1
- package/lib/lib/evaluateTailwindFunctions.js +4 -4
- package/lib/lib/expandApplyAtRules.js +2 -2
- package/lib/lib/expandTailwindAtRules.js +34 -9
- package/lib/lib/findAtConfigPath.js +3 -3
- package/lib/lib/generateRules.js +105 -50
- package/lib/lib/offsets.js +88 -1
- package/lib/lib/remap-bitfield.js +87 -0
- package/lib/lib/resolveDefaultsAtRules.js +4 -4
- package/lib/lib/setupContextUtils.js +121 -80
- package/lib/lib/setupTrackingContext.js +25 -4
- package/lib/lib/sharedState.js +19 -1
- package/lib/oxide/cli/build/deps.js +81 -0
- package/lib/oxide/cli/build/index.js +47 -0
- package/lib/oxide/cli/build/plugin.js +364 -0
- package/lib/oxide/cli/build/utils.js +77 -0
- package/lib/oxide/cli/build/watching.js +177 -0
- package/lib/oxide/cli/help/index.js +70 -0
- package/lib/oxide/cli/index.js +220 -0
- package/lib/oxide/cli/init/index.js +35 -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/plugin.js +2 -2
- package/lib/util/cloneNodes.js +2 -2
- package/lib/util/color.js +20 -6
- package/lib/util/createUtilityPlugin.js +2 -2
- package/lib/util/dataTypes.js +26 -2
- package/lib/util/defaults.js +4 -4
- package/lib/util/escapeClassName.js +3 -3
- package/lib/util/formatVariantSelector.js +171 -105
- package/lib/util/getAllConfigs.js +2 -2
- package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +2 -2
- package/lib/util/negateValue.js +2 -2
- package/lib/util/normalizeConfig.js +22 -22
- package/lib/util/pluginUtils.js +38 -40
- package/lib/util/prefixSelector.js +22 -8
- package/lib/util/resolveConfig.js +8 -10
- package/package.json +30 -19
- package/peers/index.js +61 -42
- package/resolveConfig.d.ts +11 -2
- package/scripts/swap-engines.js +40 -0
- package/src/cli/build/index.js +6 -2
- package/src/cli/build/plugin.js +14 -9
- package/src/cli/index.js +234 -3
- package/src/cli.js +4 -220
- package/src/corePlugins.js +31 -3
- package/src/index.js +4 -46
- package/src/lib/content.js +12 -17
- package/src/lib/defaultExtractor.js +9 -3
- package/src/lib/detectNesting.js +9 -1
- package/src/lib/expandTailwindAtRules.js +35 -6
- package/src/lib/generateRules.js +90 -28
- package/src/lib/offsets.js +104 -1
- package/src/lib/remap-bitfield.js +82 -0
- package/src/lib/setupContextUtils.js +97 -55
- package/src/lib/setupTrackingContext.js +31 -6
- package/src/lib/sharedState.js +17 -0
- 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 +436 -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 +212 -0
- package/src/oxide/cli/init/index.ts +32 -0
- package/src/oxide/cli.ts +1 -0
- package/src/oxide/postcss-plugin.ts +1 -0
- package/src/plugin.js +107 -0
- package/src/util/color.js +17 -2
- package/src/util/dataTypes.js +29 -4
- package/src/util/formatVariantSelector.js +215 -122
- package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
- package/src/util/negateValue.js +1 -1
- package/src/util/pluginUtils.js +22 -19
- package/src/util/prefixSelector.js +28 -10
- package/src/util/resolveConfig.js +0 -2
- package/stubs/defaultConfig.stub.js +149 -165
- package/types/config.d.ts +7 -2
- package/types/generated/default-theme.d.ts +77 -77
- package/lib/cli/shared.js +0 -12
- package/scripts/install-integrations.js +0 -27
- package/scripts/rebuildFixtures.js +0 -68
- package/src/cli/shared.js +0 -5
|
@@ -17,7 +17,7 @@ import { env } from './sharedState'
|
|
|
17
17
|
import { toPath } from '../util/toPath'
|
|
18
18
|
import log from '../util/log'
|
|
19
19
|
import negateValue from '../util/negateValue'
|
|
20
|
-
import
|
|
20
|
+
import isSyntacticallyValidPropertyValue from '../util/isSyntacticallyValidPropertyValue'
|
|
21
21
|
import { generateRules, getClassNameFromSelector } from './generateRules'
|
|
22
22
|
import { hasContentChanged } from './cacheInvalidation.js'
|
|
23
23
|
import { Offsets } from './offsets.js'
|
|
@@ -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)
|
|
@@ -407,7 +418,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
407
418
|
}
|
|
408
419
|
}
|
|
409
420
|
|
|
410
|
-
if (!
|
|
421
|
+
if (!isSyntacticallyValidPropertyValue(value)) {
|
|
411
422
|
return []
|
|
412
423
|
}
|
|
413
424
|
|
|
@@ -487,7 +498,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|
|
487
498
|
}
|
|
488
499
|
}
|
|
489
500
|
|
|
490
|
-
if (!
|
|
501
|
+
if (!isSyntacticallyValidPropertyValue(value)) {
|
|
491
502
|
return []
|
|
492
503
|
}
|
|
493
504
|
|
|
@@ -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) {
|
|
@@ -950,23 +962,35 @@ function registerPlugins(plugins, context) {
|
|
|
950
962
|
|
|
951
963
|
// Generate a list of strings for autocompletion purposes, e.g.
|
|
952
964
|
// ['uppercase', 'lowercase', ...]
|
|
953
|
-
context.getClassList = function getClassList() {
|
|
965
|
+
context.getClassList = function getClassList(options = {}) {
|
|
954
966
|
let output = []
|
|
955
967
|
|
|
956
968
|
for (let util of classList) {
|
|
957
969
|
if (Array.isArray(util)) {
|
|
958
|
-
let [utilName,
|
|
970
|
+
let [utilName, utilOptions] = util
|
|
959
971
|
let negativeClasses = []
|
|
960
972
|
|
|
961
|
-
|
|
973
|
+
let modifiers = Object.keys(utilOptions?.modifiers ?? {})
|
|
974
|
+
|
|
975
|
+
if (utilOptions?.types?.some(({ type }) => type === 'color')) {
|
|
976
|
+
modifiers.push(...Object.keys(context.tailwindConfig.theme.opacity ?? {}))
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
let metadata = { modifiers }
|
|
980
|
+
let includeMetadata = options.includeMetadata && modifiers.length > 0
|
|
981
|
+
|
|
982
|
+
for (let [key, value] of Object.entries(utilOptions?.values ?? {})) {
|
|
962
983
|
// Ignore undefined and null values
|
|
963
984
|
if (value == null) {
|
|
964
985
|
continue
|
|
965
986
|
}
|
|
966
987
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
988
|
+
let cls = formatClass(utilName, key)
|
|
989
|
+
output.push(includeMetadata ? [cls, metadata] : cls)
|
|
990
|
+
|
|
991
|
+
if (utilOptions?.supportsNegativeValues && negateValue(value)) {
|
|
992
|
+
let cls = formatClass(utilName, `-${key}`)
|
|
993
|
+
negativeClasses.push(includeMetadata ? [cls, metadata] : cls)
|
|
970
994
|
}
|
|
971
995
|
}
|
|
972
996
|
|
|
@@ -1087,20 +1111,38 @@ function registerPlugins(plugins, context) {
|
|
|
1087
1111
|
})
|
|
1088
1112
|
}
|
|
1089
1113
|
|
|
1090
|
-
let
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
isArbitraryVariant
|
|
1096
|
-
})
|
|
1114
|
+
let isArbitraryVariant = !(value in (options.values ?? {}))
|
|
1115
|
+
|
|
1116
|
+
formatStrings = formatStrings.map((format) =>
|
|
1117
|
+
format.map((str) => ({
|
|
1118
|
+
format: str,
|
|
1119
|
+
isArbitraryVariant,
|
|
1120
|
+
}))
|
|
1121
|
+
)
|
|
1122
|
+
|
|
1123
|
+
manualFormatStrings = manualFormatStrings.map((format) => ({
|
|
1124
|
+
format,
|
|
1125
|
+
isArbitraryVariant,
|
|
1126
|
+
}))
|
|
1127
|
+
|
|
1128
|
+
let opts = {
|
|
1129
|
+
candidate,
|
|
1130
|
+
context,
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
let result = formatStrings.map((formats) =>
|
|
1134
|
+
finalizeSelector(`.${candidate}`, formatVariantSelector(formats, opts), opts)
|
|
1097
1135
|
.replace(`.${candidate}`, '&')
|
|
1098
1136
|
.replace('{ & }', '')
|
|
1099
1137
|
.trim()
|
|
1100
1138
|
)
|
|
1101
1139
|
|
|
1102
1140
|
if (manualFormatStrings.length > 0) {
|
|
1103
|
-
result.push(
|
|
1141
|
+
result.push(
|
|
1142
|
+
formatVariantSelector(manualFormatStrings, opts)
|
|
1143
|
+
.toString()
|
|
1144
|
+
.replace(`.${candidate}`, '&')
|
|
1145
|
+
)
|
|
1104
1146
|
}
|
|
1105
1147
|
|
|
1106
1148
|
return result
|
|
@@ -1219,12 +1261,12 @@ export function getContext(
|
|
|
1219
1261
|
// If there's already a context in the cache and we don't need to
|
|
1220
1262
|
// reset the context, return the cached context.
|
|
1221
1263
|
if (existingContext) {
|
|
1222
|
-
let contextDependenciesChanged = trackModified(
|
|
1264
|
+
let [contextDependenciesChanged, mtimesToCommit] = trackModified(
|
|
1223
1265
|
[...contextDependencies],
|
|
1224
1266
|
getFileModifiedMap(existingContext)
|
|
1225
1267
|
)
|
|
1226
1268
|
if (!contextDependenciesChanged && !cssDidChange) {
|
|
1227
|
-
return [existingContext, false]
|
|
1269
|
+
return [existingContext, false, mtimesToCommit]
|
|
1228
1270
|
}
|
|
1229
1271
|
}
|
|
1230
1272
|
|
|
@@ -1259,7 +1301,7 @@ export function getContext(
|
|
|
1259
1301
|
userConfigPath,
|
|
1260
1302
|
})
|
|
1261
1303
|
|
|
1262
|
-
trackModified([...contextDependencies], getFileModifiedMap(context))
|
|
1304
|
+
let [, mtimesToCommit] = trackModified([...contextDependencies], getFileModifiedMap(context))
|
|
1263
1305
|
|
|
1264
1306
|
// ---
|
|
1265
1307
|
|
|
@@ -1274,5 +1316,5 @@ export function getContext(
|
|
|
1274
1316
|
|
|
1275
1317
|
contextSourcesMap.get(context).add(sourcePath)
|
|
1276
1318
|
|
|
1277
|
-
return [context, true]
|
|
1319
|
+
return [context, true, mtimesToCommit]
|
|
1278
1320
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import fs from 'fs'
|
|
2
4
|
import LRU from 'quick-lru'
|
|
3
5
|
|
|
@@ -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,6 +1,11 @@
|
|
|
1
|
+
import pkg from '../../package.json'
|
|
2
|
+
let OXIDE_DEFAULT_ENABLED = pkg.tailwindcss.engine === 'oxide'
|
|
3
|
+
|
|
1
4
|
export const env = {
|
|
2
5
|
NODE_ENV: process.env.NODE_ENV,
|
|
3
6
|
DEBUG: resolveDebug(process.env.DEBUG),
|
|
7
|
+
ENGINE: pkg.tailwindcss.engine,
|
|
8
|
+
OXIDE: resolveBoolean(process.env.OXIDE, OXIDE_DEFAULT_ENABLED),
|
|
4
9
|
}
|
|
5
10
|
export const contextMap = new Map()
|
|
6
11
|
export const configContextMap = new Map()
|
|
@@ -10,6 +15,18 @@ export const NOT_ON_DEMAND = new String('*')
|
|
|
10
15
|
|
|
11
16
|
export const NONE = Symbol('__NONE__')
|
|
12
17
|
|
|
18
|
+
function resolveBoolean(value, defaultValue) {
|
|
19
|
+
if (value === undefined) {
|
|
20
|
+
return defaultValue
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (value === '0' || value === 'false') {
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return true
|
|
28
|
+
}
|
|
29
|
+
|
|
13
30
|
export function resolveDebug(debug) {
|
|
14
31
|
if (debug === undefined) {
|
|
15
32
|
return false
|
|
@@ -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 { createProcessor } from './plugin'
|
|
4
|
+
|
|
5
|
+
export async function build(args, configs) {
|
|
6
|
+
let input = args['--input']
|
|
7
|
+
let shouldWatch = args['--watch']
|
|
8
|
+
|
|
9
|
+
// TODO: Deprecate this in future versions
|
|
10
|
+
if (!input && args['_'][1]) {
|
|
11
|
+
console.error('[deprecation] Running tailwindcss without -i, please provide an input file.')
|
|
12
|
+
input = args['--input'] = args['_'][1]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) {
|
|
16
|
+
console.error(`Specified input file ${args['--input']} does not exist.`)
|
|
17
|
+
process.exit(9)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) {
|
|
21
|
+
console.error(`Specified config file ${args['--config']} does not exist.`)
|
|
22
|
+
process.exit(9)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// TODO: Reference the @config path here if exists
|
|
26
|
+
let configPath = args['--config']
|
|
27
|
+
? args['--config']
|
|
28
|
+
: ((defaultPath) => (fs.existsSync(defaultPath) ? defaultPath : null))(
|
|
29
|
+
path.resolve(`./${configs.tailwind}`)
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
let processor = await createProcessor(args, configPath)
|
|
33
|
+
|
|
34
|
+
if (shouldWatch) {
|
|
35
|
+
// Abort the watcher if stdin is closed to avoid zombie processes
|
|
36
|
+
// You can disable this behavior with --watch=always
|
|
37
|
+
if (args['--watch'] !== 'always') {
|
|
38
|
+
process.stdin.on('end', () => process.exit(0))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
process.stdin.resume()
|
|
42
|
+
|
|
43
|
+
await processor.watch()
|
|
44
|
+
} else {
|
|
45
|
+
await processor.build()
|
|
46
|
+
}
|
|
47
|
+
}
|