tailwindcss 3.0.22 → 3.1.0

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.
Files changed (119) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/colors.d.ts +3 -0
  3. package/defaultConfig.d.ts +3 -0
  4. package/defaultTheme.d.ts +3 -0
  5. package/lib/cli-peer-dependencies.js +10 -5
  6. package/lib/cli.js +266 -203
  7. package/lib/constants.js +8 -8
  8. package/lib/corePluginList.js +1 -0
  9. package/lib/corePlugins.js +1662 -1554
  10. package/lib/css/preflight.css +1 -8
  11. package/lib/featureFlags.js +14 -12
  12. package/lib/index.js +16 -6
  13. package/lib/lib/cacheInvalidation.js +87 -0
  14. package/lib/lib/collapseAdjacentRules.js +30 -15
  15. package/lib/lib/collapseDuplicateDeclarations.js +1 -1
  16. package/lib/lib/defaultExtractor.js +191 -30
  17. package/lib/lib/detectNesting.js +9 -9
  18. package/lib/lib/evaluateTailwindFunctions.js +37 -28
  19. package/lib/lib/expandApplyAtRules.js +379 -189
  20. package/lib/lib/expandTailwindAtRules.js +168 -144
  21. package/lib/lib/generateRules.js +190 -81
  22. package/lib/lib/getModuleDependencies.js +14 -14
  23. package/lib/lib/normalizeTailwindDirectives.js +35 -35
  24. package/lib/lib/partitionApplyAtRules.js +7 -7
  25. package/lib/lib/regex.js +52 -0
  26. package/lib/lib/resolveDefaultsAtRules.js +80 -79
  27. package/lib/lib/setupContextUtils.js +207 -170
  28. package/lib/lib/setupTrackingContext.js +61 -63
  29. package/lib/lib/sharedState.js +11 -8
  30. package/lib/lib/substituteScreenAtRules.js +3 -4
  31. package/lib/postcss-plugins/nesting/README.md +2 -2
  32. package/lib/postcss-plugins/nesting/index.js +1 -1
  33. package/lib/postcss-plugins/nesting/plugin.js +40 -9
  34. package/lib/processTailwindFeatures.js +7 -7
  35. package/lib/public/colors.js +241 -241
  36. package/lib/public/resolve-config.js +5 -5
  37. package/lib/util/buildMediaQuery.js +2 -3
  38. package/lib/util/cloneDeep.js +3 -5
  39. package/lib/util/cloneNodes.js +12 -1
  40. package/lib/util/color.js +42 -51
  41. package/lib/util/createPlugin.js +1 -2
  42. package/lib/util/createUtilityPlugin.js +6 -7
  43. package/lib/util/dataTypes.js +85 -81
  44. package/lib/util/escapeClassName.js +5 -5
  45. package/lib/util/escapeCommas.js +1 -1
  46. package/lib/util/flattenColorPalette.js +4 -7
  47. package/lib/util/formatVariantSelector.js +82 -75
  48. package/lib/util/getAllConfigs.js +15 -10
  49. package/lib/util/hashConfig.js +5 -5
  50. package/lib/util/isKeyframeRule.js +1 -1
  51. package/lib/util/isPlainObject.js +1 -1
  52. package/lib/util/isValidArbitraryValue.js +26 -27
  53. package/lib/util/log.js +9 -10
  54. package/lib/util/nameClass.js +7 -7
  55. package/lib/util/negateValue.js +4 -5
  56. package/lib/util/normalizeConfig.js +68 -58
  57. package/lib/util/normalizeScreens.js +5 -6
  58. package/lib/util/parseAnimationValue.js +56 -57
  59. package/lib/util/parseBoxShadowValue.js +19 -20
  60. package/lib/util/parseDependency.js +32 -32
  61. package/lib/util/parseObjectStyles.js +6 -6
  62. package/lib/util/pluginUtils.js +20 -12
  63. package/lib/util/prefixSelector.js +1 -1
  64. package/lib/util/resolveConfig.js +81 -58
  65. package/lib/util/resolveConfigPath.js +16 -16
  66. package/lib/util/responsive.js +6 -6
  67. package/lib/util/splitAtTopLevelOnly.js +90 -0
  68. package/lib/util/toColorValue.js +1 -1
  69. package/lib/util/toPath.js +2 -2
  70. package/lib/util/transformThemeValue.js +30 -28
  71. package/lib/util/validateConfig.js +21 -0
  72. package/lib/util/withAlphaVariable.js +23 -23
  73. package/package.json +33 -27
  74. package/peers/index.js +7728 -5848
  75. package/plugin.d.ts +11 -0
  76. package/scripts/generate-types.js +52 -0
  77. package/src/cli-peer-dependencies.js +7 -1
  78. package/src/cli.js +118 -24
  79. package/src/corePluginList.js +1 -1
  80. package/src/corePlugins.js +142 -30
  81. package/src/css/preflight.css +1 -8
  82. package/src/featureFlags.js +4 -4
  83. package/src/index.js +15 -1
  84. package/src/lib/cacheInvalidation.js +52 -0
  85. package/src/lib/collapseAdjacentRules.js +21 -2
  86. package/src/lib/defaultExtractor.js +177 -33
  87. package/src/lib/evaluateTailwindFunctions.js +20 -4
  88. package/src/lib/expandApplyAtRules.js +418 -186
  89. package/src/lib/expandTailwindAtRules.js +30 -10
  90. package/src/lib/generateRules.js +142 -51
  91. package/src/lib/regex.js +74 -0
  92. package/src/lib/resolveDefaultsAtRules.js +7 -3
  93. package/src/lib/setupContextUtils.js +142 -87
  94. package/src/lib/setupTrackingContext.js +7 -3
  95. package/src/lib/sharedState.js +2 -0
  96. package/src/postcss-plugins/nesting/README.md +2 -2
  97. package/src/postcss-plugins/nesting/plugin.js +36 -0
  98. package/src/util/cloneNodes.js +14 -1
  99. package/src/util/color.js +25 -21
  100. package/src/util/dataTypes.js +14 -6
  101. package/src/util/formatVariantSelector.js +79 -62
  102. package/src/util/getAllConfigs.js +7 -0
  103. package/src/util/log.js +8 -8
  104. package/src/util/normalizeConfig.js +0 -8
  105. package/src/util/parseBoxShadowValue.js +3 -2
  106. package/src/util/pluginUtils.js +13 -1
  107. package/src/util/resolveConfig.js +66 -22
  108. package/src/util/splitAtTopLevelOnly.js +71 -0
  109. package/src/util/toPath.js +1 -1
  110. package/src/util/transformThemeValue.js +4 -2
  111. package/src/util/validateConfig.js +13 -0
  112. package/src/util/withAlphaVariable.js +1 -1
  113. package/stubs/defaultConfig.stub.js +5 -1
  114. package/stubs/simpleConfig.stub.js +1 -0
  115. package/types/config.d.ts +325 -0
  116. package/types/generated/.gitkeep +0 -0
  117. package/types/generated/colors.d.ts +276 -0
  118. package/types/generated/corePluginList.d.ts +1 -0
  119. package/types/index.d.ts +1 -0
