purgecss-webpack-plugin 8.0.0 → 9.0.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 +3 -1
- package/lib/purgecss-webpack-plugin.d.ts +32 -5
- package/lib/purgecss-webpack-plugin.esm.js +28 -15
- package/lib/purgecss-webpack-plugin.js +28 -15
- package/package.json +15 -13
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ to filter out directories see the glob-all documentation [here](https://www.npmj
|
|
|
78
78
|
|
|
79
79
|
### Options
|
|
80
80
|
|
|
81
|
-
The options
|
|
81
|
+
The webpack plugin passes the following options of the purgecss [Configuration](https://www.purgecss.com/configuration.html) to PurgeCSS: `defaultExtractor`, `extractors`, `fontFace`, `keyframes`, `variables`, `safelist`, `blocklist`, `dynamicAttributes` and `rejected`. The plugin purges the CSS assets of the compilation and uses `paths` as the content, so it doesn't take the `css` and `content` options. Source maps are generated when the webpack `devtool` option is set. Other options, such as `rejectedCss` or `skippedContentGlobs`, have no effect.
|
|
82
82
|
|
|
83
83
|
- #### paths
|
|
84
84
|
|
|
@@ -116,6 +116,8 @@ new PurgeCSSPlugin({
|
|
|
116
116
|
});
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
The names are compared with the chunk names (for an entrypoint, its key in `entry`), not with the file names.
|
|
120
|
+
|
|
119
121
|
- #### safelist
|
|
120
122
|
|
|
121
123
|
Similar as for the `paths` option, you also can define a function for this option:
|
|
@@ -32,8 +32,29 @@ export declare type ComplexSafelist = {
|
|
|
32
32
|
* in the final CSS, even if `child-of-bg` is not found.
|
|
33
33
|
*
|
|
34
34
|
*/
|
|
35
|
-
deep?:
|
|
36
|
-
|
|
35
|
+
deep?: StringRegExpArray;
|
|
36
|
+
/**
|
|
37
|
+
* You can safelist whole selectors if any part of that selector matches a
|
|
38
|
+
* pattern with `safelist.greedy`
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* const purgecss = await new PurgeCSS().purge({
|
|
44
|
+
* content: [],
|
|
45
|
+
* css: [],
|
|
46
|
+
* safelist: {
|
|
47
|
+
* greedy: [/red$/]
|
|
48
|
+
* }
|
|
49
|
+
* })
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* In this example, selectors such as `button.bg-red.nonexistent-class`
|
|
53
|
+
* will be left in the final CSS, even if `button` and `nonexistent-class`
|
|
54
|
+
* are not found.
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
greedy?: StringRegExpArray;
|
|
37
58
|
variables?: StringRegExpArray;
|
|
38
59
|
keyframes?: StringRegExpArray;
|
|
39
60
|
};
|
|
@@ -126,7 +147,7 @@ export declare interface PurgeCSSUserDefinedOptions {
|
|
|
126
147
|
/** {@inheritDoc purgecss#Options.skippedContentGlobs} */
|
|
127
148
|
skippedContentGlobs?: Array<string>;
|
|
128
149
|
/** {@inheritDoc purgecss#Options.dynamicAttributes} */
|
|
129
|
-
dynamicAttributes?:
|
|
150
|
+
dynamicAttributes?: StringRegExpArray;
|
|
130
151
|
}
|
|
131
152
|
|
|
132
153
|
/**
|
|
@@ -158,6 +179,12 @@ export declare interface RawCSS {
|
|
|
158
179
|
export declare type SafelistFunction = () => ComplexSafelist;
|
|
159
180
|
|
|
160
181
|
/**
|
|
182
|
+
* Strings and regular expressions an option is matched against. A string
|
|
183
|
+
* matches a value exactly, except a string written between slashes, like
|
|
184
|
+
* `"/^btn-/"` or `"/^btn-/i"`, which is parsed as a regular expression. This
|
|
185
|
+
* form lets configuration files that cannot contain regular expressions, such
|
|
186
|
+
* as `postcss.config.json`, use patterns.
|
|
187
|
+
*
|
|
161
188
|
* @public
|
|
162
189
|
*/
|
|
163
190
|
export declare type StringRegExpArray = Array<RegExp | string>;
|
|
@@ -169,8 +196,8 @@ export declare type UserDefinedOptions = Omit<PurgeCSSUserDefinedOptions, "css"
|
|
|
169
196
|
paths: string[] | PathFunction;
|
|
170
197
|
moduleExtensions?: string[];
|
|
171
198
|
verbose?: boolean;
|
|
172
|
-
safelist
|
|
173
|
-
blocklist
|
|
199
|
+
safelist?: PurgeCSSUserDefinedOptions["safelist"] | SafelistFunction;
|
|
200
|
+
blocklist?: PurgeCSSUserDefinedOptions["blocklist"] | BlocklistFunction;
|
|
174
201
|
only?: string[];
|
|
175
202
|
};
|
|
176
203
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
3
4
|
import { PurgeCSS, defaultOptions } from 'purgecss';
|
|
4
5
|
import { sources } from 'webpack';
|
|
5
6
|
|
|
@@ -55,6 +56,7 @@ function getPurgeCSSOptions(pluginOptions, filesToSearch, asset, fileName, sourc
|
|
|
55
56
|
variables: options.variables,
|
|
56
57
|
safelist: options.safelist,
|
|
57
58
|
blocklist: options.blocklist,
|
|
59
|
+
dynamicAttributes: options.dynamicAttributes,
|
|
58
60
|
sourceMap: sourceMap ? { inline: false, to: fileName } : false,
|
|
59
61
|
};
|
|
60
62
|
}
|
|
@@ -72,7 +74,7 @@ function createSource(name, asset, purgeResult, sourceMap) {
|
|
|
72
74
|
return new sources.RawSource(purgeResult.css);
|
|
73
75
|
}
|
|
74
76
|
const { source, map } = asset.sourceAndMap();
|
|
75
|
-
return new sources.SourceMapSource(purgeResult.css, name, purgeResult.sourceMap, source.toString(), map, false);
|
|
77
|
+
return new sources.SourceMapSource(purgeResult.css, name, purgeResult.sourceMap, source.toString(), map !== null && map !== void 0 ? map : undefined, false);
|
|
76
78
|
}
|
|
77
79
|
/**
|
|
78
80
|
* @public
|
|
@@ -88,12 +90,23 @@ class PurgeCSSPlugin {
|
|
|
88
90
|
initializePlugin(compilation) {
|
|
89
91
|
compilation.hooks.additionalAssets.tapPromise(pluginName, async () => {
|
|
90
92
|
let configFileOptions;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
const t = path.resolve(process.cwd(), "purgecss.config.js");
|
|
94
|
+
// the config file is optional, but an existing one that fails to load
|
|
95
|
+
// (e.g. a syntax error) is reported instead of being silently ignored
|
|
96
|
+
if (fs.existsSync(t)) {
|
|
97
|
+
try {
|
|
98
|
+
const importedConfig = await import(pathToFileURL(t).href);
|
|
99
|
+
// Handle both ES modules (direct export) and CommonJS (default export)
|
|
100
|
+
configFileOptions =
|
|
101
|
+
importedConfig.default && typeof importedConfig.default === "object"
|
|
102
|
+
? importedConfig.default
|
|
103
|
+
: importedConfig;
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
throw new Error(`Error loading the config file ${t}: ${err}`, {
|
|
107
|
+
cause: err,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
97
110
|
}
|
|
98
111
|
this.options = {
|
|
99
112
|
...(configFileOptions ? configFileOptions : {}),
|
|
@@ -114,14 +127,14 @@ class PurgeCSSPlugin {
|
|
|
114
127
|
return isFileOfTypes(name, [".css"]);
|
|
115
128
|
});
|
|
116
129
|
for (const chunk of compilation.chunks) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
// `only` lists chunk names, e.g. the entry names. Compare them with the
|
|
131
|
+
// chunk name, not with the asset path: a substring of the path also
|
|
132
|
+
// matches other chunks (`style` in `style_print.css` or `css/style/`)
|
|
133
|
+
if (this.options.only &&
|
|
134
|
+
!(chunk.name && this.options.only.includes(chunk.name))) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const assetsToPurge = assetsFromCompilation.filter(([name]) => chunk.files.has(name));
|
|
125
138
|
for (const [name, asset] of assetsToPurge) {
|
|
126
139
|
const filesToSearch = entryPaths.filter((v) => !styleExtensions.some((ext) => v.endsWith(ext)));
|
|
127
140
|
const sourceMapEnabled = !!compilation.compiler.options.devtool;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
|
+
var url = require('url');
|
|
5
6
|
var purgecss = require('purgecss');
|
|
6
7
|
var webpack = require('webpack');
|
|
7
8
|
|
|
@@ -77,6 +78,7 @@ function getPurgeCSSOptions(pluginOptions, filesToSearch, asset, fileName, sourc
|
|
|
77
78
|
variables: options.variables,
|
|
78
79
|
safelist: options.safelist,
|
|
79
80
|
blocklist: options.blocklist,
|
|
81
|
+
dynamicAttributes: options.dynamicAttributes,
|
|
80
82
|
sourceMap: sourceMap ? { inline: false, to: fileName } : false,
|
|
81
83
|
};
|
|
82
84
|
}
|
|
@@ -94,7 +96,7 @@ function createSource(name, asset, purgeResult, sourceMap) {
|
|
|
94
96
|
return new webpack.sources.RawSource(purgeResult.css);
|
|
95
97
|
}
|
|
96
98
|
const { source, map } = asset.sourceAndMap();
|
|
97
|
-
return new webpack.sources.SourceMapSource(purgeResult.css, name, purgeResult.sourceMap, source.toString(), map, false);
|
|
99
|
+
return new webpack.sources.SourceMapSource(purgeResult.css, name, purgeResult.sourceMap, source.toString(), map !== null && map !== void 0 ? map : undefined, false);
|
|
98
100
|
}
|
|
99
101
|
/**
|
|
100
102
|
* @public
|
|
@@ -110,12 +112,23 @@ class PurgeCSSPlugin {
|
|
|
110
112
|
initializePlugin(compilation) {
|
|
111
113
|
compilation.hooks.additionalAssets.tapPromise(pluginName, async () => {
|
|
112
114
|
let configFileOptions;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
const t = path__namespace.resolve(process.cwd(), "purgecss.config.js");
|
|
116
|
+
// the config file is optional, but an existing one that fails to load
|
|
117
|
+
// (e.g. a syntax error) is reported instead of being silently ignored
|
|
118
|
+
if (fs__namespace.existsSync(t)) {
|
|
119
|
+
try {
|
|
120
|
+
const importedConfig = await import(url.pathToFileURL(t).href);
|
|
121
|
+
// Handle both ES modules (direct export) and CommonJS (default export)
|
|
122
|
+
configFileOptions =
|
|
123
|
+
importedConfig.default && typeof importedConfig.default === "object"
|
|
124
|
+
? importedConfig.default
|
|
125
|
+
: importedConfig;
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
throw new Error(`Error loading the config file ${t}: ${err}`, {
|
|
129
|
+
cause: err,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
119
132
|
}
|
|
120
133
|
this.options = {
|
|
121
134
|
...(configFileOptions ? configFileOptions : {}),
|
|
@@ -136,14 +149,14 @@ class PurgeCSSPlugin {
|
|
|
136
149
|
return isFileOfTypes(name, [".css"]);
|
|
137
150
|
});
|
|
138
151
|
for (const chunk of compilation.chunks) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
152
|
+
// `only` lists chunk names, e.g. the entry names. Compare them with the
|
|
153
|
+
// chunk name, not with the asset path: a substring of the path also
|
|
154
|
+
// matches other chunks (`style` in `style_print.css` or `css/style/`)
|
|
155
|
+
if (this.options.only &&
|
|
156
|
+
!(chunk.name && this.options.only.includes(chunk.name))) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const assetsToPurge = assetsFromCompilation.filter(([name]) => chunk.files.has(name));
|
|
147
160
|
for (const [name, asset] of assetsToPurge) {
|
|
148
161
|
const filesToSearch = entryPaths.filter((v) => !styleExtensions.some((ext) => v.endsWith(ext)));
|
|
149
162
|
const sourceMapEnabled = !!compilation.compiler.options.devtool;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "purgecss-webpack-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "PurgeCSS plugin for webpack - Remove unused css",
|
|
5
5
|
"author": "Ffloriel",
|
|
6
6
|
"homepage": "https://purgecss.com",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"purify"
|
|
19
19
|
],
|
|
20
20
|
"license": "MIT",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22.12.0"
|
|
23
|
+
},
|
|
21
24
|
"main": "lib/purgecss-webpack-plugin.js",
|
|
22
25
|
"module": "./lib/purgecss-webpack-plugin.esm.js",
|
|
23
26
|
"types": "./lib/purgecss-webpack-plugin.d.ts",
|
|
@@ -32,28 +35,27 @@
|
|
|
32
35
|
"type": "git",
|
|
33
36
|
"url": "git+https://github.com/FullHuman/purgecss.git"
|
|
34
37
|
},
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "ts-node build.ts",
|
|
37
|
-
"test": "jest"
|
|
38
|
-
},
|
|
39
38
|
"dependencies": {
|
|
40
|
-
"purgecss": "^
|
|
41
|
-
"webpack": ">=5.95.0"
|
|
39
|
+
"purgecss": "^9.0.0"
|
|
42
40
|
},
|
|
43
41
|
"bugs": {
|
|
44
42
|
"url": "https://github.com/FullHuman/purgecss/issues"
|
|
45
43
|
},
|
|
46
44
|
"devDependencies": {
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"mini-css-extract-plugin": "^2.
|
|
45
|
+
"css-loader": "^7.1.5",
|
|
46
|
+
"fast-glob": "^3.3.3",
|
|
47
|
+
"mini-css-extract-plugin": "^2.10.2",
|
|
48
|
+
"webpack": "^5.112.2"
|
|
50
49
|
},
|
|
51
50
|
"peerDependencies": {
|
|
52
|
-
"webpack": "
|
|
51
|
+
"webpack": "^5.0.0"
|
|
53
52
|
},
|
|
54
53
|
"publishConfig": {
|
|
55
54
|
"access": "public",
|
|
56
55
|
"registry": "https://registry.npmjs.org/"
|
|
57
56
|
},
|
|
58
|
-
"
|
|
59
|
-
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "ts-node build.ts",
|
|
59
|
+
"test": "jest"
|
|
60
|
+
}
|
|
61
|
+
}
|