cssnano 8.0.10 → 9.0.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/package.json CHANGED
@@ -1,16 +1,12 @@
1
1
  {
2
2
  "name": "cssnano",
3
- "version": "8.0.10",
3
+ "version": "9.0.1",
4
4
  "description": "A modular CSS minifier, built on top of the PostCSS ecosystem.",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./types/index.d.ts",
8
8
  "default": "./src/index.js"
9
- },
10
- "./src": "./src/index.js",
11
- "./src/index": "./src/index.js",
12
- "./src/index.js": "./src/index.js",
13
- "./package.json": "./package.json"
9
+ }
14
10
  },
15
11
  "funding": {
16
12
  "type": "opencollective",
@@ -27,8 +23,7 @@
27
23
  ],
28
24
  "license": "MIT",
29
25
  "dependencies": {
30
- "cssnano-preset-default": "^8.0.10",
31
- "lilconfig": "^3.1.3"
26
+ "cssnano-preset-default": "^9.0.1"
32
27
  },
33
28
  "homepage": "https://github.com/cssnano/cssnano",
34
29
  "author": {
@@ -49,18 +44,19 @@
49
44
  "url": "https://github.com/cssnano/cssnano/issues"
50
45
  },
51
46
  "engines": {
52
- "node": "^22.11.0 || ^24.11.0 || >=26.0"
47
+ "node": "^22.22.3 || ^24.15.0 || >=26.0"
53
48
  },
54
49
  "devDependencies": {
55
50
  "autoprefixer": "^10.5.4",
56
- "cssnano-preset-advanced": "^8.0.10",
57
- "cssnano-preset-lite": "^5.0.6",
51
+ "cssnano-preset-advanced": "^9.0.1",
52
+ "cssnano-preset-lite": "^6.0.0",
58
53
  "postcss": "^8.5.26",
59
54
  "postcss-font-magician": "^4.0.0"
60
55
  },
61
56
  "peerDependencies": {
62
57
  "postcss": "^8.5.26"
63
58
  },
59
+ "type": "module",
64
60
  "scripts": {
65
61
  "test": "node --test"
66
62
  }
package/src/index.js CHANGED
@@ -1,10 +1,12 @@
1
- 'use strict';
2
- const path = require('node:path');
3
- const postcss = require('postcss');
4
- const { lilconfigSync } = require('lilconfig');
5
- const defaultPreset = require('cssnano-preset-default');
1
+ import { createRequire } from 'node:module';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import postcss from 'postcss';
5
+ import defaultPreset from 'cssnano-preset-default';
6
6
 
7
- const cssnano = 'cssnano';
7
+ const require = createRequire(import.meta.url);
8
+
9
+ const configFileNames = ['.cssnanorc.json', 'cssnano.config.js'];
8
10
 
9
11
  /** @typedef {boolean | { exclude?: boolean } | void | undefined} PluginOptions */
10
12
  /** @typedef {import('postcss').PluginCreator<any>} PluginCreator */
@@ -48,7 +50,7 @@ function resolvePreset(preset) {
48
50
  }
49
51
 
50
52
  // For JS setups where we invoked the preset already