package/lib/cli.js CHANGED
@@ -6,9 +6,11 @@ var _path = _interopRequireDefault(require("path"));
6
6
  var _arg = _interopRequireDefault(require("arg"));
7
7
  var _fs = _interopRequireDefault(require("fs"));
8
8
  var _postcssLoadConfig = _interopRequireDefault(require("postcss-load-config"));
9
- var _cosmiconfig = require("cosmiconfig");
9
+ var _lilconfig = require("lilconfig");
10
10
  var _plugins // Little bit scary, looking at private/internal API
11
11
  = _interopRequireDefault(require("postcss-load-config/src/plugins"));
12
+ var _options // Little bit scary, looking at private/internal API
13
+ = _interopRequireDefault(require("postcss-load-config/src/options"));
12
14
  var _processTailwindFeatures = _interopRequireDefault(require("./processTailwindFeatures"));
13
15
  var _resolveConfig = _interopRequireDefault(require("../resolveConfig"));
14
16
  var _fastGlob = _interopRequireDefault(require("fast-glob"));
@@ -16,47 +18,62 @@ var _getModuleDependencies = _interopRequireDefault(require("./lib/getModuleDepe
16
18
  var _log = _interopRequireDefault(require("./util/log"));
17
19
  var _packageJson = _interopRequireDefault(require("../package.json"));
18
20
  var _normalizePath = _interopRequireDefault(require("normalize-path"));
21
+ var _validateConfigJs = require("./util/validateConfig.js");
19
22
  function _interopRequireDefault(obj) {
20
23
  return obj && obj.__esModule ? obj : {
21
24
  default: obj
22
25
  };
23
26
  }
24
27
  let env = {
25
- DEBUG: process.env.DEBUG !== undefined && process.env.DEBUG !== '0'
28
+ DEBUG: process.env.DEBUG !== undefined && process.env.DEBUG !== "0"
29
+ };
30
+ function isESM() {
31
+ const pkgPath = _path.default.resolve("./package.json");
32
+ try {
33
+ let pkg = JSON.parse(_fs.default.readFileSync(pkgPath, "utf8"));
34
+ return pkg.type && pkg.type === "module";
35
+ } catch (err) {
36
+ return false;
37
+ }
38
+ }
39
+ let configs = isESM() ? {
40
+ tailwind: "tailwind.config.cjs",
41
+ postcss: "postcss.config.cjs"
42
+ } : {
43
+ tailwind: "tailwind.config.js",
44
+ postcss: "postcss.config.js"
26
45
  };
27
46
  // ---
28
47
  function indentRecursive(node, indent = 0) {
29
48
  node.each && node.each((child, i)=>{
30
- if (!child.raws.before || !child.raws.before.trim() || child.raws.before.includes('\n')) {
31
- child.raws.before = `\n${node.type !== 'rule' && i > 0 ? '\n' : ''}${' '.repeat(indent)}`;
49
+ if (!child.raws.before || !child.raws.before.trim() || child.raws.before.includes("\n")) {
50
+ child.raws.before = `\n${node.type !== "rule" && i > 0 ? "\n" : ""}${" ".repeat(indent)}`;
32
51
  }
33
- child.raws.after = `\n${' '.repeat(indent)}`;
52
+ child.raws.after = `\n${" ".repeat(indent)}`;
34
53
  indentRecursive(child, indent + 1);
35
54
  });
36
55
  }
37
56
  function formatNodes(root) {
38
57
  indentRecursive(root);
39
58
  if (root.first) {
40
- root.first.raws.before = '';
59
+ root.first.raws.before = "";
41
60
  }
42
61
  }
43
62
  async function outputFile(file, contents) {
44
- if (_fs.default.existsSync(file) && await _fs.default.promises.readFile(file, 'utf8') === contents) {
63
+ if (_fs.default.existsSync(file) && await _fs.default.promises.readFile(file, "utf8") === contents) {
45
64
  return; // Skip writing the file
46
65
  }
47
66
  // Write the file
48
- await _fs.default.promises.writeFile(file, contents, 'utf8');
67
+ await _fs.default.promises.writeFile(file, contents, "utf8");
49
68
  }
50
69
  function drainStdin() {
51
70
  return new Promise((resolve, reject)=>{
52
- let result = '';
53
- process.stdin.on('data', (chunk)=>{
71
+ let result = "";
72
+ process.stdin.on("data", (chunk)=>{
54
73
  result += chunk;
55
74
  });
56
- process.stdin.on('end', ()=>resolve(result)
57
- );
58
- process.stdin.on('error', (err)=>reject(err)
59
- );
75
+ process.stdin.on("end", ()=>resolve(result));
76
+ process.stdin.on("error", (err)=>reject(err));
60
77
  });
61
78
  }
62
79
  function help({ message , usage , commands: commands1 , options }) {
@@ -67,31 +84,31 @@ function help({ message , usage , commands: commands1 , options }) {
67
84
  // Render message
68
85
  if (message) {
69
86
  console.log();
70
- for (let msg of message.split('\n')){
87
+ for (let msg of message.split("\n")){
71
88
  console.log(msg);
72
89
  }
73
90
  }
74
91
  // Render usage
75
92
  if (usage && usage.length > 0) {
76
93
  console.log();
77
- console.log('Usage:');
94
+ console.log("Usage:");
78
95
  for (let example of usage){
79
- console.log(' '.repeat(indent), example);
96
+ console.log(" ".repeat(indent), example);
80
97
  }
81
98
  }
82
99
  // Render commands
83
100
  if (commands1 && commands1.length > 0) {
84
101
  console.log();
85
- console.log('Commands:');
102
+ console.log("Commands:");
86
103
  for (let command1 of commands1){
87
- console.log(' '.repeat(indent), command1);
104
+ console.log(" ".repeat(indent), command1);
88
105
  }
89
106
  }
90
107
  // Render options
91
108
  if (options) {
92
109
  let groupedOptions = {};
93
110
  for (let [key, value] of Object.entries(options)){
94
- if (typeof value === 'object') {
111
+ if (typeof value === "object") {
95
112
  groupedOptions[key] = {
96
113
  ...value,
97
114
  flags: [
@@ -103,13 +120,13 @@ function help({ message , usage , commands: commands1 , options }) {
103
120
  }
104
121
  }
105
122
  console.log();
106
- console.log('Options:');
123
+ console.log("Options:");
107
124
  for (let { flags: flags1 , description , deprecated } of Object.values(groupedOptions)){
108
125
  if (deprecated) continue;
109
126
  if (flags1.length === 1) {
110
- console.log(' '.repeat(indent + 4 /* 4 = "-i, ".length */ ), flags1.slice().reverse().join(', ').padEnd(20, ' '), description);
127
+ console.log(" ".repeat(indent + 4 /* 4 = "-i, ".length */ ), flags1.slice().reverse().join(", ").padEnd(20, " "), description);
111
128
  } else {
112
- console.log(' '.repeat(indent), flags1.slice().reverse().join(', ').padEnd(24, ' '), description);
129
+ console.log(" ".repeat(indent), flags1.slice().reverse().join(", ").padEnd(24, " "), description);
113
130
  }
114
131
  }
115
132
  }
@@ -123,91 +140,100 @@ function oneOf(...options) {
123
140
  return parsed;
124
141
  }
125
142
  }
126
- throw new Error('...');
143
+ throw new Error("...");
127
144
  }, {
128
145
  manualParsing: true
129
146
  });
130
147
  }
148
+ function loadPostcss() {
149
+ // Try to load a local `postcss` version first
150
+ try {
151
+ return require("postcss");
152
+ } catch {}
153
+ return (0, _indexJs).lazyPostcss();
154
+ }
131
155
  let commands = {
132
156
  init: {
133
157
  run: init,
134
158
  args: {
135
- '--full': {
159
+ "--full": {
136
160
  type: Boolean,
137
- description: 'Initialize a full `tailwind.config.js` file'
161
+ description: `Initialize a full \`${configs.tailwind}\` file`
138
162
  },
139
- '--postcss': {
163
+ "--postcss": {
140
164
  type: Boolean,
141
- description: 'Initialize a `postcss.config.js` file'
165
+ description: `Initialize a \`${configs.postcss}\` file`
142
166
  },
143
- '-f': '--full',
144
- '-p': '--postcss'
167
+ "-f": "--full",
168
+ "-p": "--postcss"
145
169
  }
146
170
  },
147
171
  build: {
148
172
  run: build,
149
173
  args: {
150
- '--input': {
174
+ "--input": {
151
175
  type: String,
152
- description: 'Input file'
176
+ description: "Input file"
153
177
  },
154
- '--output': {
178
+ "--output": {
155
179
  type: String,
156
- description: 'Output file'
180
+ description: "Output file"
181
+ },
182
+ "--watch": {
183
+ type: Boolean,
184
+ description: "Watch for changes and rebuild as needed"
157
185
  },
158
- '--watch': {
186
+ "--poll": {
159
187
  type: Boolean,
160
- description: 'Watch for changes and rebuild as needed'
188
+ description: "Use polling instead of filesystem events when watching"
161
189
  },
162
- '--content': {
190
+ "--content": {
163
191
  type: String,
164
- description: 'Content paths to use for removing unused classes'
192
+ description: "Content paths to use for removing unused classes"
165
193
  },
166
- '--purge': {
194
+ "--purge": {
167
195
  type: String,
168
196
  deprecated: true
169
197
  },
170
- '--postcss': {
198
+ "--postcss": {
171
199
  type: oneOf(String, Boolean),
172
- description: 'Load custom PostCSS configuration'
200
+ description: "Load custom PostCSS configuration"
173
201
  },
174
- '--minify': {
202
+ "--minify": {
175
203
  type: Boolean,
176
- description: 'Minify the output'
204
+ description: "Minify the output"
177
205
  },
178
- '--config': {
206
+ "--config": {
179
207
  type: String,
180
- description: 'Path to a custom config file'
208
+ description: "Path to a custom config file"
181
209
  },
182
- '--no-autoprefixer': {
210
+ "--no-autoprefixer": {
183
211
  type: Boolean,
184
- description: 'Disable autoprefixer'
212
+ description: "Disable autoprefixer"
185
213
  },
186
- '-c': '--config',
187
- '-i': '--input',
188
- '-o': '--output',
189
- '-m': '--minify',
190
- '-w': '--watch'
214
+ "-c": "--config",
215
+ "-i": "--input",
216
+ "-o": "--output",
217
+ "-m": "--minify",
218
+ "-w": "--watch",
219
+ "-p": "--poll"
191
220
  }
192
221
  }
193
222
  };
194
223
  let sharedFlags = {
195
- '--help': {
224
+ "--help": {
196
225
  type: Boolean,
197
- description: 'Display usage information'
226
+ description: "Display usage information"
198
227
  },
199
- '-h': '--help'
228
+ "-h": "--help"
200
229
  };
201
- if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.argv[2] === undefined || process.argv.slice(2).every((flag)=>sharedFlags[flag] !== undefined
202
- ))) {
230
+ if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.argv[2] === undefined || process.argv.slice(2).every((flag)=>sharedFlags[flag] !== undefined))) {
203
231
  help({
204
232
  usage: [
205
- 'tailwindcss [--input input.css] [--output output.css] [--watch] [options...]',
206
- 'tailwindcss init [--full] [--postcss] [options...]',
233
+ "tailwindcss [--input input.css] [--output output.css] [--watch] [options...]",
234
+ "tailwindcss init [--full] [--postcss] [options...]",
207
235
  ],
208
- commands: Object.keys(commands).filter((command2)=>command2 !== 'build'
209
- ).map((command3)=>`${command3} [options]`
210
- ),
236
+ commands: Object.keys(commands).filter((command2)=>command2 !== "build").map((command3)=>`${command3} [options]`),
211
237
  options: {
212
238
  ...commands.build.args,
213
239
  ...sharedFlags
@@ -215,22 +241,19 @@ if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.
215
241
  });
216
242
  process.exit(0);
217
243
  }
218
- let command = ((arg = '')=>arg.startsWith('-') ? undefined : arg
219
- )(process.argv[2]) || 'build';
244
+ let command = ((arg = "")=>arg.startsWith("-") ? undefined : arg)(process.argv[2]) || "build";
220
245
  if (commands[command] === undefined) {
221
246
  if (_fs.default.existsSync(_path.default.resolve(command))) {
222
247
  // TODO: Deprecate this in future versions
223
248
  // Check if non-existing command, might be a file.
224
- command = 'build';
249
+ command = "build";
225
250
  } else {
226
251
  help({
227
252
  message: `Invalid command: ${command}`,
228
253
  usage: [
229
- 'tailwindcss <command> [options]'
254
+ "tailwindcss <command> [options]"
230
255
  ],
231
- commands: Object.keys(commands).filter((command4)=>command4 !== 'build'
232
- ).map((command5)=>`${command5} [options]`
233
- ),
256
+ commands: Object.keys(commands).filter((command4)=>command4 !== "build").map((command5)=>`${command5} [options]`),
234
257
  options: sharedFlags
235
258
  });
236
259
  process.exit(1);
@@ -248,19 +271,18 @@ let args = (()=>{
248
271
  return !(value === null || value === void 0 ? void 0 : (ref = value.type) === null || ref === void 0 ? void 0 : ref.manualParsing);
249
272
  }).map(([key, value])=>[
250
273
  key,
251
- typeof value === 'object' ? value.type : value
252
- ]
253
- )), {
274
+ typeof value === "object" ? value.type : value
275
+ ])), {
254
276
  permissive: true
255
277
  });
256
278
  // Manual parsing of flags to allow for special flags like oneOf(Boolean, String)
257
- for(let i = result['_'].length - 1; i >= 0; --i){
258
- let flag = result['_'][i];
259
- if (!flag.startsWith('-')) continue;
279
+ for(let i = result["_"].length - 1; i >= 0; --i){
280
+ let flag = result["_"][i];
281
+ if (!flag.startsWith("-")) continue;
260
282
  let flagName = flag;
261
283
  let handler = flags[flag];
262
284
  // Resolve flagName & handler
263
- while(typeof handler === 'string'){
285
+ while(typeof handler === "string"){
264
286
  flagName = handler;
265
287
  handler = flags[handler];
266
288
  }
@@ -268,11 +290,11 @@ let args = (()=>{
268
290
  let args1 = [];
269
291
  let offset = i + 1;
270
292
  // Parse args for current flag
271
- while(result['_'][offset] && !result['_'][offset].startsWith('-')){
272
- args1.push(result['_'][offset++]);
293
+ while(result["_"][offset] && !result["_"][offset].startsWith("-")){
294
+ args1.push(result["_"][offset++]);
273
295
  }
274
296
  // Cleanup manually parsed flags + args
275
- result['_'].splice(i, 1 + args1.length);
297
+ result["_"].splice(i, 1 + args1.length);
276
298
  // Set the resolved value in the `result` object
277
299
  result[flagName] = handler.type(args1.length === 0 ? undefined : args1.length === 1 ? args1[0] : args1, flagName);
278
300
  }
@@ -282,16 +304,16 @@ let args = (()=>{
282
304
  //
283
305
  // E.g.: tailwindcss input.css -> _: ['build', 'input.css']
284
306
  // E.g.: tailwindcss build input.css -> _: ['build', 'input.css']
285
- if (result['_'][0] !== command) {
286
- result['_'].unshift(command);
307
+ if (result["_"][0] !== command) {
308
+ result["_"].unshift(command);
287
309
  }
288
310
  return result;
289
311
  } catch (err) {
290
- if (err.code === 'ARG_UNKNOWN_OPTION') {
312
+ if (err.code === "ARG_UNKNOWN_OPTION") {
291
313
  help({
292
314
  message: err.message,
293
315
  usage: [
294
- 'tailwindcss <command> [options]'
316
+ "tailwindcss <command> [options]"
295
317
  ],
296
318
  options: sharedFlags
297
319
  });
@@ -300,7 +322,7 @@ let args = (()=>{
300
322
  throw err;
301
323
  }
302
324
  })();
303
- if (args['--help']) {
325
+ if (args["--help"]) {
304
326
  help({
305
327
  options: {
306
328
  ...flags,
@@ -317,23 +339,23 @@ run();
317
339
  function init() {
318
340
  let messages = [];
319
341
  var ref;
320
- let tailwindConfigLocation = _path.default.resolve((ref = args['_'][1]) !== null && ref !== void 0 ? ref : './tailwind.config.js');
342
+ let tailwindConfigLocation = _path.default.resolve((ref = args["_"][1]) !== null && ref !== void 0 ? ref : `./${configs.tailwind}`);
321
343
  if (_fs.default.existsSync(tailwindConfigLocation)) {
322
344
  messages.push(`${_path.default.basename(tailwindConfigLocation)} already exists.`);
323
345
  } else {
324
- let stubFile = _fs.default.readFileSync(args['--full'] ? _path.default.resolve(__dirname, '../stubs/defaultConfig.stub.js') : _path.default.resolve(__dirname, '../stubs/simpleConfig.stub.js'), 'utf8');
346
+ let stubFile = _fs.default.readFileSync(args["--full"] ? _path.default.resolve(__dirname, "../stubs/defaultConfig.stub.js") : _path.default.resolve(__dirname, "../stubs/simpleConfig.stub.js"), "utf8");
325
347
  // Change colors import
326
- stubFile = stubFile.replace('../colors', 'tailwindcss/colors');
327
- _fs.default.writeFileSync(tailwindConfigLocation, stubFile, 'utf8');
348
+ stubFile = stubFile.replace("../colors", "tailwindcss/colors");
349
+ _fs.default.writeFileSync(tailwindConfigLocation, stubFile, "utf8");
328
350
  messages.push(`Created Tailwind CSS config file: ${_path.default.basename(tailwindConfigLocation)}`);
329
351
  }
330
- if (args['--postcss']) {
331
- let postcssConfigLocation = _path.default.resolve('./postcss.config.js');
352
+ if (args["--postcss"]) {
353
+ let postcssConfigLocation = _path.default.resolve(`./${configs.postcss}`);
332
354
  if (_fs.default.existsSync(postcssConfigLocation)) {
333
355
  messages.push(`${_path.default.basename(postcssConfigLocation)} already exists.`);
334
356
  } else {
335
- let stubFile = _fs.default.readFileSync(_path.default.resolve(__dirname, '../stubs/defaultPostCssConfig.stub.js'), 'utf8');
336
- _fs.default.writeFileSync(postcssConfigLocation, stubFile, 'utf8');
357
+ let stubFile = _fs.default.readFileSync(_path.default.resolve(__dirname, "../stubs/defaultPostCssConfig.stub.js"), "utf8");
358
+ _fs.default.writeFileSync(postcssConfigLocation, stubFile, "utf8");
337
359
  messages.push(`Created PostCSS config file: ${_path.default.basename(postcssConfigLocation)}`);
338
360
  }
339
361
  }
@@ -345,32 +367,36 @@ function init() {
345
367
  }
346
368
  }
347
369
  async function build() {
348
- let input = args['--input'];
349
- let output = args['--output'];
350
- let shouldWatch = args['--watch'];
351
- let includePostCss = args['--postcss'];
370
+ let input = args["--input"];
371
+ let output = args["--output"];
372
+ let shouldWatch = args["--watch"];
373
+ let shouldPoll = args["--poll"];
374
+ let shouldCoalesceWriteEvents = shouldPoll || process.platform === "win32";
375
+ let includePostCss = args["--postcss"];
376
+ // Polling interval in milliseconds
377
+ // Used only when polling or coalescing add/change events on Windows
378
+ let pollInterval = 10;
352
379
  // TODO: Deprecate this in future versions
353
- if (!input && args['_'][1]) {
354
- console.error('[deprecation] Running tailwindcss without -i, please provide an input file.');
355
- input = args['--input'] = args['_'][1];
380
+ if (!input && args["_"][1]) {
381
+ console.error("[deprecation] Running tailwindcss without -i, please provide an input file.");
382
+ input = args["--input"] = args["_"][1];
356
383
  }
357
- if (input && input !== '-' && !_fs.default.existsSync(input = _path.default.resolve(input))) {
358
- console.error(`Specified input file ${args['--input']} does not exist.`);
384
+ if (input && input !== "-" && !_fs.default.existsSync(input = _path.default.resolve(input))) {
385
+ console.error(`Specified input file ${args["--input"]} does not exist.`);
359
386
  process.exit(9);
360
387
  }
361
- if (args['--config'] && !_fs.default.existsSync(args['--config'] = _path.default.resolve(args['--config']))) {
362
- console.error(`Specified config file ${args['--config']} does not exist.`);
388
+ if (args["--config"] && !_fs.default.existsSync(args["--config"] = _path.default.resolve(args["--config"]))) {
389
+ console.error(`Specified config file ${args["--config"]} does not exist.`);
363
390
  process.exit(9);
364
391
  }
365
- let configPath = args['--config'] ? args['--config'] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null
366
- )(_path.default.resolve('./tailwind.config.js'));
392
+ let configPath = args["--config"] ? args["--config"] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null)(_path.default.resolve(`./${configs.tailwind}`));
367
393
  async function loadPostCssPlugins() {
368
- let customPostCssPath = typeof args['--postcss'] === 'string' ? args['--postcss'] : undefined;
369
- let { plugins: configPlugins } = customPostCssPath ? await (async ()=>{
394
+ let customPostCssPath = typeof args["--postcss"] === "string" ? args["--postcss"] : undefined;
395
+ let config1 = customPostCssPath ? await (async ()=>{
370
396
  let file = _path.default.resolve(customPostCssPath);
371
- // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.0.1/src/index.js
372
- let { config ={} } = await (0, _cosmiconfig).cosmiconfig('postcss').load(file);
373
- if (typeof config === 'function') {
397
+ // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.1.0/src/index.js
398
+ let { config ={} } = await (0, _lilconfig).lilconfig("postcss").load(file);
399
+ if (typeof config === "function") {
374
400
  config = config();
375
401
  } else {
376
402
  config = Object.assign({}, config);
@@ -379,14 +405,17 @@ async function build() {
379
405
  config.plugins = [];
380
406
  }
381
407
  return {
382
- plugins: (0, _plugins).default(config, file)
408
+ file,
409
+ plugins: (0, _plugins).default(config, file),
410
+ options: (0, _options).default(config, file)
383
411
  };
384
412
  })() : await (0, _postcssLoadConfig).default();
413
+ let configPlugins = config1.plugins;
385
414
  let configPluginTailwindIdx = configPlugins.findIndex((plugin)=>{
386
- if (typeof plugin === 'function' && plugin.name === 'tailwindcss') {
415
+ if (typeof plugin === "function" && plugin.name === "tailwindcss") {
387
416
  return true;
388
417
  }
389
- if (typeof plugin === 'object' && plugin !== null && plugin.postcssPlugin === 'tailwindcss') {
418
+ if (typeof plugin === "object" && plugin !== null && plugin.postcssPlugin === "tailwindcss") {
390
419
  return true;
391
420
  }
392
421
  return false;
@@ -395,44 +424,47 @@ async function build() {
395
424
  let afterPlugins = configPluginTailwindIdx === -1 ? configPlugins : configPlugins.slice(configPluginTailwindIdx + 1);
396
425
  return [
397
426
  beforePlugins,
398
- afterPlugins
427
+ afterPlugins,
428
+ config1.options
399
429
  ];
400
430
  }
401
431
  function resolveConfig() {
402
432
  let config = configPath ? require(configPath) : {};
403
- if (args['--purge']) {
404
- _log.default.warn('purge-flag-deprecated', [
405
- 'The `--purge` flag has been deprecated.',
406
- 'Please use `--content` instead.',
433
+ if (args["--purge"]) {
434
+ _log.default.warn("purge-flag-deprecated", [
435
+ "The `--purge` flag has been deprecated.",
436
+ "Please use `--content` instead.",
407
437
  ]);
408
- if (!args['--content']) {
409
- args['--content'] = args['--purge'];
438
+ if (!args["--content"]) {
439
+ args["--content"] = args["--purge"];
410
440
  }
411
441
  }
412
- if (args['--content']) {
413
- let files = args['--content'].split(/(?<!{[^}]+),/);
442
+ if (args["--content"]) {
443
+ let files = args["--content"].split(/(?<!{[^}]+),/);
414
444
  let resolvedConfig = (0, _resolveConfig).default(config, {
415
445
  content: {
416
446
  files
417
447
  }
418
448
  });
419
449
  resolvedConfig.content.files = files;
450
+ resolvedConfig = (0, _validateConfigJs).validateConfig(resolvedConfig);
420
451
  return resolvedConfig;
421
452
  }
422
- return (0, _resolveConfig).default(config);
453
+ let resolvedConfig = (0, _resolveConfig).default(config);
454
+ resolvedConfig = (0, _validateConfigJs).validateConfig(resolvedConfig);
455
+ return resolvedConfig;
423
456
  }
424
457
  function extractFileGlobs(config) {
425
458
  return config.content.files.filter((file)=>{
426
459
  // Strings in this case are files / globs. If it is something else,
427
460
  // like an object it's probably a raw content object. But this object
428
461
  // is not watchable, so let's remove it.
429
- return typeof file === 'string';
430
- }).map((glob)=>(0, _normalizePath).default(glob)
431
- );
462
+ return typeof file === "string";
463
+ }).map((glob)=>(0, _normalizePath).default(glob));
432
464
  }
433
465
  function extractRawContent(config) {
434
466
  return config.content.files.filter((file)=>{
435
- return typeof file === 'object' && file !== null;
467
+ return typeof file === "object" && file !== null;
436
468
  });
437
469
  }
438
470
  function getChangedContent(config) {
@@ -442,12 +474,12 @@ async function build() {
442
474
  let files = _fastGlob.default.sync(globs);
443
475
  for (let file of files){
444
476
  changedContent.push({
445
- content: _fs.default.readFileSync(_path.default.resolve(file), 'utf8'),
477
+ content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
446
478
  extension: _path.default.extname(file).slice(1)
447
479
  });
448
480
  }
449
481
  // Resolve raw content in the tailwind config
450
- for (let { raw: content , extension ='html' } of extractRawContent(config)){
482
+ for (let { raw: content , extension ="html" } of extractRawContent(config)){
451
483
  changedContent.push({
452
484
  content,
453
485
  extension
@@ -460,7 +492,7 @@ async function build() {
460
492
  let changedContent = getChangedContent(config);
461
493
  let tailwindPlugin = ()=>{
462
494
  return {
463
- postcssPlugin: 'tailwindcss',
495
+ postcssPlugin: "tailwindcss",
464
496
  Once (root, { result }) {
465
497
  (0, _processTailwindFeatures).default(({ createContext })=>{
466
498
  return ()=>{
@@ -471,26 +503,56 @@ async function build() {
471
503
  };
472
504
  };
473
505
  tailwindPlugin.postcss = true;
474
- let [beforePlugins, afterPlugins] = includePostCss ? await loadPostCssPlugins() : [
506
+ let IMPORT_COMMENT = "__TAILWIND_RESTORE_IMPORT__: ";
507
+ let [beforePlugins, afterPlugins, postcssOptions] = includePostCss ? await loadPostCssPlugins() : [
508
+ [
509
+ (root)=>{
510
+ root.walkAtRules("import", (rule)=>{
511
+ if (rule.params.slice(1).startsWith("tailwindcss/")) {
512
+ rule.after(postcss.comment({
513
+ text: IMPORT_COMMENT + rule.params
514
+ }));
515
+ rule.remove();
516
+ }
517
+ });
518
+ },
519
+ (()=>{
520
+ try {
521
+ return require("postcss-import");
522
+ } catch {}
523
+ return (0, _indexJs).lazyPostcssImport();
524
+ })(),
525
+ (root)=>{
526
+ root.walkComments((rule)=>{
527
+ if (rule.text.startsWith(IMPORT_COMMENT)) {
528
+ rule.after(postcss.atRule({
529
+ name: "import",
530
+ params: rule.text.replace(IMPORT_COMMENT, "")
531
+ }));
532
+ rule.remove();
533
+ }
534
+ });
535
+ },
536
+ ],
475
537
  [],
476
- []
538
+ {},
477
539
  ];
478
540
  let plugins = [
479
541
  ...beforePlugins,
480
542
  tailwindPlugin,
481
- !args['--minify'] && formatNodes,
543
+ !args["--minify"] && formatNodes,
482
544
  ...afterPlugins,
483
- !args['--no-autoprefixer'] && (()=>{
545
+ !args["--no-autoprefixer"] && (()=>{
484
546
  // Try to load a local `autoprefixer` version first
485
547
  try {
486
- return require('autoprefixer');
548
+ return require("autoprefixer");
487
549
  } catch {}
488
550
  return (0, _indexJs).lazyAutoprefixer();
489
551
  })(),
490
- args['--minify'] && (()=>{
552
+ args["--minify"] && (()=>{
491
553
  let options = {
492
554
  preset: [
493
- 'default',
555
+ "default",
494
556
  {
495
557
  cssDeclarationSorter: false
496
558
  }
@@ -498,46 +560,46 @@ async function build() {
498
560
  };
499
561
  // Try to load a local `cssnano` version first
500
562
  try {
501
- return require('cssnano');
563
+ return require("cssnano");
502
564
  } catch {}
503
565
  return (0, _indexJs).lazyCssnano()(options);
504
566
  })(),
505
567
  ].filter(Boolean);
506
- let processor = (0, _indexJs).postcss(plugins);
568
+ let postcss = loadPostcss();
569
+ let processor = postcss(plugins);
507
570
  function processCSS(css) {
508
571
  let start = process.hrtime.bigint();
509
572
  return Promise.resolve().then(()=>output ? _fs.default.promises.mkdir(_path.default.dirname(output), {
510
573
  recursive: true
511
- }) : null
512
- ).then(()=>processor.process(css, {
574
+ }) : null).then(()=>processor.process(css, {
575
+ ...postcssOptions,
513
576
  from: input,
514
577
  to: output
515
- })
516
- ).then((result)=>{
578
+ })).then((result)=>{
517
579
  if (!output) {
518
580
  return process.stdout.write(result.css);
519
581
  }
520
582
  return Promise.all([
521
583
  outputFile(output, result.css),
522
- result.map && outputFile(output + '.map', result.map.toString()),
584
+ result.map && outputFile(output + ".map", result.map.toString()),
523
585
  ].filter(Boolean));
524
586
  }).then(()=>{
525
587
  let end = process.hrtime.bigint();
526
588
  console.error();
527
- console.error('Done in', (end - start) / BigInt(1000000) + 'ms.');
589
+ console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
528
590
  });
529
591
  }
530
592
  let css1 = await (()=>{
531
593
  // Piping in data, let's drain the stdin
532
- if (input === '-') {
594
+ if (input === "-") {
533
595
  return drainStdin();
534
596
  }
535
597
  // Input file has been provided
536
598
  if (input) {
537
- return _fs.default.readFileSync(_path.default.resolve(input), 'utf8');
599
+ return _fs.default.readFileSync(_path.default.resolve(input), "utf8");
538
600
  }
539
601
  // No input file provided, fallback to default atrules
540
- return '@tailwind base; @tailwind components; @tailwind utilities';
602
+ return "@tailwind base; @tailwind components; @tailwind utilities";
541
603
  })();
542
604
  return processCSS(css1);
543
605
  }
@@ -548,18 +610,17 @@ async function build() {
548
610
  let contextDependencies = new Set();
549
611
  let watcher = null;
550
612
  function refreshConfig() {
551
- env.DEBUG && console.time('Module dependencies');
613
+ env.DEBUG && console.time("Module dependencies");
552
614
  for (let file1 of configDependencies){
553
615
  delete require.cache[require.resolve(file1)];
554
616
  }
555
617
  if (configPath) {
556
- configDependencies = (0, _getModuleDependencies).default(configPath).map(({ file })=>file
557
- );
618
+ configDependencies = (0, _getModuleDependencies).default(configPath).map(({ file })=>file);
558
619
  for (let dependency of configDependencies){
559
620
  contextDependencies.add(dependency);
560
621
  }
561
622
  }
562
- env.DEBUG && console.timeEnd('Module dependencies');
623
+ env.DEBUG && console.timeEnd("Module dependencies");
563
624
  return resolveConfig();
564
625
  }
565
626
  let [beforePlugins, afterPlugins] = includePostCss ? await loadPostCssPlugins() : [
@@ -568,20 +629,20 @@ async function build() {
568
629
  ];
569
630
  let plugins = [
570
631
  ...beforePlugins,
571
- '__TAILWIND_PLUGIN_POSITION__',
572
- !args['--minify'] && formatNodes,
632
+ "__TAILWIND_PLUGIN_POSITION__",
633
+ !args["--minify"] && formatNodes,
573
634
  ...afterPlugins,
574
- !args['--no-autoprefixer'] && (()=>{
635
+ !args["--no-autoprefixer"] && (()=>{
575
636
  // Try to load a local `autoprefixer` version first
576
637
  try {
577
- return require('autoprefixer');
638
+ return require("autoprefixer");
578
639
  } catch {}
579
640
  return (0, _indexJs).lazyAutoprefixer();
580
641
  })(),
581
- args['--minify'] && (()=>{
642
+ args["--minify"] && (()=>{
582
643
  let options = {
583
644
  preset: [
584
- 'default',
645
+ "default",
585
646
  {
586
647
  cssDeclarationSorter: false
587
648
  }
@@ -589,53 +650,52 @@ async function build() {
589
650
  };
590
651
  // Try to load a local `cssnano` version first
591
652
  try {
592
- return require('cssnano');
653
+ return require("cssnano");
593
654
  } catch {}
594
655
  return (0, _indexJs).lazyCssnano()(options);
595
656
  })(),
596
657
  ].filter(Boolean);
597
658
  async function rebuild(config) {
598
- env.DEBUG && console.time('Finished in');
659
+ env.DEBUG && console.time("Finished in");
599
660
  let tailwindPlugin = ()=>{
600
661
  return {
601
- postcssPlugin: 'tailwindcss',
662
+ postcssPlugin: "tailwindcss",
602
663
  Once (root, { result }) {
603
- env.DEBUG && console.time('Compiling CSS');
664
+ env.DEBUG && console.time("Compiling CSS");
604
665
  (0, _processTailwindFeatures).default(({ createContext })=>{
605
666
  console.error();
606
- console.error('Rebuilding...');
667
+ console.error("Rebuilding...");
607
668
  return ()=>{
608
669
  if (context !== null) {
609
670
  context.changedContent = changedContent.splice(0);
610
671
  return context;
611
672
  }
612
- env.DEBUG && console.time('Creating context');
673
+ env.DEBUG && console.time("Creating context");
613
674
  context = createContext(config, changedContent.splice(0));
614
- env.DEBUG && console.timeEnd('Creating context');
675
+ env.DEBUG && console.timeEnd("Creating context");
615
676
  return context;
616
677
  };
617
678
  })(root, result);
618
- env.DEBUG && console.timeEnd('Compiling CSS');
679
+ env.DEBUG && console.timeEnd("Compiling CSS");
619
680
  }
620
681
  };
621
682
  };
622
683
  tailwindPlugin.postcss = true;
623
- let tailwindPluginIdx = plugins.indexOf('__TAILWIND_PLUGIN_POSITION__');
684
+ let tailwindPluginIdx = plugins.indexOf("__TAILWIND_PLUGIN_POSITION__");
624
685
  let copy = plugins.slice();
625
686
  copy.splice(tailwindPluginIdx, 1, tailwindPlugin);
626
- let processor = (0, _indexJs).postcss(copy);
687
+ let postcss = loadPostcss();
688
+ let processor = postcss(copy);
627
689
  function processCSS(css) {
628
690
  let start = process.hrtime.bigint();
629
691
  return Promise.resolve().then(()=>output ? _fs.default.promises.mkdir(_path.default.dirname(output), {
630
692
  recursive: true
631
- }) : null
632
- ).then(()=>processor.process(css, {
693
+ }) : null).then(()=>processor.process(css, {
633
694
  from: input,
634
695
  to: output
635
- })
636
- ).then(async (result)=>{
696
+ })).then(async (result)=>{
637
697
  for (let message of result.messages){
638
- if (message.type === 'dependency') {
698
+ if (message.type === "dependency") {
639
699
  contextDependencies.add(message.file);
640
700
  }
641
701
  }
@@ -647,13 +707,13 @@ async function build() {
647
707
  }
648
708
  return Promise.all([
649
709
  outputFile(output, result.css),
650
- result.map && outputFile(output + '.map', result.map.toString()),
710
+ result.map && outputFile(output + ".map", result.map.toString()),
651
711
  ].filter(Boolean));
652
712
  }).then(()=>{
653
713
  let end = process.hrtime.bigint();
654
- console.error('Done in', (end - start) / BigInt(1000000) + 'ms.');
714
+ console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
655
715
  }).catch((err)=>{
656
- if (err.name === 'CssSyntaxError') {
716
+ if (err.name === "CssSyntaxError") {
657
717
  console.error(err.toString());
658
718
  } else {
659
719
  console.error(err);
@@ -662,78 +722,81 @@ async function build() {
662
722
  }
663
723
  let css2 = await (()=>{
664
724
  // Piping in data, let's drain the stdin
665
- if (input === '-') {
725
+ if (input === "-") {
666
726
  return drainStdin();
667
727
  }
668
728
  // Input file has been provided
669
729
  if (input) {
670
- return _fs.default.readFileSync(_path.default.resolve(input), 'utf8');
730
+ return _fs.default.readFileSync(_path.default.resolve(input), "utf8");
671
731
  }
672
732
  // No input file provided, fallback to default atrules
673
- return '@tailwind base; @tailwind components; @tailwind utilities';
733
+ return "@tailwind base; @tailwind components; @tailwind utilities";
674
734
  })();
675
735
  let result1 = await processCSS(css2);
676
- env.DEBUG && console.timeEnd('Finished in');
736
+ env.DEBUG && console.timeEnd("Finished in");
677
737
  return result1;
678
738
  }
679
- let config1 = refreshConfig(configPath);
739
+ let config2 = refreshConfig(configPath);
680
740
  if (input) {
681
741
  contextDependencies.add(_path.default.resolve(input));
682
742
  }
683
743
  watcher = _chokidar.default.watch([
684
744
  ...contextDependencies,
685
- ...extractFileGlobs(config1)
745
+ ...extractFileGlobs(config2)
686
746
  ], {
747
+ usePolling: shouldPoll,
748
+ interval: shouldPoll ? pollInterval : undefined,
687
749
  ignoreInitial: true,
688
- awaitWriteFinish: process.platform === 'win32' ? {
750
+ awaitWriteFinish: shouldCoalesceWriteEvents ? {
689
751
  stabilityThreshold: 50,
690
- pollInterval: 10
752
+ pollInterval: pollInterval
691
753
  } : false
692
754
  });
693
755
  let chain = Promise.resolve();
694
- watcher.on('change', async (file)=>{
756
+ watcher.on("change", async (file)=>{
695
757
  if (contextDependencies.has(file)) {
696
- env.DEBUG && console.time('Resolve config');
758
+ env.DEBUG && console.time("Resolve config");
697
759
  context = null;
698
- config1 = refreshConfig(configPath);
699
- env.DEBUG && console.timeEnd('Resolve config');
700
- env.DEBUG && console.time('Watch new files');
701
- let globs = extractFileGlobs(config1);
760
+ config2 = refreshConfig(configPath);
761
+ env.DEBUG && console.timeEnd("Resolve config");
762
+ env.DEBUG && console.time("Watch new files");
763
+ let globs = extractFileGlobs(config2);
702
764
  watcher.add(configDependencies);
703
765
  watcher.add(globs);
704
- env.DEBUG && console.timeEnd('Watch new files');
766
+ env.DEBUG && console.timeEnd("Watch new files");
705
767
  chain = chain.then(async ()=>{
706
- changedContent.push(...getChangedContent(config1));
707
- await rebuild(config1);
768
+ changedContent.push(...getChangedContent(config2));
769
+ await rebuild(config2);
708
770
  });
709
771
  } else {
710
772
  chain = chain.then(async ()=>{
711
773
  changedContent.push({
712
- content: _fs.default.readFileSync(_path.default.resolve(file), 'utf8'),
774
+ content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
713
775
  extension: _path.default.extname(file).slice(1)
714
776
  });
715
- await rebuild(config1);
777
+ await rebuild(config2);
716
778
  });
717
779
  }
718
780
  });
719
- watcher.on('add', async (file)=>{
781
+ watcher.on("add", async (file)=>{
720
782
  chain = chain.then(async ()=>{
721
783
  changedContent.push({
722
- content: _fs.default.readFileSync(_path.default.resolve(file), 'utf8'),
784
+ content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
723
785
  extension: _path.default.extname(file).slice(1)
724
786
  });
725
- await rebuild(config1);
787
+ await rebuild(config2);
726
788
  });
727
789
  });
728
790
  chain = chain.then(()=>{
729
- changedContent.push(...getChangedContent(config1));
730
- return rebuild(config1);
791
+ changedContent.push(...getChangedContent(config2));
792
+ return rebuild(config2);
731
793
  });
732
794
  }
733
795
  if (shouldWatch) {
734
- /* Abort the watcher if stdin is closed to avoid zombie processes */ process.stdin.on('end', ()=>process.exit(0)
735
- );
736
- process.stdin.resume();
796
+ /* Abort the watcher if stdin is closed to avoid zombie processes */ if (process.stdin.isTTY) {
797
+ process.stdin.on("end", ()=>process.exit(0));
798
+ process.stdin.resume();
799
+ }
737
800
  startWatcher();
738
801
  } else {
739
802
  buildOnce();