tailwindcss 0.0.0-insiders.b7d5a2f → 0.0.0-insiders.b88c8c4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/lib/cli/build/index.js +12 -4
- package/lib/cli/build/plugin.js +110 -51
- package/lib/cli/build/watching.js +80 -13
- package/lib/cli/index.js +222 -10
- package/lib/cli/init/index.js +22 -7
- package/lib/cli.js +4 -226
- package/lib/corePluginList.js +4 -0
- package/lib/corePlugins.js +337 -69
- package/lib/css/preflight.css +4 -0
- package/lib/featureFlags.js +16 -9
- 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 +21 -11
- 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 +38 -18
- package/lib/lib/expandTailwindAtRules.js +35 -10
- package/lib/lib/findAtConfigPath.js +7 -7
- package/lib/lib/generateRules.js +141 -69
- package/lib/lib/getModuleDependencies.js +79 -33
- package/lib/lib/load-config.js +36 -0
- 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 +277 -77
- package/lib/lib/setupTrackingContext.js +29 -8
- package/lib/lib/sharedState.js +21 -1
- package/lib/oxide/cli/build/deps.js +81 -0
- package/lib/oxide/cli/build/index.js +51 -0
- package/lib/oxide/cli/build/plugin.js +373 -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 +214 -0
- package/lib/oxide/cli/init/index.js +50 -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/public/colors.js +44 -22
- package/lib/public/default-config.js +2 -2
- package/lib/public/default-theme.js +2 -2
- package/lib/public/load-config.js +10 -0
- package/lib/util/applyImportantSelector.js +22 -0
- 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 +29 -2
- package/lib/util/defaults.js +4 -4
- package/lib/util/escapeClassName.js +3 -3
- package/lib/util/formatVariantSelector.js +162 -106
- package/lib/util/getAllConfigs.js +4 -4
- package/lib/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +2 -2
- package/lib/util/negateValue.js +2 -2
- package/lib/util/normalizeConfig.js +49 -22
- package/lib/util/pluginUtils.js +58 -58
- package/lib/util/prefixSelector.js +22 -8
- package/lib/util/resolveConfig.js +11 -16
- package/lib/util/resolveConfigPath.js +19 -7
- package/lib/util/splitAtTopLevelOnly.js +7 -1
- package/loadConfig.d.ts +4 -0
- package/loadConfig.js +2 -0
- package/package.json +38 -26
- package/peers/index.js +757 -753
- package/resolveConfig.d.ts +11 -2
- package/scripts/release-channel.js +18 -0
- package/scripts/release-notes.js +21 -0
- package/scripts/swap-engines.js +40 -0
- package/src/cli/build/index.js +13 -9
- package/src/cli/build/plugin.js +108 -36
- package/src/cli/build/watching.js +108 -13
- package/src/cli/index.js +216 -3
- package/src/cli/init/index.js +37 -8
- package/src/cli.js +4 -220
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +229 -51
- package/src/css/preflight.css +4 -0
- package/src/featureFlags.js +7 -0
- package/src/index.js +4 -46
- package/src/lib/content.js +19 -16
- package/src/lib/defaultExtractor.js +9 -3
- package/src/lib/detectNesting.js +9 -1
- package/src/lib/expandApplyAtRules.js +37 -16
- package/src/lib/expandTailwindAtRules.js +35 -6
- package/src/lib/findAtConfigPath.js +4 -6
- package/src/lib/generateRules.js +144 -46
- package/src/lib/getModuleDependencies.js +70 -30
- package/src/lib/load-config.ts +27 -0
- package/src/lib/offsets.js +104 -1
- package/src/lib/remap-bitfield.js +82 -0
- package/src/lib/setupContextUtils.js +287 -75
- package/src/lib/setupTrackingContext.js +35 -10
- package/src/lib/sharedState.js +19 -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 +442 -0
- package/src/oxide/cli/build/utils.ts +74 -0
- package/src/oxide/cli/build/watching.ts +225 -0
- package/src/oxide/cli/help/index.ts +69 -0
- package/src/oxide/cli/index.ts +204 -0
- package/src/oxide/cli/init/index.ts +59 -0
- package/src/oxide/cli.ts +1 -0
- package/src/oxide/postcss-plugin.ts +1 -0
- package/src/plugin.js +107 -0
- package/src/public/colors.js +22 -0
- package/src/public/default-config.js +1 -1
- package/src/public/default-theme.js +2 -2
- package/src/public/load-config.js +2 -0
- package/src/util/applyImportantSelector.js +19 -0
- package/src/util/color.js +17 -2
- package/src/util/dataTypes.js +33 -4
- package/src/util/formatVariantSelector.js +218 -125
- package/src/util/getAllConfigs.js +2 -2
- package/src/util/{isValidArbitraryValue.js → isSyntacticallyValidPropertyValue.js} +1 -1
- package/src/util/negateValue.js +1 -1
- package/src/util/normalizeConfig.js +37 -1
- package/src/util/pluginUtils.js +54 -39
- package/src/util/prefixSelector.js +28 -10
- package/src/util/resolveConfig.js +3 -9
- package/src/util/resolveConfigPath.js +12 -1
- package/src/util/splitAtTopLevelOnly.js +8 -1
- package/stubs/.gitignore +1 -0
- package/stubs/.prettierrc.json +6 -0
- package/stubs/{defaultConfig.stub.js → config.full.js} +185 -165
- package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -1
- package/stubs/postcss.config.js +6 -0
- package/stubs/tailwind.config.cjs +2 -0
- package/stubs/tailwind.config.js +2 -0
- package/stubs/tailwind.config.ts +3 -0
- package/types/config.d.ts +15 -3
- package/types/generated/colors.d.ts +22 -0
- package/types/generated/corePluginList.d.ts +1 -1
- package/types/generated/default-theme.d.ts +108 -79
- package/CHANGELOG.md +0 -2279
- package/lib/cli/shared.js +0 -12
- package/lib/constants.js +0 -44
- package/scripts/calculate-tag-name.js +0 -8
- package/scripts/install-integrations.js +0 -27
- package/scripts/rebuildFixtures.js +0 -68
- package/src/cli/shared.js +0 -5
- package/src/constants.js +0 -17
- /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://tailwindcss.com
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<a href="https://tailwindcss.com" target="_blank">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-dark.svg">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg">
|
|
6
|
+
<img alt="Tailwind CSS" src="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg" width="350" height="70" style="max-width: 100%;">
|
|
7
|
+
</picture>
|
|
7
8
|
</a>
|
|
8
9
|
</p>
|
|
9
10
|
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
<p align="center">
|
|
16
|
-
<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>
|
|
17
18
|
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
|
|
18
19
|
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
|
|
19
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
|
@@ -9,13 +9,14 @@ Object.defineProperty(exports, "build", {
|
|
|
9
9
|
});
|
|
10
10
|
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
11
11
|
const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
12
|
+
const _resolveConfigPathJs = require("../../util/resolveConfigPath.js");
|
|
12
13
|
const _pluginJs = require("./plugin.js");
|
|
13
14
|
function _interopRequireDefault(obj) {
|
|
14
15
|
return obj && obj.__esModule ? obj : {
|
|
15
16
|
default: obj
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
|
-
async function build(args
|
|
19
|
+
async function build(args) {
|
|
19
20
|
let input = args["--input"];
|
|
20
21
|
let shouldWatch = args["--watch"];
|
|
21
22
|
// TODO: Deprecate this in future versions
|
|
@@ -32,13 +33,20 @@ async function build(args, configs) {
|
|
|
32
33
|
process.exit(9);
|
|
33
34
|
}
|
|
34
35
|
// TODO: Reference the @config path here if exists
|
|
35
|
-
let configPath = args["--config"] ? args["--config"] : (
|
|
36
|
+
let configPath = args["--config"] ? args["--config"] : (0, _resolveConfigPathJs.resolveDefaultConfigPath)();
|
|
36
37
|
let processor = await (0, _pluginJs.createProcessor)(args, configPath);
|
|
37
38
|
if (shouldWatch) {
|
|
38
|
-
|
|
39
|
+
// Abort the watcher if stdin is closed to avoid zombie processes
|
|
40
|
+
// You can disable this behavior with --watch=always
|
|
41
|
+
if (args["--watch"] !== "always") {
|
|
42
|
+
process.stdin.on("end", ()=>process.exit(0));
|
|
43
|
+
}
|
|
39
44
|
process.stdin.resume();
|
|
40
45
|
await processor.watch();
|
|
41
46
|
} else {
|
|
42
|
-
await processor.build()
|
|
47
|
+
await processor.build().catch((e)=>{
|
|
48
|
+
console.error(e);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
43
51
|
}
|
|
44
52
|
}
|
package/lib/cli/build/plugin.js
CHANGED
|
@@ -18,13 +18,15 @@ 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
|
-
const _getModuleDependenciesJs = /*#__PURE__*/ _interopRequireDefault(require("../../lib/getModuleDependencies.js"));
|
|
24
23
|
const _contentJs = require("../../lib/content.js");
|
|
25
24
|
const _watchingJs = require("./watching.js");
|
|
26
25
|
const _fastGlob = /*#__PURE__*/ _interopRequireDefault(require("fast-glob"));
|
|
27
26
|
const _findAtConfigPathJs = require("../../lib/findAtConfigPath.js");
|
|
27
|
+
const _log = /*#__PURE__*/ _interopRequireDefault(require("../../util/log"));
|
|
28
|
+
const _loadConfig = require("../../lib/load-config");
|
|
29
|
+
const _getModuleDependencies = /*#__PURE__*/ _interopRequireDefault(require("../../lib/getModuleDependencies"));
|
|
28
30
|
function _interopRequireDefault(obj) {
|
|
29
31
|
return obj && obj.__esModule ? obj : {
|
|
30
32
|
default: obj
|
|
@@ -108,12 +110,12 @@ let state = {
|
|
|
108
110
|
/** @type {any} */ context: null,
|
|
109
111
|
/** @type {ReturnType<typeof createWatcher> | null} */ watcher: null,
|
|
110
112
|
/** @type {{content: string, extension: string}[]} */ changedContent: [],
|
|
111
|
-
|
|
113
|
+
/** @type {ReturnType<typeof load> | null} */ configBag: null,
|
|
112
114
|
contextDependencies: new Set(),
|
|
113
115
|
/** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [],
|
|
114
116
|
refreshContentPaths () {
|
|
115
|
-
var
|
|
116
|
-
this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (
|
|
117
|
+
var _this_context;
|
|
118
|
+
this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig);
|
|
117
119
|
},
|
|
118
120
|
get config () {
|
|
119
121
|
return this.context.tailwindConfig;
|
|
@@ -124,31 +126,38 @@ let state = {
|
|
|
124
126
|
dynamic: this.contentPaths.filter((contentPath)=>contentPath.glob !== undefined).map((contentPath)=>contentPath.pattern)
|
|
125
127
|
};
|
|
126
128
|
},
|
|
127
|
-
loadConfig (configPath) {
|
|
129
|
+
loadConfig (configPath, content) {
|
|
128
130
|
if (this.watcher && configPath) {
|
|
129
|
-
this.refreshConfigDependencies(
|
|
131
|
+
this.refreshConfigDependencies();
|
|
130
132
|
}
|
|
131
|
-
let config =
|
|
133
|
+
let config = (0, _loadConfig.loadConfig)(configPath);
|
|
134
|
+
let dependencies = (0, _getModuleDependencies.default)(configPath);
|
|
135
|
+
this.configBag = {
|
|
136
|
+
config,
|
|
137
|
+
dependencies,
|
|
138
|
+
dispose () {
|
|
139
|
+
for (let file of dependencies){
|
|
140
|
+
delete require.cache[require.resolve(file)];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
132
144
|
// @ts-ignore
|
|
133
|
-
config = (0, _resolveConfigJs.default)(config, {
|
|
145
|
+
this.configBag.config = (0, _resolveConfigJs.default)(this.configBag.config, {
|
|
134
146
|
content: {
|
|
135
147
|
files: []
|
|
136
148
|
}
|
|
137
149
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
_shared.env.DEBUG && console.time("Module dependencies");
|
|
142
|
-
for (let file of this.configDependencies){
|
|
143
|
-
delete require.cache[require.resolve(file)];
|
|
144
|
-
}
|
|
145
|
-
if (configPath) {
|
|
146
|
-
let deps = (0, _getModuleDependenciesJs.default)(configPath).map(({ file })=>file);
|
|
147
|
-
for (let dependency of deps){
|
|
148
|
-
this.configDependencies.add(dependency);
|
|
149
|
-
}
|
|
150
|
+
// Override content files if `--content` has been passed explicitly
|
|
151
|
+
if ((content === null || content === void 0 ? void 0 : content.length) > 0) {
|
|
152
|
+
this.configBag.config.content.files = content;
|
|
150
153
|
}
|
|
151
|
-
|
|
154
|
+
return this.configBag.config;
|
|
155
|
+
},
|
|
156
|
+
refreshConfigDependencies () {
|
|
157
|
+
var _this_configBag;
|
|
158
|
+
_sharedState.env.DEBUG && console.time("Module dependencies");
|
|
159
|
+
(_this_configBag = this.configBag) === null || _this_configBag === void 0 ? void 0 : _this_configBag.dispose();
|
|
160
|
+
_sharedState.env.DEBUG && console.timeEnd("Module dependencies");
|
|
152
161
|
},
|
|
153
162
|
readContentPaths () {
|
|
154
163
|
let content = [];
|
|
@@ -156,69 +165,86 @@ let state = {
|
|
|
156
165
|
// TODO: When we make the postcss plugin async-capable this can become async
|
|
157
166
|
let files = _fastGlob.default.sync(this.contentPatterns.all);
|
|
158
167
|
for (let file of files){
|
|
159
|
-
|
|
160
|
-
content
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
if (_sharedState.env.OXIDE) {
|
|
169
|
+
content.push({
|
|
170
|
+
file,
|
|
171
|
+
extension: _path.default.extname(file).slice(1)
|
|
172
|
+
});
|
|
173
|
+
} else {
|
|
174
|
+
content.push({
|
|
175
|
+
content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
|
|
176
|
+
extension: _path.default.extname(file).slice(1)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
163
179
|
}
|
|
164
180
|
// Resolve raw content in the tailwind config
|
|
165
181
|
let rawContent = this.config.content.files.filter((file)=>{
|
|
166
182
|
return file !== null && typeof file === "object";
|
|
167
183
|
});
|
|
168
|
-
for (let { raw:
|
|
169
|
-
|
|
170
|
-
content:
|
|
184
|
+
for (let { raw: htmlContent , extension ="html" } of rawContent){
|
|
185
|
+
content.push({
|
|
186
|
+
content: htmlContent,
|
|
171
187
|
extension
|
|
172
188
|
});
|
|
173
189
|
}
|
|
174
190
|
return content;
|
|
175
191
|
},
|
|
176
|
-
getContext ({ createContext , cliConfigPath , root , result }) {
|
|
192
|
+
getContext ({ createContext , cliConfigPath , root , result , content }) {
|
|
177
193
|
if (this.context) {
|
|
178
194
|
this.context.changedContent = this.changedContent.splice(0);
|
|
179
195
|
return this.context;
|
|
180
196
|
}
|
|
181
|
-
|
|
182
|
-
var
|
|
183
|
-
let configPath = (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
let config = this.loadConfig(configPath);
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
_sharedState.env.DEBUG && console.time("Searching for config");
|
|
198
|
+
var _findAtConfigPath;
|
|
199
|
+
let configPath = (_findAtConfigPath = (0, _findAtConfigPathJs.findAtConfigPath)(root, result)) !== null && _findAtConfigPath !== void 0 ? _findAtConfigPath : cliConfigPath;
|
|
200
|
+
_sharedState.env.DEBUG && console.timeEnd("Searching for config");
|
|
201
|
+
_sharedState.env.DEBUG && console.time("Loading config");
|
|
202
|
+
let config = this.loadConfig(configPath, content);
|
|
203
|
+
_sharedState.env.DEBUG && console.timeEnd("Loading config");
|
|
204
|
+
_sharedState.env.DEBUG && console.time("Creating context");
|
|
189
205
|
this.context = createContext(config, []);
|
|
190
206
|
Object.assign(this.context, {
|
|
191
207
|
userConfigPath: configPath
|
|
192
208
|
});
|
|
193
|
-
|
|
194
|
-
|
|
209
|
+
_sharedState.env.DEBUG && console.timeEnd("Creating context");
|
|
210
|
+
_sharedState.env.DEBUG && console.time("Resolving content paths");
|
|
195
211
|
this.refreshContentPaths();
|
|
196
|
-
|
|
212
|
+
_sharedState.env.DEBUG && console.timeEnd("Resolving content paths");
|
|
197
213
|
if (this.watcher) {
|
|
198
|
-
|
|
214
|
+
_sharedState.env.DEBUG && console.time("Watch new files");
|
|
199
215
|
this.watcher.refreshWatchedFiles();
|
|
200
|
-
|
|
216
|
+
_sharedState.env.DEBUG && console.timeEnd("Watch new files");
|
|
201
217
|
}
|
|
202
|
-
_shared.env.DEBUG && console.time("Reading content files");
|
|
203
218
|
for (let file of this.readContentPaths()){
|
|
204
219
|
this.context.changedContent.push(file);
|
|
205
220
|
}
|
|
206
|
-
_shared.env.DEBUG && console.timeEnd("Reading content files");
|
|
207
221
|
return this.context;
|
|
208
222
|
}
|
|
209
223
|
};
|
|
210
224
|
async function createProcessor(args, cliConfigPath) {
|
|
225
|
+
var _args_content;
|
|
211
226
|
let postcss = (0, _deps.loadPostcss)();
|
|
212
227
|
let input = args["--input"];
|
|
213
228
|
let output = args["--output"];
|
|
214
229
|
let includePostCss = args["--postcss"];
|
|
215
230
|
let customPostCssPath = typeof args["--postcss"] === "string" ? args["--postcss"] : undefined;
|
|
216
231
|
let [beforePlugins, afterPlugins, postcssOptions] = includePostCss ? await loadPostCssPlugins(customPostCssPath) : loadBuiltinPostcssPlugins();
|
|
232
|
+
if (args["--purge"]) {
|
|
233
|
+
_log.default.warn("purge-flag-deprecated", [
|
|
234
|
+
"The `--purge` flag has been deprecated.",
|
|
235
|
+
"Please use `--content` instead."
|
|
236
|
+
]);
|
|
237
|
+
if (!args["--content"]) {
|
|
238
|
+
args["--content"] = args["--purge"];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
var _args_content_split;
|
|
242
|
+
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 : [];
|
|
217
243
|
let tailwindPlugin = ()=>{
|
|
218
244
|
return {
|
|
219
245
|
postcssPlugin: "tailwindcss",
|
|
220
246
|
Once (root, { result }) {
|
|
221
|
-
|
|
247
|
+
_sharedState.env.DEBUG && console.time("Compiling CSS");
|
|
222
248
|
(0, _processTailwindFeatures.default)(({ createContext })=>{
|
|
223
249
|
console.error();
|
|
224
250
|
console.error("Rebuilding...");
|
|
@@ -227,11 +253,12 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
227
253
|
createContext,
|
|
228
254
|
cliConfigPath,
|
|
229
255
|
root,
|
|
230
|
-
result
|
|
256
|
+
result,
|
|
257
|
+
content
|
|
231
258
|
});
|
|
232
259
|
};
|
|
233
260
|
})(root, result);
|
|
234
|
-
|
|
261
|
+
_sharedState.env.DEBUG && console.timeEnd("Compiling CSS");
|
|
235
262
|
}
|
|
236
263
|
};
|
|
237
264
|
};
|
|
@@ -265,18 +292,49 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
265
292
|
from: input,
|
|
266
293
|
to: output
|
|
267
294
|
})).then((result)=>{
|
|
295
|
+
if (!state.watcher) {
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
_sharedState.env.DEBUG && console.time("Recording PostCSS dependencies");
|
|
299
|
+
for (let message of result.messages){
|
|
300
|
+
if (message.type === "dependency") {
|
|
301
|
+
state.contextDependencies.add(message.file);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
_sharedState.env.DEBUG && console.timeEnd("Recording PostCSS dependencies");
|
|
305
|
+
// TODO: This needs to be in a different spot
|
|
306
|
+
_sharedState.env.DEBUG && console.time("Watch new files");
|
|
307
|
+
state.watcher.refreshWatchedFiles();
|
|
308
|
+
_sharedState.env.DEBUG && console.timeEnd("Watch new files");
|
|
309
|
+
return result;
|
|
310
|
+
}).then((result)=>{
|
|
268
311
|
if (!output) {
|
|
269
312
|
process.stdout.write(result.css);
|
|
270
313
|
return;
|
|
271
314
|
}
|
|
272
315
|
return Promise.all([
|
|
273
|
-
(0, _utils.outputFile)(
|
|
274
|
-
result.map && (0, _utils.outputFile)(
|
|
316
|
+
(0, _utils.outputFile)(result.opts.to, result.css),
|
|
317
|
+
result.map && (0, _utils.outputFile)(result.opts.to + ".map", result.map.toString())
|
|
275
318
|
]);
|
|
276
319
|
}).then(()=>{
|
|
277
320
|
let end = process.hrtime.bigint();
|
|
278
321
|
console.error();
|
|
279
322
|
console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
|
|
323
|
+
}).then(()=>{}, (err)=>{
|
|
324
|
+
// TODO: If an initial build fails we can't easily pick up any PostCSS dependencies
|
|
325
|
+
// that were collected before the error occurred
|
|
326
|
+
// The result is not stored on the error so we have to store it externally
|
|
327
|
+
// and pull the messages off of it here somehow
|
|
328
|
+
// This results in a less than ideal DX because the watcher will not pick up
|
|
329
|
+
// changes to imported CSS if one of them caused an error during the initial build
|
|
330
|
+
// If you fix it and then save the main CSS file so there's no error
|
|
331
|
+
// The watcher will start watching the imported CSS files and will be
|
|
332
|
+
// resilient to future errors.
|
|
333
|
+
if (state.watcher) {
|
|
334
|
+
console.error(err);
|
|
335
|
+
} else {
|
|
336
|
+
return Promise.reject(err);
|
|
337
|
+
}
|
|
280
338
|
});
|
|
281
339
|
}
|
|
282
340
|
/**
|
|
@@ -299,7 +357,8 @@ async function createProcessor(args, cliConfigPath) {
|
|
|
299
357
|
* @param {{file: string, content(): Promise<string>, extension: string}[]} changes
|
|
300
358
|
*/ async rebuild (changes) {
|
|
301
359
|
let needsNewContext = changes.some((change)=>{
|
|
302
|
-
|
|
360
|
+
var _state_configBag;
|
|
361
|
+
return ((_state_configBag = state.configBag) === null || _state_configBag === void 0 ? void 0 : _state_configBag.dependencies.has(change.file)) || state.contextDependencies.has(change.file);
|
|
303
362
|
});
|
|
304
363
|
if (needsNewContext) {
|
|
305
364
|
state.context = null;
|
|
@@ -37,22 +37,72 @@ function createWatcher(args, { state , rebuild }) {
|
|
|
37
37
|
pollInterval: pollInterval
|
|
38
38
|
} : false
|
|
39
39
|
});
|
|
40
|
+
// A queue of rebuilds, file reads, etc… to run
|
|
40
41
|
let chain = Promise.resolve();
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A list of files that have been changed since the last rebuild
|
|
44
|
+
*
|
|
45
|
+
* @type {{file: string, content: () => Promise<string>, extension: string}[]}
|
|
46
|
+
*/ let changedContent = [];
|
|
47
|
+
/**
|
|
48
|
+
* A list of files for which a rebuild has already been queued.
|
|
49
|
+
* This is used to prevent duplicate rebuilds when multiple events are fired for the same file.
|
|
50
|
+
* The rebuilt file is cleared from this list when it's associated rebuild has _started_
|
|
51
|
+
* This is because if the file is changed during a rebuild it won't trigger a new rebuild which it should
|
|
52
|
+
**/ let pendingRebuilds = new Set();
|
|
53
|
+
let _timer;
|
|
54
|
+
let _reject;
|
|
55
|
+
/**
|
|
56
|
+
* Rebuilds the changed files and resolves when the rebuild is
|
|
57
|
+
* complete regardless of whether it was successful or not
|
|
58
|
+
*/ async function rebuildAndContinue() {
|
|
59
|
+
let changes = changedContent.splice(0);
|
|
60
|
+
// There are no changes to rebuild so we can just do nothing
|
|
61
|
+
if (changes.length === 0) {
|
|
62
|
+
return Promise.resolve();
|
|
63
|
+
}
|
|
64
|
+
// Clear all pending rebuilds for the about-to-be-built files
|
|
65
|
+
changes.forEach((change)=>pendingRebuilds.delete(change.file));
|
|
66
|
+
// Resolve the promise even when the rebuild fails
|
|
67
|
+
return rebuild(changes).then(()=>{}, (e)=>{
|
|
68
|
+
console.error(e.toString());
|
|
69
|
+
});
|
|
70
|
+
}
|
|
43
71
|
/**
|
|
44
72
|
*
|
|
45
73
|
* @param {*} file
|
|
46
74
|
* @param {(() => Promise<string>) | null} content
|
|
47
|
-
|
|
75
|
+
* @param {boolean} skipPendingCheck
|
|
76
|
+
* @returns {Promise<void>}
|
|
77
|
+
*/ function recordChangedFile(file, content = null, skipPendingCheck = false) {
|
|
48
78
|
file = _path.default.resolve(file);
|
|
49
|
-
|
|
79
|
+
// Applications like Vim/Neovim fire both rename and change events in succession for atomic writes
|
|
80
|
+
// In that case rebuild has already been queued by rename, so can be skipped in change
|
|
81
|
+
if (pendingRebuilds.has(file) && !skipPendingCheck) {
|
|
82
|
+
return Promise.resolve();
|
|
83
|
+
}
|
|
84
|
+
// Mark that a rebuild of this file is going to happen
|
|
85
|
+
// It MUST happen synchronously before the rebuild is queued for this to be effective
|
|
86
|
+
pendingRebuilds.add(file);
|
|
50
87
|
changedContent.push({
|
|
51
88
|
file,
|
|
52
|
-
content,
|
|
89
|
+
content: content !== null && content !== void 0 ? content : ()=>_fs.default.promises.readFile(file, "utf8"),
|
|
53
90
|
extension: _path.default.extname(file).slice(1)
|
|
54
91
|
});
|
|
55
|
-
|
|
92
|
+
if (_timer) {
|
|
93
|
+
clearTimeout(_timer);
|
|
94
|
+
_reject();
|
|
95
|
+
}
|
|
96
|
+
// If a rebuild is already in progress we don't want to start another one until the 10ms timer has expired
|
|
97
|
+
chain = chain.then(()=>new Promise((resolve, reject)=>{
|
|
98
|
+
_timer = setTimeout(resolve, 10);
|
|
99
|
+
_reject = reject;
|
|
100
|
+
}));
|
|
101
|
+
// Resolves once this file has been rebuilt (or the rebuild for this file has failed)
|
|
102
|
+
// This queues as many rebuilds as there are changed files
|
|
103
|
+
// But those rebuilds happen after some delay
|
|
104
|
+
// And will immediately resolve if there are no changes
|
|
105
|
+
chain = chain.then(rebuildAndContinue, rebuildAndContinue);
|
|
56
106
|
return chain;
|
|
57
107
|
}
|
|
58
108
|
watcher.on("change", (file)=>recordChangedFile(file));
|
|
@@ -91,22 +141,39 @@ function createWatcher(args, { state , rebuild }) {
|
|
|
91
141
|
if (pendingRebuilds.has(filePath)) {
|
|
92
142
|
return;
|
|
93
143
|
}
|
|
144
|
+
// We'll go ahead and add the file to the pending rebuilds list here
|
|
145
|
+
// It'll be removed when the rebuild starts unless the read fails
|
|
146
|
+
// which will be taken care of as well
|
|
94
147
|
pendingRebuilds.add(filePath);
|
|
95
|
-
|
|
96
|
-
let content;
|
|
148
|
+
async function enqueue() {
|
|
97
149
|
try {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
150
|
+
// We need to read the file as early as possible outside of the chain
|
|
151
|
+
// because it may be gone by the time we get to it. doing the read
|
|
152
|
+
// immediately increases the chance that the file is still there
|
|
153
|
+
let content = await (0, _utilsJs.readFileWithRetries)(_path.default.resolve(filePath));
|
|
154
|
+
if (content === undefined) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// This will push the rebuild onto the chain
|
|
158
|
+
// We MUST skip the rebuild check here otherwise the rebuild will never happen on Linux
|
|
159
|
+
// This is because the order of events and timing is different on Linux
|
|
160
|
+
// @ts-ignore: TypeScript isn't picking up that content is a string here
|
|
161
|
+
await recordChangedFile(filePath, ()=>content, true);
|
|
162
|
+
} catch {
|
|
163
|
+
// If reading the file fails, it's was probably a deleted temporary file
|
|
164
|
+
// So we can ignore it and no rebuild is needed
|
|
101
165
|
}
|
|
102
|
-
|
|
166
|
+
}
|
|
167
|
+
enqueue().then(()=>{
|
|
168
|
+
// If the file read fails we still need to make sure the file isn't stuck in the pending rebuilds list
|
|
169
|
+
pendingRebuilds.delete(filePath);
|
|
103
170
|
});
|
|
104
171
|
});
|
|
105
172
|
return {
|
|
106
173
|
fswatcher: watcher,
|
|
107
174
|
refreshWatchedFiles () {
|
|
108
175
|
watcher.add(Array.from(state.contextDependencies));
|
|
109
|
-
watcher.add(Array.from(state.
|
|
176
|
+
watcher.add(Array.from(state.configBag.dependencies));
|
|
110
177
|
watcher.add(state.contentPatterns.all);
|
|
111
178
|
}
|
|
112
179
|
};
|