tailwindcss 3.2.6 → 3.3.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 (83) hide show
  1. package/CHANGELOG.md +52 -8
  2. package/lib/cli/build/index.js +7 -3
  3. package/lib/cli/build/plugin.js +28 -19
  4. package/lib/cli/build/watching.js +4 -2
  5. package/lib/cli/index.js +12 -21
  6. package/lib/cli/init/index.js +21 -6
  7. package/lib/corePluginList.js +4 -0
  8. package/lib/corePlugins.js +282 -26
  9. package/lib/css/preflight.css +2 -0
  10. package/lib/featureFlags.js +8 -1
  11. package/lib/lib/expandApplyAtRules.js +2 -1
  12. package/lib/lib/generateRules.js +20 -16
  13. package/lib/lib/getModuleDependencies.js +79 -33
  14. package/lib/lib/load-config.js +36 -0
  15. package/lib/lib/setupContextUtils.js +10 -2
  16. package/lib/lib/setupTrackingContext.js +4 -4
  17. package/lib/oxide/cli/build/index.js +7 -3
  18. package/lib/oxide/cli/build/plugin.js +27 -18
  19. package/lib/oxide/cli/build/watching.js +1 -1
  20. package/lib/oxide/cli/index.js +10 -16
  21. package/lib/oxide/cli/init/index.js +19 -4
  22. package/lib/public/colors.js +44 -22
  23. package/lib/public/default-config.js +2 -2
  24. package/lib/public/default-theme.js +2 -2
  25. package/lib/public/load-config.js +10 -0
  26. package/lib/util/applyImportantSelector.js +22 -0
  27. package/lib/util/dataTypes.js +3 -0
  28. package/lib/util/formatVariantSelector.js +2 -12
  29. package/lib/util/getAllConfigs.js +2 -2
  30. package/lib/util/normalizeConfig.js +16 -3
  31. package/lib/util/pluginUtils.js +14 -26
  32. package/lib/util/resolveConfigPath.js +19 -7
  33. package/lib/util/splitAtTopLevelOnly.js +7 -1
  34. package/loadConfig.d.ts +4 -0
  35. package/loadConfig.js +2 -0
  36. package/package.json +5 -4
  37. package/src/cli/build/index.js +7 -7
  38. package/src/cli/build/plugin.js +28 -23
  39. package/src/cli/build/watching.js +4 -2
  40. package/src/cli/index.js +8 -26
  41. package/src/cli/init/index.js +37 -8
  42. package/src/corePluginList.js +1 -1
  43. package/src/corePlugins.js +184 -27
  44. package/src/css/preflight.css +2 -0
  45. package/src/featureFlags.js +7 -0
  46. package/src/lib/expandApplyAtRules.js +2 -1
  47. package/src/lib/generateRules.js +35 -15
  48. package/src/lib/getModuleDependencies.js +70 -30
  49. package/src/lib/load-config.ts +27 -0
  50. package/src/lib/setupContextUtils.js +9 -2
  51. package/src/lib/setupTrackingContext.js +4 -4
  52. package/src/oxide/cli/build/index.ts +7 -7
  53. package/src/oxide/cli/build/plugin.ts +28 -22
  54. package/src/oxide/cli/build/watching.ts +1 -1
  55. package/src/oxide/cli/index.ts +7 -15
  56. package/src/oxide/cli/init/index.ts +34 -7
  57. package/src/public/colors.js +22 -0
  58. package/src/public/default-config.js +1 -1
  59. package/src/public/default-theme.js +2 -2
  60. package/src/public/load-config.js +2 -0
  61. package/src/util/applyImportantSelector.js +19 -0
  62. package/src/util/dataTypes.js +4 -0
  63. package/src/util/formatVariantSelector.js +1 -1
  64. package/src/util/getAllConfigs.js +2 -2
  65. package/src/util/normalizeConfig.js +19 -1
  66. package/src/util/pluginUtils.js +20 -31
  67. package/src/util/resolveConfigPath.js +12 -1
  68. package/src/util/splitAtTopLevelOnly.js +8 -1
  69. package/stubs/.gitignore +1 -0
  70. package/stubs/.prettierrc.json +6 -0
  71. package/stubs/{defaultConfig.stub.js → config.full.js} +38 -3
  72. package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -1
  73. package/stubs/postcss.config.js +6 -0
  74. package/stubs/tailwind.config.cjs +2 -0
  75. package/stubs/tailwind.config.js +2 -0
  76. package/stubs/tailwind.config.ts +3 -0
  77. package/types/config.d.ts +7 -1
  78. package/types/generated/colors.d.ts +22 -0
  79. package/types/generated/corePluginList.d.ts +1 -1
  80. package/types/generated/default-theme.d.ts +31 -2
  81. package/lib/constants.js +0 -44
  82. package/src/constants.js +0 -17
  83. /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
