astro-purgecss 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -1
- package/dist/index.mjs +17 -12
- package/dist/utils.d.ts +3 -0
- package/dist/utils.mjs +42 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -79,6 +79,14 @@ export default defineConfig({
|
|
|
79
79
|
blocklist: ['usedClass', /^nav-/],
|
|
80
80
|
content: [
|
|
81
81
|
process.cwd() + '/src/**/*.{astro,vue}' // Watching astro and vue sources (for SSR, read the note below)
|
|
82
|
+
],
|
|
83
|
+
extractors: [
|
|
84
|
+
{
|
|
85
|
+
// Example using a taiwindcss compatible class extractor
|
|
86
|
+
extractor: (content) =>
|
|
87
|
+
content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [],
|
|
88
|
+
extensions: ['astro', 'html']
|
|
89
|
+
}
|
|
82
90
|
]
|
|
83
91
|
})
|
|
84
92
|
]
|
|
@@ -103,6 +111,11 @@ export type PurgeCSSOptions = {
|
|
|
103
111
|
safelist?: UserDefinedSafelist; // indicates which selectors are safe to leave in the final CSS
|
|
104
112
|
blocklist?: StringRegExpArray; // blocks the CSS selectors from appearing in the final output CSS
|
|
105
113
|
content?: Array<string | RawContent>;
|
|
114
|
+
extractors?: // provides custom functions to extract CSS classes in specific ways (eg. when using tailwind.css)
|
|
115
|
+
Array<{
|
|
116
|
+
extractor: (content: string) => string[]; // matched css classes
|
|
117
|
+
extensions: string[]; // file extensions for which this extractor is to be used
|
|
118
|
+
}>;
|
|
106
119
|
};
|
|
107
120
|
```
|
|
108
121
|
|
|
@@ -116,7 +129,38 @@ We have also setup an example repository available here: [example-purgecss](../.
|
|
|
116
129
|
|
|
117
130
|
- If you are using [inline styles](https://docs.astro.build/en/guides/styling/#scoped-styles), this plugin won't be able to purge those css rules, due to astro's way of handling scoped css rules.
|
|
118
131
|
|
|
119
|
-
- If you are using
|
|
132
|
+
- If you are using Astro view transitions, use the following options so that purgecss keeps the corresponding animations:
|
|
133
|
+
|
|
134
|
+
```diff
|
|
135
|
+
export default defineConfig({
|
|
136
|
+
integrations: [
|
|
137
|
+
purgecss({
|
|
138
|
+
+ keyframes: false
|
|
139
|
+
+ , safelist: {
|
|
140
|
+
+ greedy: [/*astro*/]
|
|
141
|
+
+ }
|
|
142
|
+
}),
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- If you are using `tailwind.css`, please read about purge limitations in this guide [writing-purgeable-html](https://v2.tailwindcss.com/docs/optimizing-for-production#writing-purgeable-html). You may also need a custom class extractor compatible with arbitrary and container based `tailwind.css` classes. For example:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
export default defineConfig({
|
|
151
|
+
integrations: [
|
|
152
|
+
purgecss({
|
|
153
|
+
extractors: [
|
|
154
|
+
{
|
|
155
|
+
extractor: (content) =>
|
|
156
|
+
content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [],
|
|
157
|
+
extensions: ['astro', 'html']
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
```
|
|
120
164
|
|
|
121
165
|
## Changelog
|
|
122
166
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { writeFile } from "node:fs/promises";
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return outputPath;
|
|
7
|
-
if (outputPath.endsWith("\\")) {
|
|
8
|
-
outputPath = outputPath.substring(0, outputPath.length - 1);
|
|
9
|
-
}
|
|
10
|
-
outputPath = outputPath.replaceAll("\\", "/");
|
|
11
|
-
return outputPath;
|
|
12
|
-
}
|
|
5
|
+
import { PurgeCSS } from "purgecss";
|
|
6
|
+
import { handleWindowsPath, replaceStringInDirectory } from "./utils";
|
|
13
7
|
function src_default(options = {}) {
|
|
14
8
|
return {
|
|
15
9
|
name: "astro-purgecss",
|
|
@@ -27,7 +21,18 @@ function src_default(options = {}) {
|
|
|
27
21
|
]
|
|
28
22
|
});
|
|
29
23
|
await Promise.all(
|
|
30
|
-
purged.filter(({ file }) => file == null ? void 0 : file.endsWith(".css")).map(async ({ css, file }) =>
|
|
24
|
+
purged.filter(({ file }) => file == null ? void 0 : file.endsWith(".css")).map(async ({ css, file }) => {
|
|
25
|
+
if (!file) return;
|
|
26
|
+
await writeFile(file, css);
|
|
27
|
+
const hash = await createHash("sha256").update(css).digest("hex").substring(0, 7);
|
|
28
|
+
const newPath = file.slice(0, -12) + hash + ".css";
|
|
29
|
+
await rename(file, newPath);
|
|
30
|
+
await replaceStringInDirectory(
|
|
31
|
+
outDir + "../",
|
|
32
|
+
path.basename(file),
|
|
33
|
+
path.basename(newPath)
|
|
34
|
+
);
|
|
35
|
+
})
|
|
31
36
|
);
|
|
32
37
|
}
|
|
33
38
|
}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function handleWindowsPath(outputPath: string): string;
|
|
2
|
+
export declare function replaceStringInFile(filePath: string, searchValue: string, replaceValue: string): Promise<void>;
|
|
3
|
+
export declare function replaceStringInDirectory(directory: string, searchValue: string, replaceValue: string): Promise<void>;
|
package/dist/utils.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
function handleWindowsPath(outputPath) {
|
|
4
|
+
if (process.platform !== "win32") return outputPath;
|
|
5
|
+
if (outputPath.endsWith("\\")) {
|
|
6
|
+
outputPath = outputPath.substring(0, outputPath.length - 1);
|
|
7
|
+
}
|
|
8
|
+
outputPath = outputPath.replaceAll("\\", "/");
|
|
9
|
+
return outputPath;
|
|
10
|
+
}
|
|
11
|
+
async function replaceStringInFile(filePath, searchValue, replaceValue) {
|
|
12
|
+
try {
|
|
13
|
+
const fileContent = await readFile(filePath, "utf8");
|
|
14
|
+
if (fileContent.includes(searchValue)) {
|
|
15
|
+
const re = new RegExp(searchValue, "g");
|
|
16
|
+
const newContent = fileContent.replace(re, replaceValue);
|
|
17
|
+
await writeFile(filePath, newContent, "utf8");
|
|
18
|
+
}
|
|
19
|
+
} catch (err) {
|
|
20
|
+
console.error(`Error processing file ${filePath}: ${err}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function replaceStringInDirectory(directory, searchValue, replaceValue) {
|
|
24
|
+
try {
|
|
25
|
+
const files = await readdir(directory, { withFileTypes: true });
|
|
26
|
+
for (const file of files) {
|
|
27
|
+
const fullPath = path.join(directory, file.name);
|
|
28
|
+
if (file.isDirectory()) {
|
|
29
|
+
await replaceStringInDirectory(fullPath, searchValue, replaceValue);
|
|
30
|
+
} else if (file.isFile()) {
|
|
31
|
+
await replaceStringInFile(fullPath, searchValue, replaceValue);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error(`Error processing directory ${directory}: ${err}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
handleWindowsPath,
|
|
40
|
+
replaceStringInDirectory,
|
|
41
|
+
replaceStringInFile
|
|
42
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-purgecss",
|
|
3
3
|
"description": "Remove unused CSS rules from your final Astro bundle",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"author": "codiume",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"astro": "^4.0.0",
|
|
40
|
-
"purgecss": "^
|
|
40
|
+
"purgecss": "^6.0.0"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "astro-build --src src/index.ts",
|
|
43
|
+
"build": "astro-build --src src/index.ts src/utils.ts",
|
|
44
44
|
"typecheck": "tsc --declaration --emitDeclarationOnly"
|
|
45
45
|
}
|
|
46
46
|
}
|