tailwindcss 3.2.3 → 3.2.5
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 +56 -1
- package/README.md +1 -1
- package/lib/cli/build/index.js +5 -1
- package/lib/cli/build/plugin.js +50 -34
- package/lib/cli/build/watching.js +6 -3
- 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 +35 -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 +122 -79
- 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 +36 -22
- package/lib/util/pluginUtils.js +38 -40
- package/lib/util/prefixSelector.js +22 -8
- package/lib/util/resolveConfig.js +8 -10
- package/oxide-node-api-shim/index.js +21 -0
- package/oxide-node-api-shim/package.json +5 -0
- package/package.json +32 -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 +31 -9
- package/src/cli/build/watching.js +6 -3
- 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 +37 -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 +99 -56
- 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/normalizeConfig.js +18 -0
- 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
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
- Nothing yet!
|
|
11
11
|
|
|
12
|
+
## [3.2.5] - 2023-02-08
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Add standalone CLI build for 64-bit Windows on ARM (`node16-win-arm64`) ([#10001](https://github.com/tailwindlabs/tailwindcss/pull/10001))
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Cleanup unused `variantOrder` ([#9829](https://github.com/tailwindlabs/tailwindcss/pull/9829))
|
|
21
|
+
- Fix `foo-[abc]/[def]` not being handled correctly ([#9866](https://github.com/tailwindlabs/tailwindcss/pull/9866))
|
|
22
|
+
- Add container queries plugin to standalone CLI ([#9865](https://github.com/tailwindlabs/tailwindcss/pull/9865))
|
|
23
|
+
- Support renaming of output files by `PostCSS` plugin. ([#9944](https://github.com/tailwindlabs/tailwindcss/pull/9944))
|
|
24
|
+
- Improve return value of `resolveConfig`, unwrap `ResolvableTo` ([#9972](https://github.com/tailwindlabs/tailwindcss/pull/9972))
|
|
25
|
+
- Clip unbalanced brackets in arbitrary values ([#9973](https://github.com/tailwindlabs/tailwindcss/pull/9973))
|
|
26
|
+
- Don’t reorder webkit scrollbar pseudo elements ([#9991](https://github.com/tailwindlabs/tailwindcss/pull/9991))
|
|
27
|
+
- Deterministic sorting of arbitrary variants ([#10016](https://github.com/tailwindlabs/tailwindcss/pull/10016))
|
|
28
|
+
- Add `data` key to theme types ([#10023](https://github.com/tailwindlabs/tailwindcss/pull/10023))
|
|
29
|
+
- Prevent invalid arbitrary variant selectors from failing the build ([#10059](https://github.com/tailwindlabs/tailwindcss/pull/10059))
|
|
30
|
+
- Properly handle subtraction followed by a variable ([#10074](https://github.com/tailwindlabs/tailwindcss/pull/10074))
|
|
31
|
+
- Fix missing `string[]` in the `theme.dropShadow` types ([#10072](https://github.com/tailwindlabs/tailwindcss/pull/10072))
|
|
32
|
+
- Update list of length units ([#10100](https://github.com/tailwindlabs/tailwindcss/pull/10100))
|
|
33
|
+
- Fix not matching arbitrary properties when closely followed by square brackets ([#10212](https://github.com/tailwindlabs/tailwindcss/pull/10212))
|
|
34
|
+
- Allow direct nesting in `root` or `@layer` nodes ([#10229](https://github.com/tailwindlabs/tailwindcss/pull/10229))
|
|
35
|
+
- Don't prefix classes in arbitrary variants ([#10214](https://github.com/tailwindlabs/tailwindcss/pull/10214))
|
|
36
|
+
- Fix perf regression when checking for changed content ([#10234](https://github.com/tailwindlabs/tailwindcss/pull/10234))
|
|
37
|
+
- Fix missing `blocklist` member in the `Config` type ([#10239](https://github.com/tailwindlabs/tailwindcss/pull/10239))
|
|
38
|
+
- Escape group names in selectors ([#10276](https://github.com/tailwindlabs/tailwindcss/pull/10276))
|
|
39
|
+
- Consider earlier variants before sorting functions ([#10288](https://github.com/tailwindlabs/tailwindcss/pull/10288))
|
|
40
|
+
- Allow variants with slashes ([#10336](https://github.com/tailwindlabs/tailwindcss/pull/10336))
|
|
41
|
+
- Ensure generated CSS is always sorted in the same order for a given set of templates ([#10382](https://github.com/tailwindlabs/tailwindcss/pull/10382))
|
|
42
|
+
- Handle variants when the same class appears multiple times in a selector ([#10397](https://github.com/tailwindlabs/tailwindcss/pull/10397))
|
|
43
|
+
- Handle group/peer variants with quoted strings ([#10400](https://github.com/tailwindlabs/tailwindcss/pull/10400))
|
|
44
|
+
- Parse alpha value from rgba/hsla colors when using variables ([#10429](https://github.com/tailwindlabs/tailwindcss/pull/10429))
|
|
45
|
+
- Sort by `layer` inside `variants` layer ([#10505](https://github.com/tailwindlabs/tailwindcss/pull/10505))
|
|
46
|
+
- Add `--watch=always` option to prevent exit when stdin closes ([#9966](https://github.com/tailwindlabs/tailwindcss/pull/9966))
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- Alphabetize `theme` keys in default config ([#9953](https://github.com/tailwindlabs/tailwindcss/pull/9953))
|
|
51
|
+
- Update esbuild to v17 ([#10368](https://github.com/tailwindlabs/tailwindcss/pull/10368))
|
|
52
|
+
- Include `outline-color` in `transition` and `transition-colors` utilitires ([#10385](https://github.com/tailwindlabs/tailwindcss/pull/10385))
|
|
53
|
+
|
|
54
|
+
## [3.2.4] - 2022-11-11
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- Add `blocklist` option to prevent generating unwanted CSS ([#9812](https://github.com/tailwindlabs/tailwindcss/pull/9812))
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- Fix watching of files on Linux when renames are involved ([#9796](https://github.com/tailwindlabs/tailwindcss/pull/9796))
|
|
63
|
+
- Make sure errors are always displayed when watching for changes ([#9810](https://github.com/tailwindlabs/tailwindcss/pull/9810))
|
|
64
|
+
|
|
12
65
|
## [3.2.3] - 2022-11-09
|
|
13
66
|
|
|
14
67
|
### Fixed
|
|
@@ -2110,7 +2163,9 @@ No release notes
|
|
|
2110
2163
|
|
|
2111
2164
|
- Everything!
|
|
2112
2165
|
|
|
2113
|
-
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.
|
|
2166
|
+
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.5...HEAD
|
|
2167
|
+
[3.2.5]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.4...v3.2.5
|
|
2168
|
+
[3.2.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.3...v3.2.4
|
|
2114
2169
|
[3.2.3]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.2...v3.2.3
|
|
2115
2170
|
[3.2.2]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.1...v3.2.2
|
|
2116
2171
|
[3.2.1]: https://github.com/tailwindlabs/tailwindcss/compare/v3.2.0...v3.2.1
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/workflow/status/tailwindlabs/tailwindcss/
|
|
17
|
+
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci-stable.yml?branch=master" alt="Build Status"></a>
|
|
18
18
|
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
|
|
19
19
|
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
|
|
20
20
|
<a href="https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a>
|
package/lib/cli/build/index.js
CHANGED
|
@@ -35,7 +35,11 @@ async function build(args, configs) {
|
|
|
35
35
|
let configPath = args["--config"] ? args["--config"] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null)(_path.default.resolve(`./${configs.tailwind}`));
|
|
36
36
|
let processor = await (0, _pluginJs.createProcessor)(args, configPath);
|
|
37
37
|
if (shouldWatch) {
|
|
38
|
-
|
|
38
|
+
// Abort the watcher if stdin is closed to avoid zombie processes
|
|
39
|
+
// You can disable this behavior with --watch=always
|
|
40
|
+
if (args["--watch"] !== "always") {
|
|
41
|
+
process.stdin.on("end", ()=>process.exit(0));
|
|
42
|
+
}
|
|
39
43
|
process.stdin.resume();
|
|
40
44
|
await processor.watch();
|
|
41
45
|
} else {
|
package/lib/cli/build/plugin.js
CHANGED
|
@@ -18,7 +18,7 @@ const _options = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-conf
|
|
|
18
18
|
const _processTailwindFeatures = /*#__PURE__*/ _interopRequireDefault(require("../../processTailwindFeatures"));
|
|
19
19
|
const _deps = require("./deps");
|
|
20
20
|
const _utils = require("./utils");
|
|
21
|
-
const
|
|
21
|
+
const _sharedState = require("../../lib/sharedState");
|
|
22
22
|
const _resolveConfigJs = /*#__PURE__*/ _interopRequireDefault(require("../../../resolveConfig.js"));
|
|
23
23
|
const _getModuleDependenciesJs = /*#__PURE__*/ _interopRequireDefault(require("../../lib/getModuleDependencies.js"));
|
|
24
24
|
const _contentJs = require("../../lib/content.js");
|
|
@@ -113,8 +113,8 @@ let state = {
|
|
|
113
113
|
contextDependencies: new Set(),
|
|
114
114
|
/** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [],
|
|
115
115
|
refreshContentPaths () {
|
|
116
|
-
var
|
|
117
|
-
this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (
|
|
116
|
+
var _this_context;
|
|
117
|
+
this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig);
|
|
118
118
|
},
|
|
119
119
|
get config () {
|
|
120
120
|
return this.context.tailwindConfig;
|
|
@@ -143,7 +143,7 @@ let state = {
|
|
|
143
143
|
return config;
|
|
144
144
|
},
|
|
145
145
|
refreshConfigDependencies (configPath) {
|
|
146
|
-
|
|
146
|
+
_sharedState.env.DEBUG && console.time("Module dependencies");
|
|
147
147
|
for (let file of this.configDependencies){
|
|
148
148
|
delete require.cache[require.resolve(file)];
|
|
149
149
|
}
|
|
@@ -153,7 +153,7 @@ let state = {
|
|
|
153
153
|
this.configDependencies.add(dependency);
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
_sharedState.env.DEBUG && console.timeEnd("Module dependencies");
|
|
157
157
|
},
|
|
158
158
|
readContentPaths () {
|
|
159
159
|
let content = [];
|
|
@@ -161,10 +161,17 @@ let state = {
|
|
|
161
161
|
// TODO: When we make the postcss plugin async-capable this can become async
|
|
162
162
|
let files = _fastGlob.default.sync(this.contentPatterns.all);
|
|
163
163
|
for (let file of files){
|
|
164
|
-
|
|
165
|
-
content
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
if (_sharedState.env.OXIDE) {
|
|
165
|
+
content.push({
|
|
166
|
+
file,
|
|
167
|
+
extension: _path.default.extname(file).slice(1)
|
|
168
|
+
});
|
|
169
|
+
} else {
|
|
170
|
+
content.push({
|
|
171
|
+
content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
|
|
172
|
+
extension: _path.default.extname(file).slice(1)
|
|
173
|
+
});
|
|
174
|
+
}
|
|
168
175
|
}
|
|
169
176
|
// Resolve raw content in the tailwind config
|
|
170
177
|
let rawContent = this.config.content.files.filter((file)=>{
|
|
@@ -183,37 +190,35 @@ let state = {
|
|
|
183
190
|
this.context.changedContent = this.changedContent.splice(0);
|
|
184
191
|
return this.context;
|
|
185
192
|
}
|
|
186
|
-
|
|
187
|
-
var
|
|
188
|
-
let configPath = (
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
_sharedState.env.DEBUG && console.time("Searching for config");
|
|
194
|
+
var _findAtConfigPath;
|
|
195
|
+
let configPath = (_findAtConfigPath = (0, _findAtConfigPathJs.findAtConfigPath)(root, result)) !== null && _findAtConfigPath !== void 0 ? _findAtConfigPath : cliConfigPath;
|
|
196
|
+
_sharedState.env.DEBUG && console.timeEnd("Searching for config");
|
|
197
|
+
_sharedState.env.DEBUG && console.time("Loading config");
|
|
191
198
|
let config = this.loadConfig(configPath, content);
|
|
192
|
-
|
|
193
|
-
|
|
199
|
+
_sharedState.env.DEBUG && console.timeEnd("Loading config");
|
|
200
|
+
_sharedState.env.DEBUG && console.time("Creating context");
|
|
194
201
|
this.context = createContext(config, []);
|
|
195
202
|
Object.assign(this.context, {
|
|
196
203
|
userConfigPath: configPath
|
|
197
204
|
});
|
|
198
|
-
|
|
199
|
-
|
|
205
|
+
_sharedState.env.DEBUG && console.timeEnd("Creating context");
|
|
206
|
+
_sharedState.env.DEBUG && console.time("Resolving content paths");
|
|
200
207
|
this.refreshContentPaths();
|
|
201
|
-
|
|
208
|
+
_sharedState.env.DEBUG && console.timeEnd("Resolving content paths");
|
|
202
209
|
if (this.watcher) {
|
|
203
|
-
|
|
210
|
+
_sharedState.env.DEBUG && console.time("Watch new files");
|
|
204
211
|
this.watcher.refreshWatchedFiles();
|
|
205
|
-
|
|
212
|
+
_sharedState.env.DEBUG && console.timeEnd("Watch new files");
|
|
206
213
|
}
|
|
207
|
-
_shared.env.DEBUG && console.time("Reading content files");
|
|
208
214
|
for (let file of this.readContentPaths()){
|
|
209
215
|
this.context.changedContent.push(file);
|
|
210
216
|
}
|
|
211
|
-
_shared.env.DEBUG && console.timeEnd("Reading content files");
|
|
212
217
|
return this.context;
|
|
213
218
|
}
|
|
214
219
|
};
|
|
215
220
|
async function createProcessor(args, cliConfigPath) {
|
|
216
|
-
var
|
|
221
|
+
var _args_content;
|
|
217
222
|
let postcss = (0, _deps.loadPostcss)();
|
|
218
223
|
let input = args["--input"];
|
|
219
224
|
let output = args["--output"];
|
|
@@ -229,13 +234,13 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
229
234
|
args["--content"] = args["--purge"];
|
|
230
235
|
}
|
|
231
236
|
}
|
|
232
|
-
var
|
|
233
|
-
let content = (
|
|
237
|
+
var _args_content_split;
|
|
238
|
+
let content = (_args_content_split = (_args_content = args["--content"]) === null || _args_content === void 0 ? void 0 : _args_content.split(/(?<!{[^}]+),/)) !== null && _args_content_split !== void 0 ? _args_content_split : [];
|
|
234
239
|
let tailwindPlugin = ()=>{
|
|
235
240
|
return {
|
|
236
241
|
postcssPlugin: "tailwindcss",
|
|
237
242
|
Once (root, { result }) {
|
|
238
|
-
|
|
243
|
+
_sharedState.env.DEBUG && console.time("Compiling CSS");
|
|
239
244
|
(0, _processTailwindFeatures.default)(({ createContext })=>{
|
|
240
245
|
console.error();
|
|
241
246
|
console.error("Rebuilding...");
|
|
@@ -249,7 +254,7 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
249
254
|
});
|
|
250
255
|
};
|
|
251
256
|
})(root, result);
|
|
252
|
-
|
|
257
|
+
_sharedState.env.DEBUG && console.timeEnd("Compiling CSS");
|
|
253
258
|
}
|
|
254
259
|
};
|
|
255
260
|
};
|
|
@@ -286,17 +291,17 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
286
291
|
if (!state.watcher) {
|
|
287
292
|
return result;
|
|
288
293
|
}
|
|
289
|
-
|
|
294
|
+
_sharedState.env.DEBUG && console.time("Recording PostCSS dependencies");
|
|
290
295
|
for (let message of result.messages){
|
|
291
296
|
if (message.type === "dependency") {
|
|
292
297
|
state.contextDependencies.add(message.file);
|
|
293
298
|
}
|
|
294
299
|
}
|
|
295
|
-
|
|
300
|
+
_sharedState.env.DEBUG && console.timeEnd("Recording PostCSS dependencies");
|
|
296
301
|
// TODO: This needs to be in a different spot
|
|
297
|
-
|
|
302
|
+
_sharedState.env.DEBUG && console.time("Watch new files");
|
|
298
303
|
state.watcher.refreshWatchedFiles();
|
|
299
|
-
|
|
304
|
+
_sharedState.env.DEBUG && console.timeEnd("Watch new files");
|
|
300
305
|
return result;
|
|
301
306
|
}).then((result)=>{
|
|
302
307
|
if (!output) {
|
|
@@ -304,13 +309,24 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
304
309
|
return;
|
|
305
310
|
}
|
|
306
311
|
return Promise.all([
|
|
307
|
-
(0, _utils.outputFile)(
|
|
308
|
-
result.map && (0, _utils.outputFile)(
|
|
312
|
+
(0, _utils.outputFile)(result.opts.to, result.css),
|
|
313
|
+
result.map && (0, _utils.outputFile)(result.opts.to + ".map", result.map.toString())
|
|
309
314
|
]);
|
|
310
315
|
}).then(()=>{
|
|
311
316
|
let end = process.hrtime.bigint();
|
|
312
317
|
console.error();
|
|
313
318
|
console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
|
|
319
|
+
}).then(()=>{}, (err)=>{
|
|
320
|
+
// TODO: If an initial build fails we can't easily pick up any PostCSS dependencies
|
|
321
|
+
// that were collected before the error occurred
|
|
322
|
+
// The result is not stored on the error so we have to store it externally
|
|
323
|
+
// and pull the messages off of it here somehow
|
|
324
|
+
// This results in a less than ideal DX because the watcher will not pick up
|
|
325
|
+
// changes to imported CSS if one of them caused an error during the initial build
|
|
326
|
+
// If you fix it and then save the main CSS file so there's no error
|
|
327
|
+
// The watcher will start watching the imported CSS files and will be
|
|
328
|
+
// resilient to future errors.
|
|
329
|
+
console.error(err);
|
|
314
330
|
});
|
|
315
331
|
}
|
|
316
332
|
/**
|
|
@@ -70,12 +70,13 @@ function createWatcher(args, { state , rebuild }) {
|
|
|
70
70
|
*
|
|
71
71
|
* @param {*} file
|
|
72
72
|
* @param {(() => Promise<string>) | null} content
|
|
73
|
+
* @param {boolean} skipPendingCheck
|
|
73
74
|
* @returns {Promise<void>}
|
|
74
|
-
*/ function recordChangedFile(file, content = null) {
|
|
75
|
+
*/ function recordChangedFile(file, content = null, skipPendingCheck = false) {
|
|
75
76
|
file = _path.default.resolve(file);
|
|
76
77
|
// Applications like Vim/Neovim fire both rename and change events in succession for atomic writes
|
|
77
78
|
// In that case rebuild has already been queued by rename, so can be skipped in change
|
|
78
|
-
if (pendingRebuilds.has(file)) {
|
|
79
|
+
if (pendingRebuilds.has(file) && !skipPendingCheck) {
|
|
79
80
|
return Promise.resolve();
|
|
80
81
|
}
|
|
81
82
|
// Mark that a rebuild of this file is going to happen
|
|
@@ -152,8 +153,10 @@ function createWatcher(args, { state , rebuild }) {
|
|
|
152
153
|
return;
|
|
153
154
|
}
|
|
154
155
|
// This will push the rebuild onto the chain
|
|
156
|
+
// We MUST skip the rebuild check here otherwise the rebuild will never happen on Linux
|
|
157
|
+
// This is because the order of events and timing is different on Linux
|
|
155
158
|
// @ts-ignore: TypeScript isn't picking up that content is a string here
|
|
156
|
-
await recordChangedFile(filePath, ()=>content);
|
|
159
|
+
await recordChangedFile(filePath, ()=>content, true);
|
|
157
160
|
} catch {
|
|
158
161
|
// If reading the file fails, it's was probably a deleted temporary file
|
|
159
162
|
// So we can ignore it and no rebuild is needed
|
package/lib/cli/index.js
CHANGED
|
@@ -1,18 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
4
|
value: true
|
|
4
5
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
7
|
+
const _arg = /*#__PURE__*/ _interopRequireDefault(require("arg"));
|
|
8
|
+
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
9
|
+
const _build = require("./build");
|
|
10
|
+
const _help = require("./help");
|
|
11
|
+
const _init = require("./init");
|
|
12
|
+
function _interopRequireDefault(obj) {
|
|
13
|
+
return obj && obj.__esModule ? obj : {
|
|
14
|
+
default: obj
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function isESM() {
|
|
18
|
+
const pkgPath = _path.default.resolve("./package.json");
|
|
19
|
+
try {
|
|
20
|
+
let pkg = JSON.parse(_fs.default.readFileSync(pkgPath, "utf8"));
|
|
21
|
+
return pkg.type && pkg.type === "module";
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
let configs = isESM() ? {
|
|
27
|
+
tailwind: "tailwind.config.cjs",
|
|
28
|
+
postcss: "postcss.config.cjs"
|
|
29
|
+
} : {
|
|
30
|
+
tailwind: "tailwind.config.js",
|
|
31
|
+
postcss: "postcss.config.js"
|
|
32
|
+
};
|
|
33
|
+
// ---
|
|
34
|
+
function oneOf(...options) {
|
|
35
|
+
return Object.assign((value = true)=>{
|
|
36
|
+
for (let option of options){
|
|
37
|
+
let parsed = option(value);
|
|
38
|
+
if (parsed === value) {
|
|
39
|
+
return parsed;
|
|
14
40
|
}
|
|
41
|
+
}
|
|
42
|
+
throw new Error("...");
|
|
43
|
+
}, {
|
|
44
|
+
manualParsing: true
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
let commands = {
|
|
48
|
+
init: {
|
|
49
|
+
run: _init.init,
|
|
50
|
+
args: {
|
|
51
|
+
"--full": {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
description: `Initialize a full \`${configs.tailwind}\` file`
|
|
54
|
+
},
|
|
55
|
+
"--postcss": {
|
|
56
|
+
type: Boolean,
|
|
57
|
+
description: `Initialize a \`${configs.postcss}\` file`
|
|
58
|
+
},
|
|
59
|
+
"-f": "--full",
|
|
60
|
+
"-p": "--postcss"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
build: {
|
|
64
|
+
run: _build.build,
|
|
65
|
+
args: {
|
|
66
|
+
"--input": {
|
|
67
|
+
type: String,
|
|
68
|
+
description: "Input file"
|
|
69
|
+
},
|
|
70
|
+
"--output": {
|
|
71
|
+
type: String,
|
|
72
|
+
description: "Output file"
|
|
73
|
+
},
|
|
74
|
+
"--watch": {
|
|
75
|
+
type: oneOf(String, Boolean),
|
|
76
|
+
description: "Watch for changes and rebuild as needed"
|
|
77
|
+
},
|
|
78
|
+
"--poll": {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
description: "Use polling instead of filesystem events when watching"
|
|
81
|
+
},
|
|
82
|
+
"--content": {
|
|
83
|
+
type: String,
|
|
84
|
+
description: "Content paths to use for removing unused classes"
|
|
85
|
+
},
|
|
86
|
+
"--purge": {
|
|
87
|
+
type: String,
|
|
88
|
+
deprecated: true
|
|
89
|
+
},
|
|
90
|
+
"--postcss": {
|
|
91
|
+
type: oneOf(String, Boolean),
|
|
92
|
+
description: "Load custom PostCSS configuration"
|
|
93
|
+
},
|
|
94
|
+
"--minify": {
|
|
95
|
+
type: Boolean,
|
|
96
|
+
description: "Minify the output"
|
|
97
|
+
},
|
|
98
|
+
"--config": {
|
|
99
|
+
type: String,
|
|
100
|
+
description: "Path to a custom config file"
|
|
101
|
+
},
|
|
102
|
+
"--no-autoprefixer": {
|
|
103
|
+
type: Boolean,
|
|
104
|
+
description: "Disable autoprefixer"
|
|
105
|
+
},
|
|
106
|
+
"-c": "--config",
|
|
107
|
+
"-i": "--input",
|
|
108
|
+
"-o": "--output",
|
|
109
|
+
"-m": "--minify",
|
|
110
|
+
"-w": "--watch",
|
|
111
|
+
"-p": "--poll"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
let sharedFlags = {
|
|
116
|
+
"--help": {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
description: "Display usage information"
|
|
119
|
+
},
|
|
120
|
+
"-h": "--help"
|
|
121
|
+
};
|
|
122
|
+
if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.argv[2] === undefined || process.argv.slice(2).every((flag)=>sharedFlags[flag] !== undefined))) {
|
|
123
|
+
(0, _help.help)({
|
|
124
|
+
usage: [
|
|
125
|
+
"tailwindcss [--input input.css] [--output output.css] [--watch] [options...]",
|
|
126
|
+
"tailwindcss init [--full] [--postcss] [options...]"
|
|
127
|
+
],
|
|
128
|
+
commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
|
|
129
|
+
options: {
|
|
130
|
+
...commands.build.args,
|
|
131
|
+
...sharedFlags
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
let command = ((arg = "")=>arg.startsWith("-") ? undefined : arg)(process.argv[2]) || "build";
|
|
137
|
+
if (commands[command] === undefined) {
|
|
138
|
+
if (_fs.default.existsSync(_path.default.resolve(command))) {
|
|
139
|
+
// TODO: Deprecate this in future versions
|
|
140
|
+
// Check if non-existing command, might be a file.
|
|
141
|
+
command = "build";
|
|
142
|
+
} else {
|
|
143
|
+
(0, _help.help)({
|
|
144
|
+
message: `Invalid command: ${command}`,
|
|
145
|
+
usage: [
|
|
146
|
+
"tailwindcss <command> [options]"
|
|
147
|
+
],
|
|
148
|
+
commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
|
|
149
|
+
options: sharedFlags
|
|
150
|
+
});
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Execute command
|
|
155
|
+
let { args: flags , run } = commands[command];
|
|
156
|
+
let args = (()=>{
|
|
157
|
+
try {
|
|
158
|
+
let result = (0, _arg.default)(Object.fromEntries(Object.entries({
|
|
159
|
+
...flags,
|
|
160
|
+
...sharedFlags
|
|
161
|
+
}).filter(([_key, value])=>{
|
|
162
|
+
var _value_type;
|
|
163
|
+
return !(value === null || value === void 0 ? void 0 : (_value_type = value.type) === null || _value_type === void 0 ? void 0 : _value_type.manualParsing);
|
|
164
|
+
}).map(([key, value])=>[
|
|
165
|
+
key,
|
|
166
|
+
typeof value === "object" ? value.type : value
|
|
167
|
+
])), {
|
|
168
|
+
permissive: true
|
|
15
169
|
});
|
|
170
|
+
// Manual parsing of flags to allow for special flags like oneOf(Boolean, String)
|
|
171
|
+
for(let i = result["_"].length - 1; i >= 0; --i){
|
|
172
|
+
let flag = result["_"][i];
|
|
173
|
+
if (!flag.startsWith("-")) continue;
|
|
174
|
+
let [flagName, flagValue] = flag.split("=");
|
|
175
|
+
let handler = flags[flagName];
|
|
176
|
+
// Resolve flagName & handler
|
|
177
|
+
while(typeof handler === "string"){
|
|
178
|
+
flagName = handler;
|
|
179
|
+
handler = flags[handler];
|
|
180
|
+
}
|
|
181
|
+
if (!handler) continue;
|
|
182
|
+
let args = [];
|
|
183
|
+
let offset = i + 1;
|
|
184
|
+
// --flag value syntax was used so we need to pull `value` from `args`
|
|
185
|
+
if (flagValue === undefined) {
|
|
186
|
+
// Parse args for current flag
|
|
187
|
+
while(result["_"][offset] && !result["_"][offset].startsWith("-")){
|
|
188
|
+
args.push(result["_"][offset++]);
|
|
189
|
+
}
|
|
190
|
+
// Cleanup manually parsed flags + args
|
|
191
|
+
result["_"].splice(i, 1 + args.length);
|
|
192
|
+
// No args were provided, use default value defined in handler
|
|
193
|
+
// One arg was provided, use that directly
|
|
194
|
+
// Multiple args were provided so pass them all in an array
|
|
195
|
+
flagValue = args.length === 0 ? undefined : args.length === 1 ? args[0] : args;
|
|
196
|
+
} else {
|
|
197
|
+
// Remove the whole flag from the args array
|
|
198
|
+
result["_"].splice(i, 1);
|
|
199
|
+
}
|
|
200
|
+
// Set the resolved value in the `result` object
|
|
201
|
+
result[flagName] = handler.type(flagValue, flagName);
|
|
202
|
+
}
|
|
203
|
+
// Ensure that the `command` is always the first argument in the `args`.
|
|
204
|
+
// This is important so that we don't have to check if a default command
|
|
205
|
+
// (build) was used or not from within each plugin.
|
|
206
|
+
//
|
|
207
|
+
// E.g.: tailwindcss input.css -> _: ['build', 'input.css']
|
|
208
|
+
// E.g.: tailwindcss build input.css -> _: ['build', 'input.css']
|
|
209
|
+
if (result["_"][0] !== command) {
|
|
210
|
+
result["_"].unshift(command);
|
|
211
|
+
}
|
|
212
|
+
return result;
|
|
213
|
+
} catch (err) {
|
|
214
|
+
if (err.code === "ARG_UNKNOWN_OPTION") {
|
|
215
|
+
(0, _help.help)({
|
|
216
|
+
message: err.message,
|
|
217
|
+
usage: [
|
|
218
|
+
"tailwindcss <command> [options]"
|
|
219
|
+
],
|
|
220
|
+
options: sharedFlags
|
|
221
|
+
});
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
})();
|
|
227
|
+
if (args["--help"]) {
|
|
228
|
+
(0, _help.help)({
|
|
229
|
+
options: {
|
|
230
|
+
...flags,
|
|
231
|
+
...sharedFlags
|
|
232
|
+
},
|
|
233
|
+
usage: [
|
|
234
|
+
`tailwindcss ${command} [options]`
|
|
235
|
+
]
|
|
16
236
|
});
|
|
17
|
-
|
|
237
|
+
process.exit(0);
|
|
18
238
|
}
|
|
239
|
+
run(args, configs);
|
package/lib/cli/init/index.js
CHANGED
|
@@ -16,8 +16,8 @@ function _interopRequireDefault(obj) {
|
|
|
16
16
|
}
|
|
17
17
|
function init(args, configs) {
|
|
18
18
|
let messages = [];
|
|
19
|
-
var
|
|
20
|
-
let tailwindConfigLocation = _path.default.resolve((
|
|
19
|
+
var _args___;
|
|
20
|
+
let tailwindConfigLocation = _path.default.resolve((_args___ = args["_"][1]) !== null && _args___ !== void 0 ? _args___ : `./${configs.tailwind}`);
|
|
21
21
|
if (_fs.default.existsSync(tailwindConfigLocation)) {
|
|
22
22
|
messages.push(`${_path.default.basename(tailwindConfigLocation)} already exists.`);
|
|
23
23
|
} else {
|