@@ -7,10 +7,10 @@ Object.defineProperty(exports, "default", {
7
7
  get: ()=>_default
8
8
  });
9
9
  const _cloneDeep = require("../util/cloneDeep");
10
- const _defaultConfigStub = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub"));
10
+ const _configFull = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/config.full"));
11
11
  function _interopRequireDefault(obj) {
12
12
  return obj && obj.__esModule ? obj : {
13
13
  default: obj
14
14
  };
15
15
  }
16
- const _default = (0, _cloneDeep.cloneDeep)(_defaultConfigStub.default.theme);
16
+ const _default = (0, _cloneDeep.cloneDeep)(_configFull.default.theme);
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: ()=>_default
8
+ });
9
+ const _loadConfig = require("../lib/load-config");
10
+ const _default = _loadConfig.loadConfig;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "applyImportantSelector", {
6
+ enumerable: true,
7
+ get: ()=>applyImportantSelector
8
+ });
9
+ const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly");
10
+ function applyImportantSelector(selector, important) {
11
+ let matches = /^(.*?)(:before|:after|::[\w-]+)(\)*)$/g.exec(selector);
12
+ if (!matches) return `${important} ${wrapWithIs(selector)}`;
13
+ let [, before, pseudo, brackets] = matches;
14
+ return `${important} ${wrapWithIs(before + brackets)}${pseudo}`;
15
+ }
16
+ function wrapWithIs(selector) {
17
+ let parts = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(selector, " ");
18
+ if (parts.length === 1 && parts[0].startsWith(":is(") && parts[0].endsWith(")")) {
19
+ return selector;
20
+ }
21
+ return `:is(${selector})`;
22
+ }
@@ -41,6 +41,9 @@ function isCSSFunction(value) {
41
41
  const placeholder = "--tw-placeholder";
42
42
  const placeholderRe = new RegExp(placeholder, "g");
43
43
  function normalize(value, isRoot = true) {
44
+ if (value.startsWith("--")) {
45
+ return `var(${value})`;
46
+ }
44
47
  // Keep raw strings if it starts with `url(`
45
48
  if (value.includes("url(")) {
46
49
  return value.split(/(url\(.*?\))/g).filter(Boolean).map((part)=>{
@@ -10,6 +10,7 @@ function _export(target, all) {
10
10
  }
11
11
  _export(exports, {
12
12
  formatVariantSelector: ()=>formatVariantSelector,
13
+ eliminateIrrelevantSelectors: ()=>eliminateIrrelevantSelectors,
13
14
  finalizeSelector: ()=>finalizeSelector,
14
15
  handleMergePseudo: ()=>handleMergePseudo
15
16
  });
@@ -98,18 +99,7 @@ function formatVariantSelector(formats, { context , candidate }) {
98
99
  });
99
100
  return sel;
100
101
  }
101
- /**
102
- * Remove extraneous selectors that do not include the base class/candidate
103
- *
104
- * Example:
105
- * Given the utility `.a, .b { color: red}`
106
- * Given the candidate `sm:b`
107
- *
108
- * The final selector should be `.sm\:b` and not `.a, .sm\:b`
109
- *
110
- * @param {Selector} ast
111
- * @param {string} base
112
- */ function eliminateIrrelevantSelectors(sel, base) {
102
+ function eliminateIrrelevantSelectors(sel, base) {
113
103
  let hasClassesMatchingCandidate = false;
114
104
  sel.walk((child)=>{
115
105
  if (child.type === "class" && child.value === base) {
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "default", {
6
6
  enumerable: true,
7
7
  get: ()=>getAllConfigs
8
8
  });
9
- const _defaultConfigStubJs = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub.js"));
9
+ const _configFullJs = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/config.full.js"));
10
10
  const _featureFlags = require("../featureFlags");
11
11
  function _interopRequireDefault(obj) {
12
12
  return obj && obj.__esModule ? obj : {
@@ -16,7 +16,7 @@ function _interopRequireDefault(obj) {
16
16
  function getAllConfigs(config) {
17
17
  var _config_presets;
18
18
  const configs = ((_config_presets = config === null || config === void 0 ? void 0 : config.presets) !== null && _config_presets !== void 0 ? _config_presets : [
19
- _defaultConfigStubJs.default
19
+ _configFullJs.default
20
20
  ]).slice().reverse().flatMap((preset)=>getAllConfigs(preset instanceof Function ? preset() : preset));
21
21
  const features = {
22
22
  // Add experimental configs here...
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "normalizeConfig", {
6
6
  enumerable: true,
7
7
  get: ()=>normalizeConfig
8
8
  });
9
+ const _featureFlags = require("../featureFlags");
9
10
  const _log = /*#__PURE__*/ _interopRequireWildcard(require("./log"));
10
11
  function _getRequireWildcardCache(nodeInterop) {
11
12
  if (typeof WeakMap !== "function") return null;
@@ -191,13 +192,11 @@ function normalizeConfig(config) {
191
192
  // Normalize the `content`
192
193
  config.content = {
193
194
  relative: (()=>{
194
- var _config_future;
195
195
  let { content } = config;
196
196
  if (content === null || content === void 0 ? void 0 : content.relative) {
197
197
  return content.relative;
198
198
  }
199
- var _config_future_relativeContentPathsByDefault;
200
- return (_config_future_relativeContentPathsByDefault = (_config_future = config.future) === null || _config_future === void 0 ? void 0 : _config_future.relativeContentPathsByDefault) !== null && _config_future_relativeContentPathsByDefault !== void 0 ? _config_future_relativeContentPathsByDefault : false;
199
+ return (0, _featureFlags.flagEnabled)(config, "relativeContentPathsByDefault");
201
200
  })(),
202
201
  files: (()=>{
203
202
  let { content , purge } = config;
@@ -277,5 +276,19 @@ function normalizeConfig(config) {
277
276
  break;
278
277
  }
279
278
  }
279
+ // Warn if the line-clamp plugin is installed
280
+ if (config.plugins.length > 0) {
281
+ let plugin;
282
+ try {
283
+ plugin = require("@tailwindcss/line-clamp");
284
+ } catch {}
285
+ if (plugin && config.plugins.includes(plugin)) {
286
+ _log.default.warn("line-clamp-in-core", [
287
+ "As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.",
288
+ "Remove it from the `plugins` array in your configuration to eliminate this warning."
289
+ ]);
290
+ config.plugins = config.plugins.filter((p)=>p !== plugin);
291
+ }
292
+ }
280
293
  return config;
281
294
  }
@@ -10,7 +10,6 @@ function _export(target, all) {
10
10
  }
11
11
  _export(exports, {
12
12
  updateAllClasses: ()=>updateAllClasses,
13
- filterSelectorsForClass: ()=>filterSelectorsForClass,
14
13
  asValue: ()=>asValue,
15
14
  parseColorFormat: ()=>parseColorFormat,
16
15
  asColor: ()=>asColor,
@@ -19,7 +18,6 @@ _export(exports, {
19
18
  coerceValue: ()=>coerceValue,
20
19
  getMatchingTypes: ()=>getMatchingTypes
21
20
  });
22
- const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser"));
23
21
  const _escapeCommas = /*#__PURE__*/ _interopRequireDefault(require("./escapeCommas"));
24
22
  const _withAlphaVariable = require("./withAlphaVariable");
25
23
  const _dataTypes = require("./dataTypes");
@@ -32,29 +30,12 @@ function _interopRequireDefault(obj) {
32
30
  };
33
31
  }
34
32
  function updateAllClasses(selectors, updateClass) {
35
- let parser = (0, _postcssSelectorParser.default)((selectors)=>{
36
- selectors.walkClasses((sel)=>{
37
- let updatedClass = updateClass(sel.value);
38
- sel.value = updatedClass;
39
- if (sel.raws && sel.raws.value) {
40
- sel.raws.value = (0, _escapeCommas.default)(sel.raws.value);
41
- }
42
- });
43
- });
44
- let result = parser.processSync(selectors);
45
- return result;
46
- }
47
- function filterSelectorsForClass(selectors, classCandidate) {
48
- let parser = (0, _postcssSelectorParser.default)((selectors)=>{
49
- selectors.each((sel)=>{
50
- const containsClass = sel.nodes.some((node)=>node.type === "class" && node.value === classCandidate);
51
- if (!containsClass) {
52
- sel.remove();
53
- }
54
- });
33
+ selectors.walkClasses((sel)=>{
34
+ sel.value = updateClass(sel.value);
35
+ if (sel.raws && sel.raws.value) {
36
+ sel.raws.value = (0, _escapeCommas.default)(sel.raws.value);
37
+ }
55
38
  });
56
- let result = parser.processSync(selectors);
57
- return result;
58
39
  }
59
40
  function resolveArbitraryValue(modifier, validate) {
60
41
  if (!isArbitraryValue(modifier)) {
@@ -123,6 +104,13 @@ function parseColorFormat(value) {
123
104
  }
124
105
  return value;
125
106
  }
107
+ function unwrapArbitraryModifier(modifier) {
108
+ modifier = modifier.slice(1, -1);
109
+ if (modifier.startsWith("--")) {
110
+ modifier = `var(${modifier})`;
111
+ }
112
+ return modifier;
113
+ }
126
114
  function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
127
115
  var _options_values;
128
116
  if (((_options_values = options.values) === null || _options_values === void 0 ? void 0 : _options_values[modifier]) !== undefined) {
@@ -141,7 +129,7 @@ function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) {
141
129
  }
142
130
  normalizedColor = parseColorFormat(normalizedColor);
143
131
  if (isArbitraryValue(alpha)) {
144
- return (0, _withAlphaVariable.withAlphaValue)(normalizedColor, alpha.slice(1, -1));
132
+ return (0, _withAlphaVariable.withAlphaValue)(normalizedColor, unwrapArbitraryModifier(alpha));
145
133
  }
146
134
  if (((_tailwindConfig_theme = tailwindConfig.theme) === null || _tailwindConfig_theme === void 0 ? void 0 : (_tailwindConfig_theme_opacity = _tailwindConfig_theme.opacity) === null || _tailwindConfig_theme_opacity === void 0 ? void 0 : _tailwindConfig_theme_opacity[alpha]) === undefined) {
147
135
  return undefined;
@@ -256,7 +244,7 @@ function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
256
244
  if (configValue !== null) {
257
245
  utilityModifier = configValue;
258
246
  } else if (isArbitraryValue(utilityModifier)) {
259
- utilityModifier = utilityModifier.slice(1, -1);
247
+ utilityModifier = unwrapArbitraryModifier(utilityModifier);
260
248
  }
261
249
  }
262
250
  }
@@ -2,9 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "default", {
6
- enumerable: true,
7
- get: ()=>resolveConfigPath
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ default: ()=>resolveConfigPath,
13
+ resolveDefaultConfigPath: ()=>resolveDefaultConfigPath
8
14
  });
9
15
  const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
10
16
  const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
@@ -13,6 +19,12 @@ function _interopRequireDefault(obj) {
13
19
  default: obj
14
20
  };
15
21
  }
22
+ const defaultConfigFiles = [
23
+ "./tailwind.config.js",
24
+ "./tailwind.config.cjs",
25
+ "./tailwind.config.mjs",
26
+ "./tailwind.config.ts"
27
+ ];
16
28
  function isObject(value) {
17
29
  return typeof value === "object" && value !== null;
18
30
  }
@@ -40,10 +52,10 @@ function resolveConfigPath(pathOrConfig) {
40
52
  return _path.default.resolve(pathOrConfig);
41
53
  }
42
54
  // require('tailwindcss')
43
- for (const configFile of [
44
- "./tailwind.config.js",
45
- "./tailwind.config.cjs"
46
- ]){
55
+ return resolveDefaultConfigPath();
56
+ }
57
+ function resolveDefaultConfigPath() {
58
+ for (const configFile of defaultConfigFiles){
47
59
  try {
48
60
  const configPath = _path.default.resolve(configFile);
49
61
  _fs.default.accessSync(configPath);
@@ -24,14 +24,20 @@ function splitAtTopLevelOnly(input, separator) {
24
24
  let stack = [];
25
25
  let parts = [];
26
26
  let lastPos = 0;
27
+ let isEscaped = false;
27
28
  for(let idx = 0; idx < input.length; idx++){
28
29
  let char = input[idx];
29
- if (stack.length === 0 && char === separator[0]) {
30
+ if (stack.length === 0 && char === separator[0] && !isEscaped) {
30
31
  if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) {
31
32
  parts.push(input.slice(lastPos, idx));
32
33
  lastPos = idx + separator.length;
33
34
  }
34
35
  }
36
+ if (isEscaped) {
37
+ isEscaped = false;
38
+ } else if (char === "\\") {
39
+ isEscaped = true;
40
+ }
35
41
  if (char === "(" || char === "[" || char === "{") {
36
42
  stack.push(char);
37
43
  } else if (char === ")" && stack[stack.length - 1] === "(" || char === "]" && stack[stack.length - 1] === "[" || char === "}" && stack[stack.length - 1] === "{") {
@@ -0,0 +1,4 @@
1
+ import type { Config } from './types/config'
2
+
3
+ declare function loadConfig(path: string): Config
4
+ export = loadConfig
package/loadConfig.js ADDED
@@ -0,0 +1,2 @@
1
+ let loadConfig = require('./lib/public/load-config')
2
+ module.exports = (loadConfig.__esModule ? loadConfig : { default: loadConfig }).default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwindcss",
3
- "version": "3.2.6",
3
+ "version": "3.3.0",
4
4
  "description": "A utility-first CSS framework for rapidly building custom user interfaces.",
5
5
  "license": "MIT",
6
6
  "main": "lib/index.js",
@@ -38,7 +38,7 @@
38
38
  "lib/*",
39
39
  "peers/*",
40
40
  "scripts/*.js",
41
- "stubs/*.stub.js",
41
+ "stubs/*",
42
42
  "nesting/*",
43
43
  "types/**/*",
44
44
  "*.d.ts",
@@ -73,12 +73,12 @@
73
73
  "arg": "^5.0.2",
74
74
  "chokidar": "^3.5.3",
75
75
  "color-name": "^1.1.4",
76
- "detective": "^5.2.1",
77
76
  "didyoumean": "^1.2.2",
78
77
  "dlv": "^1.1.3",
79
78
  "fast-glob": "^3.2.12",
80
79
  "glob-parent": "^6.0.2",
81
80
  "is-glob": "^4.0.3",
81
+ "jiti": "^1.17.2",
82
82
  "lilconfig": "^2.0.6",
83
83
  "micromatch": "^4.0.5",
84
84
  "normalize-path": "^3.0.0",
@@ -92,7 +92,8 @@
92
92
  "postcss-selector-parser": "^6.0.11",
93
93
  "postcss-value-parser": "^4.2.0",
94
94
  "quick-lru": "^5.1.1",
95
- "resolve": "^1.22.1"
95
+ "resolve": "^1.22.1",
96
+ "sucrase": "^3.29.0"
96
97
  },
97
98
  "browserslist": [
98
99
  "> 1%",
@@ -2,9 +2,10 @@
2
2
 
3
3
  import fs from 'fs'
4
4
  import path from 'path'
5
+ import { resolveDefaultConfigPath } from '../../util/resolveConfigPath.js'
5
6
  import { createProcessor } from './plugin.js'
6
7
 
7
- export async function build(args, configs) {
8
+ export async function build(args) {
8
9
  let input = args['--input']
9
10
  let shouldWatch = args['--watch']
10
11
 
@@ -25,11 +26,7 @@ export async function build(args, configs) {
25
26
  }
26
27
 
27
28
  // TODO: Reference the @config path here if exists
28
- let configPath = args['--config']
29
- ? args['--config']
30
- : ((defaultPath) => (fs.existsSync(defaultPath) ? defaultPath : null))(
31
- path.resolve(`./${configs.tailwind}`)
32
- )
29
+ let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath()
33
30
 
34
31
  let processor = await createProcessor(args, configPath)
35
32
 
@@ -44,6 +41,9 @@ export async function build(args, configs) {
44
41
 
45
42
  await processor.watch()
46
43
  } else {
47
- await processor.build()
44
+ await processor.build().catch((e) => {
45
+ console.error(e)
46
+ process.exit(1)
47
+ })
48
48
  }
49
49
  }
@@ -12,12 +12,13 @@ import { loadAutoprefixer, loadCssNano, loadPostcss, loadPostcssImport } from '.
12
12
  import { formatNodes, drainStdin, outputFile } from './utils'
13
13
  import { env } from '../../lib/sharedState'
14
14
  import resolveConfig from '../../../resolveConfig.js'
15
- import getModuleDependencies from '../../lib/getModuleDependencies.js'
16
15
  import { parseCandidateFiles } from '../../lib/content.js'
17
16
  import { createWatcher } from './watching.js'
18
17
  import fastGlob from 'fast-glob'
19
18
  import { findAtConfigPath } from '../../lib/findAtConfigPath.js'
20
19
  import log from '../../util/log'
20
+ import { loadConfig } from '../../lib/load-config'
21
+ import getModuleDependencies from '../../lib/getModuleDependencies'
21
22
 
22
23
  /**
23
24
  *
@@ -117,7 +118,9 @@ let state = {
117
118
  /** @type {{content: string, extension: string}[]} */
118
119
  changedContent: [],
119
120
 
120
- configDependencies: new Set(),
121
+ /** @type {ReturnType<typeof load> | null} */
122
+ configBag: null,
123
+
121
124
  contextDependencies: new Set(),
122
125
 
123
126
  /** @type {import('../../lib/content.js').ContentPath[]} */
@@ -142,37 +145,35 @@ let state = {
142
145
 
143
146
  loadConfig(configPath, content) {
144
147
  if (this.watcher && configPath) {
145
- this.refreshConfigDependencies(configPath)
148
+ this.refreshConfigDependencies()
146
149
  }
147
150
 
148
- let config = configPath ? require(configPath) : {}
151
+ let config = loadConfig(configPath)
152
+ let dependencies = getModuleDependencies(configPath)
153
+ this.configBag = {
154
+ config,
155
+ dependencies,
156
+ dispose() {
157
+ for (let file of dependencies) {
158
+ delete require.cache[require.resolve(file)]
159
+ }
160
+ },
161
+ }
149
162
 
150
163
  // @ts-ignore
151
- config = resolveConfig(config, { content: { files: [] } })
164
+ this.configBag.config = resolveConfig(this.configBag.config, { content: { files: [] } })
152
165
 
153
166
  // Override content files if `--content` has been passed explicitly
154
167
  if (content?.length > 0) {
155
- config.content.files = content
168
+ this.configBag.config.content.files = content
156
169
  }
157
170
 
158
- return config
171
+ return this.configBag.config
159
172
  },
160
173
 
161
- refreshConfigDependencies(configPath) {
174
+ refreshConfigDependencies() {
162
175
  env.DEBUG && console.time('Module dependencies')
163
-
164
- for (let file of this.configDependencies) {
165
- delete require.cache[require.resolve(file)]
166
- }
167
-
168
- if (configPath) {
169
- let deps = getModuleDependencies(configPath).map(({ file }) => file)
170
-
171
- for (let dependency of deps) {
172
- this.configDependencies.add(dependency)
173
- }
174
- }
175
-
176
+ this.configBag?.dispose()
176
177
  env.DEBUG && console.timeEnd('Module dependencies')
177
178
  },
178
179
 
@@ -383,7 +384,11 @@ export async function createProcessor(args, cliConfigPath) {
383
384
  // The watcher will start watching the imported CSS files and will be
384
385
  // resilient to future errors.
385
386
 
386
- console.error(err)
387
+ if (state.watcher) {
388
+ console.error(err)
389
+ } else {
390
+ return Promise.reject(err)
391
+ }
387
392
  }
388
393
  )
389
394
  }
@@ -416,7 +421,7 @@ export async function createProcessor(args, cliConfigPath) {
416
421
  async rebuild(changes) {
417
422
  let needsNewContext = changes.some((change) => {
418
423
  return (
419
- state.configDependencies.has(change.file) ||
424
+ state.configBag?.dependencies.has(change.file) ||
420
425
  state.contextDependencies.has(change.file)
421
426
  )
422
427
  })
@@ -89,7 +89,9 @@ export function createWatcher(args, { state, rebuild }) {
89
89
  // Resolve the promise even when the rebuild fails
90
90
  return rebuild(changes).then(
91
91
  () => {},
92
- () => {}
92
+ (e) => {
93
+ console.error(e.toString())
94
+ }
93
95
  )
94
96
  }
95
97
 
@@ -220,7 +222,7 @@ export function createWatcher(args, { state, rebuild }) {
220
222
 
221
223
  refreshWatchedFiles() {
222
224
  watcher.add(Array.from(state.contextDependencies))
223
- watcher.add(Array.from(state.configDependencies))
225
+ watcher.add(Array.from(state.configBag.dependencies))
224
226
  watcher.add(state.contentPatterns.all)
225
227
  },
226
228
  }
package/src/cli/index.js CHANGED
@@ -8,29 +8,6 @@ import { build } from './build'
8
8
  import { help } from './help'
9
9
  import { init } from './init'
10
10
 
11
- function isESM() {
12
- const pkgPath = path.resolve('./package.json')
13
-
14
- try {
15
- let pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
16
- return pkg.type && pkg.type === 'module'
17
- } catch (err) {
18
- return false
19
- }
20
- }
21
-
22
- let configs = isESM()
23
- ? {
24
- tailwind: 'tailwind.config.cjs',
25
- postcss: 'postcss.config.cjs',
26
- }
27
- : {
28
- tailwind: 'tailwind.config.js',
29
- postcss: 'postcss.config.js',
30
- }
31
-
32
- // ---
33
-
34
11
  function oneOf(...options) {
35
12
  return Object.assign(
36
13
  (value = true) => {
@@ -51,8 +28,13 @@ let commands = {
51
28
  init: {
52
29
  run: init,
53
30
  args: {
54
- '--full': { type: Boolean, description: `Initialize a full \`${configs.tailwind}\` file` },
55
- '--postcss': { type: Boolean, description: `Initialize a \`${configs.postcss}\` file` },
31
+ '--esm': { type: Boolean, description: `Initialize configuration file as ESM` },
32
+ '--ts': { type: Boolean, description: `Initialize configuration file as TypeScript` },
33
+ '--postcss': { type: Boolean, description: `Initialize a \`postcss.config.js\` file` },
34
+ '--full': {
35
+ type: Boolean,
36
+ description: `Include the default values for all options in the generated configuration file`,
37
+ },
56
38
  '-f': '--full',
57
39
  '-p': '--postcss',
58
40
  },
@@ -231,4 +213,4 @@ if (args['--help']) {
231
213
  process.exit(0)
232
214
  }
233
215
 
234
- run(args, configs)
216
+ run(args)
@@ -3,22 +3,49 @@
3
3
  import fs from 'fs'
4
4
  import path from 'path'
5
5
 
6
- export function init(args, configs) {
6
+ function isESM() {
7
+ const pkgPath = path.resolve('./package.json')
8
+
9
+ try {
10
+ let pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
11
+ return pkg.type && pkg.type === 'module'
12
+ } catch (err) {
13
+ return false
14
+ }
15
+ }
16
+
17
+ export function init(args) {
7
18
  let messages = []
8
19
 
9
- let tailwindConfigLocation = path.resolve(args['_'][1] ?? `./${configs.tailwind}`)
20
+ let isProjectESM = args['--ts'] || args['--esm'] || isESM()
21
+ let syntax = args['--ts'] ? 'ts' : isProjectESM ? 'js' : 'cjs'
22
+ let extension = args['--ts'] ? 'ts' : 'js'
23
+
24
+ let tailwindConfigLocation = path.resolve(args['_'][1] ?? `./tailwind.config.${extension}`)
25
+
10
26
  if (fs.existsSync(tailwindConfigLocation)) {
11
27
  messages.push(`${path.basename(tailwindConfigLocation)} already exists.`)
12
28
  } else {
13
- let stubFile = fs.readFileSync(
29
+ let stubContentsFile = fs.readFileSync(
14
30
  args['--full']
15
- ? path.resolve(__dirname, '../../../stubs/defaultConfig.stub.js')
16
- : path.resolve(__dirname, '../../../stubs/simpleConfig.stub.js'),
31
+ ? path.resolve(__dirname, '../../../stubs/config.full.js')
32
+ : path.resolve(__dirname, '../../../stubs/config.simple.js'),
33
+ 'utf8'
34
+ )
35
+
36
+ let stubFile = fs.readFileSync(
37
+ path.resolve(__dirname, `../../../stubs/tailwind.config.${syntax}`),
17
38
  'utf8'
18
39
  )
19
40
 
20
41
  // Change colors import
21
- stubFile = stubFile.replace('../colors', 'tailwindcss/colors')
42
+ stubContentsFile = stubContentsFile.replace('../colors', 'tailwindcss/colors')
43
+
44
+ // Replace contents of {ts,js,cjs} file with the stub {simple,full}.
45
+ stubFile =
46
+ stubFile
47
+ .replace('__CONFIG__', stubContentsFile.replace('module.exports =', '').trim())
48
+ .trim() + '\n\n'
22
49
 
23
50
  fs.writeFileSync(tailwindConfigLocation, stubFile, 'utf8')
24
51
 
@@ -26,12 +53,14 @@ export function init(args, configs) {
26
53
  }
27
54
 
28
55
  if (args['--postcss']) {
29
- let postcssConfigLocation = path.resolve(`./${configs.postcss}`)
56
+ let postcssConfigLocation = path.resolve('./postcss.config.js')
30
57
  if (fs.existsSync(postcssConfigLocation)) {
31
58
  messages.push(`${path.basename(postcssConfigLocation)} already exists.`)
32
59
  } else {
33
60
  let stubFile = fs.readFileSync(
34
- path.resolve(__dirname, '../../../stubs/defaultPostCssConfig.stub.js'),
61
+ isProjectESM
62
+ ? path.resolve(__dirname, '../../../stubs/postcss.config.js')
63
+ : path.resolve(__dirname, '../../../stubs/postcss.config.cjs'),
35
64
  'utf8'
36
65
  )
37
66
 
@@ -1 +1 @@
1
- export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]
1
+ export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]