Skip to content

Commit ddbdac3

Browse files
committed
refactor: cli in typescript
- move cli to typescript - add build process for cli
1 parent 595c188 commit ddbdac3

File tree

8 files changed

+170
-112
lines changed

8 files changed

+170
-112
lines changed

packages/postcss-purgecss/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import * as postcss from "postcss";
2-
32
import PurgeCSS, {
43
defaultOptions,
54
mergeExtractorSelectors,
6-
standardizeSafelist,
5+
standardizeSafelist
76
} from "purgecss";
8-
97
import { RawContent, UserDefinedOptions } from "./types";
108

119
const PLUGIN_NAME = "postcss-purgecss";
@@ -51,6 +49,8 @@ async function purgeCSS(
5149
const selectors = mergeExtractorSelectors(cssFileSelectors, cssRawSelectors);
5250

5351
//purge unused selectors
52+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
53+
// @ts-ignore
5454
purgeCSS.walkThroughCSS(root, selectors);
5555

5656
if (purgeCSS.options.fontFace) purgeCSS.removeUnusedFontFaces();

packages/purgecss/bin/purgecss.js

Lines changed: 1 addition & 91 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/purgecss/src/VariablesStructure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as postcss from "postcss";
2-
import { matchAll } from "./index";
32
import { StringRegExpArray } from "./types";
3+
import { matchAll } from "./utils";
44

55
class VariableNode {
66
public nodes: VariableNode[] = [];

packages/purgecss/src/bin.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { program } from "commander";
2+
import fs from "fs";
3+
import packageJson from "./../package.json";
4+
import {
5+
defaultOptions,
6+
PurgeCSS,
7+
setOptions,
8+
standardizeSafelist
9+
} from "./index";
10+
11+
async function writeCSSToFile(filePath: string, css: string) {
12+
try {
13+
await fs.promises.writeFile(filePath, css);
14+
} catch (err) {
15+
console.error(err.message);
16+
}
17+
}
18+
19+
type CommandOptions = {
20+
config?: string;
21+
css?: string[];
22+
content?: string[];
23+
output?: string;
24+
fontFace?: boolean;
25+
keyframes?: boolean;
26+
variables?: boolean;
27+
rejected?: boolean;
28+
safelist?: string[];
29+
blocklist?: string[];
30+
skippedContentGlobs: string[];
31+
};
32+
33+
function parseCommandOptions() {
34+
program
35+
.description(packageJson.description)
36+
.version(packageJson.version)
37+
.usage("--css <css...> --content <content...> [options]");
38+
39+
program
40+
.option("-con, --content <files...>", "glob of content files")
41+
.option("-css, --css <files...>", "glob of css files")
42+
.option("-c, --config <path>", "path to the configuration file")
43+
.option(
44+
"-o, --output <path>",
45+
"file path directory to write purged css files to"
46+
)
47+
.option("-font, --font-face", "option to remove unused font-faces")
48+
.option("-keyframes, --keyframes", "option to remove unused keyframes")
49+
.option("-v, --variables", "option to remove unused variables")
50+
.option("-rejected, --rejected", "option to output rejected selectors")
51+
.option(
52+
"-s, --safelist <list...>",
53+
"list of classes that should not be removed"
54+
)
55+
.option(
56+
"-b, --blocklist <list...>",
57+
"list of selectors that should be removed"
58+
)
59+
.option(
60+
"-k, --skippedContentGlobs <list...>",
61+
"list of glob patterns for folders/files that should not be scanned"
62+
);
63+
64+
program.parse(process.argv);
65+
}
66+
67+
async function run() {
68+
parseCommandOptions();
69+
// config file is not specified or the content and css are not,
70+
// PurgeCSS will not run
71+
const {
72+
config,
73+
css,
74+
content,
75+
output,
76+
fontFace,
77+
keyframes,
78+
variables,
79+
rejected,
80+
safelist,
81+
blocklist,
82+
skippedContentGlobs,
83+
} = program.opts<CommandOptions>();
84+
85+
// config file is not specified or the content and css are not,
86+
// PurgeCSS will not run
87+
if (!config && !(content && css)) {
88+
program.help();
89+
}
90+
91+
// if the config file is present, use it
92+
// other options specified will override
93+
let options = defaultOptions;
94+
if (config) {
95+
options = await setOptions(config);
96+
}
97+
if (content) options.content = content;
98+
if (css) options.css = css;
99+
if (fontFace) options.fontFace = fontFace;
100+
if (keyframes) options.keyframes = keyframes;
101+
if (rejected) options.rejected = rejected;
102+
if (variables) options.variables = variables;
103+
if (safelist) options.safelist = standardizeSafelist(safelist);
104+
if (blocklist) options.blocklist = blocklist;
105+
if (skippedContentGlobs) options.skippedContentGlobs = skippedContentGlobs;
106+
107+
const purged = await new PurgeCSS().purge(options);
108+
const resultOutput = options.output || output;
109+
// output results in specified directory
110+
if (resultOutput) {
111+
if (purged.length === 1 && resultOutput.endsWith(".css")) {
112+
await writeCSSToFile(resultOutput, purged[0].css);
113+
return;
114+
}
115+
116+
for (const purgedResult of purged) {
117+
const fileName = purgedResult?.file?.split("/").pop();
118+
await writeCSSToFile(`${output}/${fileName}`, purgedResult.css);
119+
}
120+
} else {
121+
console.log(JSON.stringify(purged));
122+
}
123+
}
124+
125+
try {
126+
run();
127+
} catch (error) {
128+
console.error(error.message);
129+
process.exit(1);
130+
}

0 commit comments

Comments
 (0)