51
- if (fn.plugins) {
53
+ if (typeof fn === 'object' && fn !== null && 'plugins' in fn) {
52
54
  return fn.plugins;
53
55
  }
54
56
 
@@ -67,11 +69,13 @@ function resolvePreset(preset) {
67
69
  return require(fn)(options).plugins;
68
70
  }
69
71
 
70
- const sugar = `cssnano-preset-${fn}`;
71
-
72
- // Try loading a preset from node_modules (sugar)
73
- if (isResolvable(sugar)) {
74
- return require(sugar)(options).plugins;
72
+ // Only the built-in preset names support shorthand resolution. Other
73
+ // strings must be passed to the module resolver unchanged.
74
+ if (fn === 'lite' || fn === 'advanced') {
75
+ const sugar = `cssnano-preset-${fn}`;
76
+ if (isResolvable(sugar)) {
77
+ return require(sugar)(options).plugins;
78
+ }
75
79
  }
76
80
 
77
81
  // If all else fails, we probably have a typo in the config somewhere
@@ -81,93 +85,100 @@ function resolvePreset(preset) {
81
85
  }
82
86
 
83
87
  /**
84
- * cssnano will look for configuration firstly as options passed
85
- * directly to it, and failing this it will use lilconfig to
86
- * load an external file.
87
-
88
- * @param {Options} options
88
+ * @param {string} filePath
89
+ * @returns {unknown}
89
90
  */
90
- function resolveConfig(options) {
91
- if (options.preset) {
92
- return resolvePreset(options.preset);
91
+ function loadConfigFile(filePath) {
92
+ if (filePath.endsWith('.json')) {
93
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
93
94
  }
94
-
95
- /** @type {string | undefined} */
96
- let searchPath = process.cwd();
97
- let configPath = undefined;
98
-
99
- if (options.configFile) {
100
- searchPath = undefined;
101
- configPath = path.resolve(process.cwd(), options.configFile);
95
+ const config = createRequire(filePath)(filePath);
96
+ if (
97
+ config !== null &&
98
+ typeof config === 'object' &&
99
+ Object.prototype.toString.call(config) === '[object Module]' &&
100
+ 'default' in config
101
+ ) {
102
+ return config.default;
102
103
  }
104
+ return config;
105
+ }
103
106
 
104
- const configExplorer = lilconfigSync(cssnano, {
105
- searchPlaces: [
106
- 'package.json',
107
- '.cssnanorc',
108
- '.cssnanorc.json',
109
- '.cssnanorc.js',
110
- 'cssnano.config.js',
111
- ],
112
- });
113
- const config = configPath
114
- ? configExplorer.load(configPath)
115
- : configExplorer.search(searchPath);
116
-
117
- if (config === null) {
118
- return resolvePreset('default');
107
+ /**
108
+ * @param {string} [configFile]
109
+ * @returns {unknown | null}
110
+ */
111
+ function loadDiscoveredConfig(configFile) {
112
+ if (configFile) {
113
+ const configPath = path.resolve(process.cwd(), configFile);
114
+ if (!fs.existsSync(configPath)) {
115
+ throw new Error(
116
+ `Cannot find cssnano configuration file "${configFile}".`
117
+ );
118
+ }
119
+ return loadConfigFile(configPath);
119
120
  }
120
121
 
121
- return resolvePreset(config.config.preset || config.config);
122
+ for (const fileName of configFileNames) {
123
+ const configPath = path.join(process.cwd(), fileName);
124
+ if (!fs.existsSync(configPath)) continue;
125
+ return loadConfigFile(configPath);
126
+ }
127
+ return null;
122
128
  }
123
129
 
124
130
  /**
125
- * @type {import('postcss').PluginCreator<Options>}
126
- * @param {Options=} options
127
- * @return {import('postcss').Processor}
131
+ * @param {Options} options
132
+ * @returns {PresetPlugin[]}
128
133
  */
129
- function cssnanoPlugin(options = {}) {
130
- /** @typedef {Options & { preset: { plugins: PresetPlugin[] } }} MutableOptions */
131
- if (Array.isArray(/** @type {MutableOptions} */ (options).plugins)) {
134
+ function resolveConfig(options) {
135
+ if (options.preset) {
132
136
  if (
133
- !(/** @type {MutableOptions} */ (options).preset) ||
134
- !(/** @type {MutableOptions} */ (options).preset.plugins)
137
+ Array.isArray(options.preset) &&
138
+ /** @type {unknown[]} */ (options.preset).length === 0
135
139
  ) {
136
- /** @type {MutableOptions} */ (options).preset = { plugins: [] };
140
+ return [];
137
141
  }
142
+ return resolvePreset(options.preset);
143
+ }
144
+ if (Array.isArray(options.plugins)) return [];
145
+
146
+ const config = loadDiscoveredConfig(options.configFile);
147
+ const preset =
148
+ config !== null && typeof config === 'object' && 'preset' in config
149
+ ? config.preset
150
+ : config;
151
+ return resolvePreset(config === null ? 'default' : preset);
152
+ }
138
153
 
139
- const inputPlugins = /** @type {PluginSpec[]} */ (
140
- /** @type {MutableOptions} */ (options).plugins
141
- );
154
+ /**
155
+ * @param {Options=} options
156
+ * @return {import('postcss').Processor}
157
+ */
158
+ function cssnanoPlugin(options = {}) {
159
+ let nanoPlugins = resolveConfig(options);
160
+ if (Array.isArray(options.plugins)) {
161
+ nanoPlugins = nanoPlugins.slice();
162
+ const inputPlugins = options.plugins;
142
163
  for (const plugin of inputPlugins) {
143
164
  if (Array.isArray(plugin)) {
144
165
  const [pluginDef, opts = {}] = plugin;
145
166
  if (typeof pluginDef === 'string' && isResolvable(pluginDef)) {
146
- /** @type {MutableOptions} */ (options).preset.plugins.push([
147
- require(pluginDef),
167
+ nanoPlugins.push([
168
+ /** @type {PluginCreator} */ (require(pluginDef)),
148
169
  opts,
149
170
  ]);
150
171
  } else {
151
- /** @type {MutableOptions} */ (options).preset.plugins.push([
152
- /** @type {PluginCreator} */ (pluginDef),
153
- opts,
154
- ]);
172
+ nanoPlugins.push([/** @type {PluginCreator} */ (pluginDef), opts]);
155
173
  }
156
174
  } else if (typeof plugin === 'string' && isResolvable(plugin)) {
157
- /** @type {MutableOptions} */ (options).preset.plugins.push([
158
- require(plugin),
159
- {},
160
- ]);
175
+ nanoPlugins.push([/** @type {PluginCreator} */ (require(plugin)), {}]);
161
176
  } else {
162
- /** @type {MutableOptions} */ (options).preset.plugins.push([
163
- /** @type {PluginCreator} */ (plugin),
164
- {},
165
- ]);
177
+ nanoPlugins.push([/** @type {PluginCreator} */ (plugin), {}]);
166
178
  }
167
179
  }
168
180
  }
169
181
  const plugins = [];
170
- const nanoPlugins = resolveConfig(options);
171
182
  for (const nanoPlugin of nanoPlugins) {
172
183
  if (Array.isArray(nanoPlugin)) {
173
184
  const [processor, opts] = nanoPlugin;
@@ -185,5 +196,7 @@ function cssnanoPlugin(options = {}) {
185
196
  return postcss(plugins);
186
197
  }
187
198
 
199
+ /** @type {true} */
188
200
  cssnanoPlugin.postcss = true;
189
- module.exports = cssnanoPlugin;
201
+
202
+ export { cssnanoPlugin as default, cssnanoPlugin as 'module.exports' };
package/types/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- export = cssnanoPlugin;
2
- import postcss = require('postcss');
3
1
  export type PluginOptions = boolean | {
4
2
  exclude?: boolean;
5
3
  } | void | undefined;
@@ -18,9 +16,13 @@ export type Options = {
18
16
  configFile?: string;
19
17
  };
20
18
  /**
21
- * @type {import('postcss').PluginCreator<Options>}
22
19
  * @param {Options=} options
23
20
  * @return {import('postcss').Processor}
24
21
  */
25
- declare function cssnanoPlugin(options?: {}): postcss.Processor;
22
+ declare function cssnanoPlugin(options?: Options | undefined): import('postcss').Processor;
23
+ declare namespace cssnanoPlugin {
24
+ var _a: true;
25
+ export { _a as postcss };
26
+ }
27
+ export { cssnanoPlugin as default, cssnanoPlugin as 'module.exports' };
26
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"SA4LiB,aAAa;OA1LxB,OAAO,WAAW,SAAS;AAM7B,YAA8D,aAAa,GAAjE,OAAO,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAe;AAC3E,YAAgD,aAAa,GAAnD,OAAO,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAe;AAC7D,YAA0C,YAAY,GAA5C,CAAC,aAAa,EAAE,aAAa,CAAC,CAAc;AACtD,YAA0D,aAAa,GAA7D,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK;IAAE,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAe;AACvE,YAAmG,UAAU,GAAnG,MAAM,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAY;AAC7G,YAAsE,UAAU,GAAtE,MAAM,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC,CAAY;AAChF,YAAgF,OAAO,GAA7E;IAAE,MAAM,CAAC,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAS;AA6G3F;;;;GAIG;AACH,iBAAS,aAAa,CAAC,OAAO,KAAK,qBAyDlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAUI,YAA8D,aAAa,GAAjE,OAAO,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAe;AAC3E,YAAgD,aAAa,GAAnD,OAAO,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAe;AAC7D,YAA0C,YAAY,GAA5C,CAAC,aAAa,EAAE,aAAa,CAAC,CAAc;AACtD,YAA0D,aAAa,GAA7D,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK;IAAE,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAe;AACvE,YAAmG,UAAU,GAAnG,MAAM,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAY;AAC7G,YAAsE,UAAU,GAAtE,MAAM,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC,CAAY;AAChF,YAAgF,OAAO,GAA7E;IAAE,MAAM,CAAC,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAS;AAyI3F;;;GAGG;AACH,iBAAS,aAAa,CAAC,OAAO,AAH3B,CACA,EADQ,OAAO,YAGiB,GAFvB,OAAO,SAAS,EAAE,SAAS,CAyCtC;kBAvCQ,aAAa;YAyCX,IAAI;;;AAGf,OAAO,EAAE,aAAa,IAAI,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,CAAC"}