tailwindcss-patch 9.1.0 → 9.2.1
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/dist/cli.js +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/commands/cli-runtime.js +1 -1
- package/dist/commands/cli-runtime.mjs +1 -1
- package/dist/{index.bundle-C4Y53Ygf.js → index.bundle-BkqJb7rw.js} +11 -4
- package/dist/{index.bundle-0Fe7Jx8V.mjs → index.bundle-Dnh0a6WS.mjs} +11 -4
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{validate-BuhhSYBe.js → validate-Bo-Ua7Kg.js} +64 -17
- package/dist/{validate-4FCU-Ql3.mjs → validate-CceFRP7h.mjs} +64 -17
- package/package.json +2 -2
- package/src/extraction/candidate-extractor.ts +20 -1
- package/src/v4/engine.ts +29 -6
- package/src/v4/node-adapter.ts +71 -11
- package/src/v4/types.ts +7 -0
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-8l464Juk.js");
|
|
2
|
-
const require_validate = require("./validate-
|
|
3
|
-
const require_index_bundle = require("./index.bundle-
|
|
2
|
+
const require_validate = require("./validate-Bo-Ua7Kg.js");
|
|
3
|
+
const require_index_bundle = require("./index.bundle-BkqJb7rw.js");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_chunk.__toESM(node_process);
|
|
6
6
|
//#region src/cli.bundle.ts
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as logger, r as ValidateCommandError } from "./validate-
|
|
2
|
-
import { t as createTailwindcssPatchCli } from "./index.bundle-
|
|
1
|
+
import { k as logger, r as ValidateCommandError } from "./validate-CceFRP7h.mjs";
|
|
2
|
+
import { t as createTailwindcssPatchCli } from "./index.bundle-Dnh0a6WS.mjs";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
//#region src/cli.bundle.ts
|
|
5
5
|
async function main() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../chunk-8l464Juk.js");
|
|
3
|
-
const require_validate = require("../validate-
|
|
3
|
+
const require_validate = require("../validate-Bo-Ua7Kg.js");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_chunk.__toESM(node_process);
|
|
6
6
|
let fs_extra = require("fs-extra");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as loadWorkspaceConfigModule, T as loadPatchOptionsForWorkspace, a as tailwindcssPatchCommands, b as groupTokensByFile, i as classifyValidateError, k as logger, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher } from "../validate-
|
|
1
|
+
import { E as loadWorkspaceConfigModule, T as loadPatchOptionsForWorkspace, a as tailwindcssPatchCommands, b as groupTokensByFile, i as classifyValidateError, k as logger, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher } from "../validate-CceFRP7h.mjs";
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import fs from "fs-extra";
|
|
4
4
|
import path from "pathe";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-8l464Juk.js");
|
|
2
|
-
const require_validate = require("./validate-
|
|
2
|
+
const require_validate = require("./validate-Bo-Ua7Kg.js");
|
|
3
3
|
let node_module = require("node:module");
|
|
4
4
|
let node_process = require("node:process");
|
|
5
5
|
node_process = require_chunk.__toESM(node_process);
|
|
@@ -7,13 +7,20 @@ let pathe = require("pathe");
|
|
|
7
7
|
pathe = require_chunk.__toESM(pathe);
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
//#region src/v4/engine.ts
|
|
10
|
-
|
|
10
|
+
function resolveScanSources(options, compiledSources) {
|
|
11
|
+
if (Array.isArray(options?.scanSources)) return options.scanSources;
|
|
12
|
+
if (options?.scanSources === true) return compiledSources;
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
async function collectRawCandidates(source, options, compiledSources = []) {
|
|
11
16
|
const rawCandidates = /* @__PURE__ */ new Set();
|
|
12
17
|
for (const candidate of options?.candidates ?? []) rawCandidates.add(candidate);
|
|
13
18
|
for (const candidateSource of options?.sources ?? []) {
|
|
14
19
|
const candidates = await require_validate.extractRawCandidatesWithPositions(candidateSource.content, candidateSource.extension);
|
|
15
20
|
for (const candidate of candidates) rawCandidates.add(candidate.rawCandidate);
|
|
16
21
|
}
|
|
22
|
+
const filesystemSources = resolveScanSources(options, compiledSources);
|
|
23
|
+
if (filesystemSources.length > 0) for (const candidate of await require_validate.extractRawCandidates(filesystemSources)) rawCandidates.add(candidate);
|
|
17
24
|
const inlineSources = require_validate.extractTailwindV4InlineSourceCandidates(source.css);
|
|
18
25
|
for (const candidate of inlineSources.included) rawCandidates.add(candidate);
|
|
19
26
|
for (const candidate of inlineSources.excluded) rawCandidates.delete(candidate);
|
|
@@ -29,11 +36,11 @@ function createTailwindV4Engine(source) {
|
|
|
29
36
|
return require_validate.resolveValidTailwindV4Candidates(await require_validate.loadTailwindV4DesignSystem(source), candidates);
|
|
30
37
|
},
|
|
31
38
|
async generate(options) {
|
|
32
|
-
const
|
|
39
|
+
const { compiled, dependencies } = await require_validate.compileTailwindV4Source(source);
|
|
40
|
+
const rawCandidates = await collectRawCandidates(source, options, compiled.sources);
|
|
33
41
|
const classSet = require_validate.resolveValidTailwindV4Candidates(await require_validate.loadTailwindV4DesignSystem(source), rawCandidates);
|
|
34
42
|
const inlineSources = require_validate.extractTailwindV4InlineSourceCandidates(source.css);
|
|
35
43
|
for (const candidate of inlineSources.excluded) classSet.delete(candidate);
|
|
36
|
-
const { compiled, dependencies } = await require_validate.compileTailwindV4Source(source);
|
|
37
44
|
return {
|
|
38
45
|
css: compiled.build(Array.from(classSet)),
|
|
39
46
|
classSet,
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import { C as extractTailwindV4InlineSourceCandidates, D as normalizeOptions, S as loadTailwindV4DesignSystem, v as extractRawCandidatesWithPositions, w as resolveValidTailwindV4Candidates, x as compileTailwindV4Source } from "./validate-
|
|
1
|
+
import { C as extractTailwindV4InlineSourceCandidates, D as normalizeOptions, S as loadTailwindV4DesignSystem, _ as extractRawCandidates, v as extractRawCandidatesWithPositions, w as resolveValidTailwindV4Candidates, x as compileTailwindV4Source } from "./validate-CceFRP7h.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import path from "pathe";
|
|
5
5
|
import { promises } from "node:fs";
|
|
6
6
|
//#region src/v4/engine.ts
|
|
7
|
-
|
|
7
|
+
function resolveScanSources(options, compiledSources) {
|
|
8
|
+
if (Array.isArray(options?.scanSources)) return options.scanSources;
|
|
9
|
+
if (options?.scanSources === true) return compiledSources;
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
async function collectRawCandidates(source, options, compiledSources = []) {
|
|
8
13
|
const rawCandidates = /* @__PURE__ */ new Set();
|
|
9
14
|
for (const candidate of options?.candidates ?? []) rawCandidates.add(candidate);
|
|
10
15
|
for (const candidateSource of options?.sources ?? []) {
|
|
11
16
|
const candidates = await extractRawCandidatesWithPositions(candidateSource.content, candidateSource.extension);
|
|
12
17
|
for (const candidate of candidates) rawCandidates.add(candidate.rawCandidate);
|
|
13
18
|
}
|
|
19
|
+
const filesystemSources = resolveScanSources(options, compiledSources);
|
|
20
|
+
if (filesystemSources.length > 0) for (const candidate of await extractRawCandidates(filesystemSources)) rawCandidates.add(candidate);
|
|
14
21
|
const inlineSources = extractTailwindV4InlineSourceCandidates(source.css);
|
|
15
22
|
for (const candidate of inlineSources.included) rawCandidates.add(candidate);
|
|
16
23
|
for (const candidate of inlineSources.excluded) rawCandidates.delete(candidate);
|
|
@@ -26,11 +33,11 @@ function createTailwindV4Engine(source) {
|
|
|
26
33
|
return resolveValidTailwindV4Candidates(await loadTailwindV4DesignSystem(source), candidates);
|
|
27
34
|
},
|
|
28
35
|
async generate(options) {
|
|
29
|
-
const
|
|
36
|
+
const { compiled, dependencies } = await compileTailwindV4Source(source);
|
|
37
|
+
const rawCandidates = await collectRawCandidates(source, options, compiled.sources);
|
|
30
38
|
const classSet = resolveValidTailwindV4Candidates(await loadTailwindV4DesignSystem(source), rawCandidates);
|
|
31
39
|
const inlineSources = extractTailwindV4InlineSourceCandidates(source.css);
|
|
32
40
|
for (const candidate of inlineSources.excluded) classSet.delete(candidate);
|
|
33
|
-
const { compiled, dependencies } = await compileTailwindV4Source(source);
|
|
34
41
|
return {
|
|
35
42
|
css: compiled.build(Array.from(classSet)),
|
|
36
43
|
classSet,
|
package/dist/index.d.mts
CHANGED
|
@@ -101,6 +101,13 @@ interface TailwindV4CandidateSource {
|
|
|
101
101
|
interface TailwindV4GenerateOptions {
|
|
102
102
|
candidates?: Iterable<string>;
|
|
103
103
|
sources?: TailwindV4CandidateSource[];
|
|
104
|
+
/**
|
|
105
|
+
* 扫描文件系统 source entries 中的候选类名。
|
|
106
|
+
*
|
|
107
|
+
* - `true`:使用 Tailwind v4 编译入口解析出的 `@source` 列表。
|
|
108
|
+
* - `TailwindV4SourcePattern[]`:使用调用方显式传入的 source 列表。
|
|
109
|
+
*/
|
|
110
|
+
scanSources?: boolean | TailwindV4SourcePattern[];
|
|
104
111
|
}
|
|
105
112
|
interface TailwindV4SourcePattern {
|
|
106
113
|
base: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,13 @@ interface TailwindV4CandidateSource {
|
|
|
101
101
|
interface TailwindV4GenerateOptions {
|
|
102
102
|
candidates?: Iterable<string>;
|
|
103
103
|
sources?: TailwindV4CandidateSource[];
|
|
104
|
+
/**
|
|
105
|
+
* 扫描文件系统 source entries 中的候选类名。
|
|
106
|
+
*
|
|
107
|
+
* - `true`:使用 Tailwind v4 编译入口解析出的 `@source` 列表。
|
|
108
|
+
* - `TailwindV4SourcePattern[]`:使用调用方显式传入的 source 列表。
|
|
109
|
+
*/
|
|
110
|
+
scanSources?: boolean | TailwindV4SourcePattern[];
|
|
104
111
|
}
|
|
105
112
|
interface TailwindV4SourcePattern {
|
|
106
113
|
base: string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_validate = require("./validate-
|
|
3
|
-
const require_index_bundle = require("./index.bundle-
|
|
2
|
+
const require_validate = require("./validate-Bo-Ua7Kg.js");
|
|
3
|
+
const require_index_bundle = require("./index.bundle-BkqJb7rw.js");
|
|
4
4
|
exports.CacheStore = require_validate.CacheStore;
|
|
5
5
|
exports.MIGRATION_REPORT_KIND = require_validate.MIGRATION_REPORT_KIND;
|
|
6
6
|
exports.MIGRATION_REPORT_SCHEMA_VERSION = require_validate.MIGRATION_REPORT_SCHEMA_VERSION;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { D as normalizeOptions, O as CacheStore, S as loadTailwindV4DesignSystem, _ as extractRawCandidates, a as tailwindcssPatchCommands, b as groupTokensByFile, c as MIGRATION_REPORT_KIND, d as getPatchStatusReport, f as runTailwindBuild, g as extractProjectCandidatesWithPositions, h as collectClassesFromTailwindV4, k as logger, l as MIGRATION_REPORT_SCHEMA_VERSION, m as collectClassesFromContexts, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, p as loadRuntimeContexts, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher, v as extractRawCandidatesWithPositions, w as resolveValidTailwindV4Candidates, y as extractValidCandidates } from "./validate-
|
|
2
|
-
import { a as resolveTailwindV4SourceFromPatchOptions, i as resolveTailwindV4Source, n as defineConfig, o as createTailwindV4Engine, r as mountTailwindcssPatchCommands, t as createTailwindcssPatchCli } from "./index.bundle-
|
|
1
|
+
import { D as normalizeOptions, O as CacheStore, S as loadTailwindV4DesignSystem, _ as extractRawCandidates, a as tailwindcssPatchCommands, b as groupTokensByFile, c as MIGRATION_REPORT_KIND, d as getPatchStatusReport, f as runTailwindBuild, g as extractProjectCandidatesWithPositions, h as collectClassesFromTailwindV4, k as logger, l as MIGRATION_REPORT_SCHEMA_VERSION, m as collectClassesFromContexts, n as VALIDATE_FAILURE_REASONS, o as migrateConfigFiles, p as loadRuntimeContexts, r as ValidateCommandError, s as restoreConfigFiles, t as VALIDATE_EXIT_CODES, u as TailwindcssPatcher, v as extractRawCandidatesWithPositions, w as resolveValidTailwindV4Candidates, y as extractValidCandidates } from "./validate-CceFRP7h.mjs";
|
|
2
|
+
import { a as resolveTailwindV4SourceFromPatchOptions, i as resolveTailwindV4Source, n as defineConfig, o as createTailwindV4Engine, r as mountTailwindcssPatchCommands, t as createTailwindcssPatchCli } from "./index.bundle-Dnh0a6WS.mjs";
|
|
3
3
|
export { CacheStore, MIGRATION_REPORT_KIND, MIGRATION_REPORT_SCHEMA_VERSION, TailwindcssPatcher, VALIDATE_EXIT_CODES, VALIDATE_FAILURE_REASONS, ValidateCommandError, collectClassesFromContexts, collectClassesFromTailwindV4, createTailwindV4Engine, createTailwindcssPatchCli, defineConfig, extractProjectCandidatesWithPositions, extractRawCandidates, extractRawCandidatesWithPositions, extractValidCandidates, getPatchStatusReport, groupTokensByFile, loadRuntimeContexts, loadTailwindV4DesignSystem, logger, migrateConfigFiles, mountTailwindcssPatchCommands, normalizeOptions, resolveTailwindV4Source, resolveTailwindV4SourceFromPatchOptions, resolveValidTailwindV4Candidates, restoreConfigFiles, runTailwindBuild, tailwindcssPatchCommands };
|
|
@@ -23,7 +23,7 @@ _babel_traverse = require_chunk.__toESM(_babel_traverse);
|
|
|
23
23
|
let _babel_parser = require("@babel/parser");
|
|
24
24
|
let tailwindcss_config = require("tailwindcss-config");
|
|
25
25
|
//#region package.json
|
|
26
|
-
var version = "9.1
|
|
26
|
+
var version = "9.2.1";
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/constants.ts
|
|
29
29
|
const pkgName = "tailwindcss-patch";
|
|
@@ -1592,6 +1592,31 @@ function unique(values) {
|
|
|
1592
1592
|
function createRequireBase(base) {
|
|
1593
1593
|
return pathe.default.join(base, "package.json");
|
|
1594
1594
|
}
|
|
1595
|
+
function isRelativeSpecifier(id) {
|
|
1596
|
+
return id.startsWith("./") || id.startsWith("../") || id === "." || id === "..";
|
|
1597
|
+
}
|
|
1598
|
+
function isAbsoluteSpecifier(id) {
|
|
1599
|
+
return pathe.default.isAbsolute(id);
|
|
1600
|
+
}
|
|
1601
|
+
function isCssSpecifier(id) {
|
|
1602
|
+
return pathe.default.extname(id) === ".css";
|
|
1603
|
+
}
|
|
1604
|
+
function createCssResolutionCandidates(id) {
|
|
1605
|
+
if (isCssSpecifier(id)) return [id];
|
|
1606
|
+
return [`${id}/index.css`, id];
|
|
1607
|
+
}
|
|
1608
|
+
function createFallbackCssResolver(baseCandidates) {
|
|
1609
|
+
const bases = unique(baseCandidates);
|
|
1610
|
+
return async (id) => {
|
|
1611
|
+
if (isRelativeSpecifier(id) || isAbsoluteSpecifier(id)) return;
|
|
1612
|
+
for (const base of bases) {
|
|
1613
|
+
const requireFromBase = (0, node_module.createRequire)(createRequireBase(base));
|
|
1614
|
+
for (const candidate of createCssResolutionCandidates(id)) try {
|
|
1615
|
+
return requireFromBase.resolve(candidate);
|
|
1616
|
+
} catch {}
|
|
1617
|
+
}
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1595
1620
|
async function importResolvedModule(resolved) {
|
|
1596
1621
|
return import((0, node_url.pathToFileURL)(resolved).href);
|
|
1597
1622
|
}
|
|
@@ -1656,31 +1681,53 @@ async function loadTailwindV4DesignSystem(source) {
|
|
|
1656
1681
|
return promise;
|
|
1657
1682
|
}
|
|
1658
1683
|
async function compileTailwindV4Source(source) {
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1684
|
+
const bases = unique([source.base, ...source.baseFallbacks]);
|
|
1685
|
+
if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 compiler.");
|
|
1686
|
+
const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
|
|
1687
|
+
let lastError;
|
|
1688
|
+
for (const base of bases) {
|
|
1689
|
+
const dependencies = new Set(source.dependencies);
|
|
1690
|
+
try {
|
|
1691
|
+
return {
|
|
1692
|
+
compiled: await node.compile(source.css, {
|
|
1693
|
+
base,
|
|
1694
|
+
customCssResolver: createFallbackCssResolver([source.projectRoot, ...bases]),
|
|
1695
|
+
onDependency(dependency) {
|
|
1696
|
+
dependencies.add(pathe.default.resolve(dependency));
|
|
1697
|
+
}
|
|
1698
|
+
}),
|
|
1699
|
+
dependencies
|
|
1700
|
+
};
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
lastError = error;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
if (lastError instanceof Error) throw lastError;
|
|
1706
|
+
throw new Error("Failed to compile Tailwind CSS v4 source.");
|
|
1674
1707
|
}
|
|
1675
1708
|
//#endregion
|
|
1676
1709
|
//#region src/extraction/candidate-extractor.ts
|
|
1677
1710
|
let oxideImportPromise;
|
|
1678
1711
|
const designSystemCandidateCache = /* @__PURE__ */ new Map();
|
|
1712
|
+
function createOxideRuntimeDependencyError(cause) {
|
|
1713
|
+
return new Error([
|
|
1714
|
+
"tailwindcss-patch could not load @tailwindcss/oxide, which is required for source candidate scanning.",
|
|
1715
|
+
"This dependency should be installed automatically by tailwindcss-patch.",
|
|
1716
|
+
"Reinstall dependencies without disabling optional dependencies, or install @tailwindcss/oxide@^4.2.4 manually if your package manager omitted it."
|
|
1717
|
+
].join(" "), { cause });
|
|
1718
|
+
}
|
|
1679
1719
|
async function importOxide() {
|
|
1680
|
-
|
|
1720
|
+
try {
|
|
1721
|
+
return await import("@tailwindcss/oxide");
|
|
1722
|
+
} catch (error) {
|
|
1723
|
+
throw createOxideRuntimeDependencyError(error);
|
|
1724
|
+
}
|
|
1681
1725
|
}
|
|
1682
1726
|
function getOxideModule() {
|
|
1683
1727
|
oxideImportPromise ??= importOxide();
|
|
1728
|
+
oxideImportPromise.catch(() => {
|
|
1729
|
+
oxideImportPromise = void 0;
|
|
1730
|
+
});
|
|
1684
1731
|
return oxideImportPromise;
|
|
1685
1732
|
}
|
|
1686
1733
|
async function extractRawCandidatesWithPositions(content, extension = "html") {
|
|
@@ -16,7 +16,7 @@ import _babelTraverse from "@babel/traverse";
|
|
|
16
16
|
import { parse, parse as parse$1 } from "@babel/parser";
|
|
17
17
|
import { loadConfig } from "tailwindcss-config";
|
|
18
18
|
//#region package.json
|
|
19
|
-
var version = "9.1
|
|
19
|
+
var version = "9.2.1";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/constants.ts
|
|
22
22
|
const pkgName = "tailwindcss-patch";
|
|
@@ -1590,6 +1590,31 @@ function unique(values) {
|
|
|
1590
1590
|
function createRequireBase(base) {
|
|
1591
1591
|
return path.join(base, "package.json");
|
|
1592
1592
|
}
|
|
1593
|
+
function isRelativeSpecifier(id) {
|
|
1594
|
+
return id.startsWith("./") || id.startsWith("../") || id === "." || id === "..";
|
|
1595
|
+
}
|
|
1596
|
+
function isAbsoluteSpecifier(id) {
|
|
1597
|
+
return path.isAbsolute(id);
|
|
1598
|
+
}
|
|
1599
|
+
function isCssSpecifier(id) {
|
|
1600
|
+
return path.extname(id) === ".css";
|
|
1601
|
+
}
|
|
1602
|
+
function createCssResolutionCandidates(id) {
|
|
1603
|
+
if (isCssSpecifier(id)) return [id];
|
|
1604
|
+
return [`${id}/index.css`, id];
|
|
1605
|
+
}
|
|
1606
|
+
function createFallbackCssResolver(baseCandidates) {
|
|
1607
|
+
const bases = unique(baseCandidates);
|
|
1608
|
+
return async (id) => {
|
|
1609
|
+
if (isRelativeSpecifier(id) || isAbsoluteSpecifier(id)) return;
|
|
1610
|
+
for (const base of bases) {
|
|
1611
|
+
const requireFromBase = createRequire(createRequireBase(base));
|
|
1612
|
+
for (const candidate of createCssResolutionCandidates(id)) try {
|
|
1613
|
+
return requireFromBase.resolve(candidate);
|
|
1614
|
+
} catch {}
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1593
1618
|
async function importResolvedModule(resolved) {
|
|
1594
1619
|
return import(pathToFileURL(resolved).href);
|
|
1595
1620
|
}
|
|
@@ -1654,31 +1679,53 @@ async function loadTailwindV4DesignSystem(source) {
|
|
|
1654
1679
|
return promise;
|
|
1655
1680
|
}
|
|
1656
1681
|
async function compileTailwindV4Source(source) {
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1682
|
+
const bases = unique([source.base, ...source.baseFallbacks]);
|
|
1683
|
+
if (bases.length === 0) throw new Error("No base directories provided for Tailwind CSS v4 compiler.");
|
|
1684
|
+
const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases]);
|
|
1685
|
+
let lastError;
|
|
1686
|
+
for (const base of bases) {
|
|
1687
|
+
const dependencies = new Set(source.dependencies);
|
|
1688
|
+
try {
|
|
1689
|
+
return {
|
|
1690
|
+
compiled: await node.compile(source.css, {
|
|
1691
|
+
base,
|
|
1692
|
+
customCssResolver: createFallbackCssResolver([source.projectRoot, ...bases]),
|
|
1693
|
+
onDependency(dependency) {
|
|
1694
|
+
dependencies.add(path.resolve(dependency));
|
|
1695
|
+
}
|
|
1696
|
+
}),
|
|
1697
|
+
dependencies
|
|
1698
|
+
};
|
|
1699
|
+
} catch (error) {
|
|
1700
|
+
lastError = error;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
if (lastError instanceof Error) throw lastError;
|
|
1704
|
+
throw new Error("Failed to compile Tailwind CSS v4 source.");
|
|
1672
1705
|
}
|
|
1673
1706
|
//#endregion
|
|
1674
1707
|
//#region src/extraction/candidate-extractor.ts
|
|
1675
1708
|
let oxideImportPromise;
|
|
1676
1709
|
const designSystemCandidateCache = /* @__PURE__ */ new Map();
|
|
1710
|
+
function createOxideRuntimeDependencyError(cause) {
|
|
1711
|
+
return new Error([
|
|
1712
|
+
"tailwindcss-patch could not load @tailwindcss/oxide, which is required for source candidate scanning.",
|
|
1713
|
+
"This dependency should be installed automatically by tailwindcss-patch.",
|
|
1714
|
+
"Reinstall dependencies without disabling optional dependencies, or install @tailwindcss/oxide@^4.2.4 manually if your package manager omitted it."
|
|
1715
|
+
].join(" "), { cause });
|
|
1716
|
+
}
|
|
1677
1717
|
async function importOxide() {
|
|
1678
|
-
|
|
1718
|
+
try {
|
|
1719
|
+
return await import("@tailwindcss/oxide");
|
|
1720
|
+
} catch (error) {
|
|
1721
|
+
throw createOxideRuntimeDependencyError(error);
|
|
1722
|
+
}
|
|
1679
1723
|
}
|
|
1680
1724
|
function getOxideModule() {
|
|
1681
1725
|
oxideImportPromise ??= importOxide();
|
|
1726
|
+
oxideImportPromise.catch(() => {
|
|
1727
|
+
oxideImportPromise = void 0;
|
|
1728
|
+
});
|
|
1682
1729
|
return oxideImportPromise;
|
|
1683
1730
|
}
|
|
1684
1731
|
async function extractRawCandidatesWithPositions(content, extension = "html") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss-patch",
|
|
3
|
-
"version": "9.1
|
|
3
|
+
"version": "9.2.1",
|
|
4
4
|
"description": "patch tailwindcss for exposing context and extract classes",
|
|
5
5
|
"author": "ice breaker <1324318532@qq.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"@babel/traverse": "^7.29.0",
|
|
67
67
|
"@babel/types": "^7.29.0",
|
|
68
68
|
"@tailwindcss/node": "^4.2.4",
|
|
69
|
+
"@tailwindcss/oxide": "^4.2.4",
|
|
69
70
|
"cac": "6.7.14",
|
|
70
71
|
"consola": "^3.4.2",
|
|
71
72
|
"fs-extra": "^11.3.4",
|
|
@@ -77,7 +78,6 @@
|
|
|
77
78
|
"@tailwindcss-mangle/config": "7.0.1"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
|
-
"@tailwindcss/oxide": "^4.2.4",
|
|
81
81
|
"@tailwindcss/postcss": "^4.2.4",
|
|
82
82
|
"@tailwindcss/vite": "^4.2.4",
|
|
83
83
|
"tailwindcss": "^4.1.18",
|
|
@@ -14,12 +14,31 @@ import { getTailwindV4DesignSystemCacheKey, loadTailwindV4DesignSystem } from '.
|
|
|
14
14
|
let oxideImportPromise: ReturnType<typeof importOxide> | undefined
|
|
15
15
|
const designSystemCandidateCache = new Map<string, Map<string, boolean>>()
|
|
16
16
|
|
|
17
|
+
function createOxideRuntimeDependencyError(cause: unknown) {
|
|
18
|
+
return new Error(
|
|
19
|
+
[
|
|
20
|
+
'tailwindcss-patch could not load @tailwindcss/oxide, which is required for source candidate scanning.',
|
|
21
|
+
'This dependency should be installed automatically by tailwindcss-patch.',
|
|
22
|
+
'Reinstall dependencies without disabling optional dependencies, or install @tailwindcss/oxide@^4.2.4 manually if your package manager omitted it.',
|
|
23
|
+
].join(' '),
|
|
24
|
+
{ cause },
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
async function importOxide() {
|
|
18
|
-
|
|
29
|
+
try {
|
|
30
|
+
return await import('@tailwindcss/oxide')
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw createOxideRuntimeDependencyError(error)
|
|
34
|
+
}
|
|
19
35
|
}
|
|
20
36
|
|
|
21
37
|
function getOxideModule() {
|
|
22
38
|
oxideImportPromise ??= importOxide()
|
|
39
|
+
oxideImportPromise.catch(() => {
|
|
40
|
+
oxideImportPromise = undefined
|
|
41
|
+
})
|
|
23
42
|
return oxideImportPromise
|
|
24
43
|
}
|
|
25
44
|
|
package/src/v4/engine.ts
CHANGED
|
@@ -3,12 +3,30 @@ import type {
|
|
|
3
3
|
TailwindV4GenerateOptions,
|
|
4
4
|
TailwindV4GenerateResult,
|
|
5
5
|
TailwindV4ResolvedSource,
|
|
6
|
+
TailwindV4SourcePattern,
|
|
6
7
|
} from './types'
|
|
7
|
-
import { extractRawCandidatesWithPositions } from '../extraction/candidate-extractor'
|
|
8
|
+
import { extractRawCandidates, extractRawCandidatesWithPositions } from '../extraction/candidate-extractor'
|
|
8
9
|
import { extractTailwindV4InlineSourceCandidates, resolveValidTailwindV4Candidates } from './candidates'
|
|
9
10
|
import { compileTailwindV4Source, loadTailwindV4DesignSystem } from './node-adapter'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
function resolveScanSources(
|
|
13
|
+
options: TailwindV4GenerateOptions | undefined,
|
|
14
|
+
compiledSources: TailwindV4SourcePattern[],
|
|
15
|
+
) {
|
|
16
|
+
if (Array.isArray(options?.scanSources)) {
|
|
17
|
+
return options.scanSources
|
|
18
|
+
}
|
|
19
|
+
if (options?.scanSources === true) {
|
|
20
|
+
return compiledSources
|
|
21
|
+
}
|
|
22
|
+
return []
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function collectRawCandidates(
|
|
26
|
+
source: TailwindV4ResolvedSource,
|
|
27
|
+
options: TailwindV4GenerateOptions | undefined,
|
|
28
|
+
compiledSources: TailwindV4SourcePattern[] = [],
|
|
29
|
+
) {
|
|
12
30
|
const rawCandidates = new Set<string>()
|
|
13
31
|
|
|
14
32
|
for (const candidate of options?.candidates ?? []) {
|
|
@@ -22,6 +40,13 @@ async function collectRawCandidates(source: TailwindV4ResolvedSource, options: T
|
|
|
22
40
|
}
|
|
23
41
|
}
|
|
24
42
|
|
|
43
|
+
const filesystemSources = resolveScanSources(options, compiledSources)
|
|
44
|
+
if (filesystemSources.length > 0) {
|
|
45
|
+
for (const candidate of await extractRawCandidates(filesystemSources)) {
|
|
46
|
+
rawCandidates.add(candidate)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
25
50
|
const inlineSources = extractTailwindV4InlineSourceCandidates(source.css)
|
|
26
51
|
for (const candidate of inlineSources.included) {
|
|
27
52
|
rawCandidates.add(candidate)
|
|
@@ -44,17 +69,15 @@ export function createTailwindV4Engine(source: TailwindV4ResolvedSource): Tailwi
|
|
|
44
69
|
return resolveValidTailwindV4Candidates(designSystem, candidates)
|
|
45
70
|
},
|
|
46
71
|
async generate(options): Promise<TailwindV4GenerateResult> {
|
|
47
|
-
const
|
|
72
|
+
const { compiled, dependencies } = await compileTailwindV4Source(source)
|
|
73
|
+
const rawCandidates = await collectRawCandidates(source, options, compiled.sources)
|
|
48
74
|
const designSystem = await loadTailwindV4DesignSystem(source)
|
|
49
75
|
const classSet = resolveValidTailwindV4Candidates(designSystem, rawCandidates)
|
|
50
76
|
const inlineSources = extractTailwindV4InlineSourceCandidates(source.css)
|
|
51
|
-
// TODO: Non-inline `@source not "..."` is surfaced through `compiled.sources`;
|
|
52
|
-
// apply it here if generate() grows filesystem SourceEntry scanning.
|
|
53
77
|
for (const candidate of inlineSources.excluded) {
|
|
54
78
|
classSet.delete(candidate)
|
|
55
79
|
}
|
|
56
80
|
|
|
57
|
-
const { compiled, dependencies } = await compileTailwindV4Source(source)
|
|
58
81
|
const css = compiled.build(Array.from(classSet))
|
|
59
82
|
|
|
60
83
|
return {
|
package/src/v4/node-adapter.ts
CHANGED
|
@@ -20,6 +20,7 @@ interface TailwindV4NodeModule {
|
|
|
20
20
|
compile: (css: string, options: {
|
|
21
21
|
base: string
|
|
22
22
|
onDependency: (dependency: string) => void
|
|
23
|
+
customCssResolver?: (id: string, base: string) => Promise<string | false | undefined>
|
|
23
24
|
}) => Promise<TailwindV4CompiledSource>
|
|
24
25
|
__unstable__loadDesignSystem: (css: string, options: { base: string }) => Promise<TailwindV4DesignSystem>
|
|
25
26
|
}
|
|
@@ -35,6 +36,45 @@ function createRequireBase(base: string) {
|
|
|
35
36
|
return path.join(base, 'package.json')
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
function isRelativeSpecifier(id: string) {
|
|
40
|
+
return id.startsWith('./') || id.startsWith('../') || id === '.' || id === '..'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isAbsoluteSpecifier(id: string) {
|
|
44
|
+
return path.isAbsolute(id)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isCssSpecifier(id: string) {
|
|
48
|
+
return path.extname(id) === '.css'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function createCssResolutionCandidates(id: string) {
|
|
52
|
+
if (isCssSpecifier(id)) {
|
|
53
|
+
return [id]
|
|
54
|
+
}
|
|
55
|
+
return [`${id}/index.css`, id]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function createFallbackCssResolver(baseCandidates: string[]) {
|
|
59
|
+
const bases = unique(baseCandidates)
|
|
60
|
+
return async (id: string) => {
|
|
61
|
+
if (isRelativeSpecifier(id) || isAbsoluteSpecifier(id)) {
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
for (const base of bases) {
|
|
66
|
+
const requireFromBase = createRequire(createRequireBase(base))
|
|
67
|
+
for (const candidate of createCssResolutionCandidates(id)) {
|
|
68
|
+
try {
|
|
69
|
+
return requireFromBase.resolve(candidate)
|
|
70
|
+
}
|
|
71
|
+
catch {}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
38
78
|
async function importResolvedModule(resolved: string): Promise<TailwindV4NodeModule> {
|
|
39
79
|
return import(pathToFileURL(resolved).href) as unknown as Promise<TailwindV4NodeModule>
|
|
40
80
|
}
|
|
@@ -133,17 +173,37 @@ export async function loadTailwindV4DesignSystem(source: TailwindV4ResolvedSourc
|
|
|
133
173
|
}
|
|
134
174
|
|
|
135
175
|
export async function compileTailwindV4Source(source: TailwindV4ResolvedSource) {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
176
|
+
const bases = unique([source.base, ...source.baseFallbacks])
|
|
177
|
+
if (bases.length === 0) {
|
|
178
|
+
throw new Error('No base directories provided for Tailwind CSS v4 compiler.')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const node = await loadTailwindV4NodeModule([source.projectRoot, ...bases])
|
|
182
|
+
let lastError: unknown
|
|
183
|
+
|
|
184
|
+
for (const base of bases) {
|
|
185
|
+
const dependencies = new Set(source.dependencies)
|
|
186
|
+
try {
|
|
187
|
+
const compiled = await node.compile(source.css, {
|
|
188
|
+
base,
|
|
189
|
+
customCssResolver: createFallbackCssResolver([source.projectRoot, ...bases]),
|
|
190
|
+
onDependency(dependency) {
|
|
191
|
+
dependencies.add(path.resolve(dependency))
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
compiled,
|
|
197
|
+
dependencies,
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
lastError = error
|
|
202
|
+
}
|
|
203
|
+
}
|
|
144
204
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
dependencies,
|
|
205
|
+
if (lastError instanceof Error) {
|
|
206
|
+
throw lastError
|
|
148
207
|
}
|
|
208
|
+
throw new Error('Failed to compile Tailwind CSS v4 source.')
|
|
149
209
|
}
|
package/src/v4/types.ts
CHANGED
|
@@ -24,6 +24,13 @@ export interface TailwindV4CandidateSource {
|
|
|
24
24
|
export interface TailwindV4GenerateOptions {
|
|
25
25
|
candidates?: Iterable<string>
|
|
26
26
|
sources?: TailwindV4CandidateSource[]
|
|
27
|
+
/**
|
|
28
|
+
* 扫描文件系统 source entries 中的候选类名。
|
|
29
|
+
*
|
|
30
|
+
* - `true`:使用 Tailwind v4 编译入口解析出的 `@source` 列表。
|
|
31
|
+
* - `TailwindV4SourcePattern[]`:使用调用方显式传入的 source 列表。
|
|
32
|
+
*/
|
|
33
|
+
scanSources?: boolean | TailwindV4SourcePattern[]
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
export interface TailwindV4SourcePattern {
|