Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18.x, 20.x, 22.x, 24.x]
node-version: [20.x, 22.x, 24.x, 25.x]
webpack-version: [latest]

runs-on: ${{ matrix.os }}
Expand Down
17,789 changes: 8,387 additions & 9,402 deletions package-lock.json

Large diffs are not rendered by default.

29 changes: 9 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,48 +64,37 @@
"jest-worker": "^30.0.5",
"postcss": "^8.4.40",
"schema-utils": "^4.2.0",
"serialize-javascript": "^6.0.2"
"serialize-javascript": "^7.0.3"
},
"devDependencies": {
"@babel/cli": "^7.24.8",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@eslint/js": "^9.32.0",
"@eslint/markdown": "^7.0.0",
"@commitlint/cli": "^20.4.2",
"@commitlint/config-conventional": "^20.4.2",
"@parcel/css": "^1.8.3",
"@stylistic/eslint-plugin": "^5.2.2",
"@swc/css": "^0.0.28",
"@types/clean-css": "^4.2.11",
"@types/csso": "^5.0.4",
"@types/node": "^20.14.9",
"@types/serialize-javascript": "^5.0.4",
"babel-jest": "^30.0.5",
"clean-css": "^5.3.3",
"copy-webpack-plugin": "^13.0.0",
"copy-webpack-plugin": "^14.0.0",
"cross-env": "^7.0.3",
"cspell": "^8.13.1",
"cspell": "^9.7.0",
"css-loader": "^6.10.0",
"cssnano-preset-simple": "^4.0.0",
"csso": "^5.0.3",
"del": "^6.1.0",
"del-cli": "^5.1.0",
"esbuild": "^0.25.0",
"del-cli": "^7.0.0",
"esbuild": "^0.27.3",
"eslint": "^9.30.1",
"eslint-config-prettier": "^10.1.5",
"eslint-config-webpack": "^4.4.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-jsdoc": "^52.0.0",
"eslint-plugin-n": "^17.21.0",
"eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-unicorn": "^60.0.0",
"globals": "^16.3.0",
"husky": "^9.1.4",
"jest": "^30.0.5",
"lightningcss": "^1.25.1",
"lint-staged": "^15.2.8",
"lint-staged": "^16.3.1",
"memfs": "^4.11.1",
"mini-css-extract-plugin": "^2.9.0",
"npm-run-all": "^4.1.5",
Expand Down Expand Up @@ -141,6 +130,6 @@
}
},
"engines": {
"node": ">= 18.12.0"
"node": ">= 20.9.0"
}
}
39 changes: 20 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const {
/** @typedef {import("postcss").Stringifier} Stringifier */
/** @typedef {import("@jridgewell/trace-mapping").TraceMap} TraceMap */

// eslint-disable-next-line jsdoc/reject-any-type
/** @typedef {any} EXPECTED_ANY */

/**
* @typedef {Record<string, unknown>} CssNanoOptions
* @property {string=} configFile Configuration file path
Expand Down Expand Up @@ -58,8 +61,8 @@ const {
* @typedef {object} MinimizedResult
* @property {string} code Minimized code
* @property {RawSourceMap=} map Source map
* @property {Array<Error | ErrorObject| string>=} errors Errors
* @property {Array<Warning | WarningObject | string>=} warnings Warnings
* @property {(Error | ErrorObject | string)[]=} errors Errors
* @property {(Warning | WarningObject | string)[]=} warnings Warnings
*/

/**
Expand All @@ -77,7 +80,7 @@ const {

/**
* @template T
* @typedef {T extends any[] ? { [P in keyof T]?: InferDefaultType<T[P]> } : InferDefaultType<T>} MinimizerOptions
* @typedef {T extends EXPECTED_ANY[] ? { [P in keyof T]?: InferDefaultType<T[P]> } : InferDefaultType<T>} MinimizerOptions
*/

/**
Expand All @@ -96,7 +99,7 @@ const {

/**
* @template T
* @typedef {T extends any[] ? { [P in keyof T]: BasicMinimizerImplementation<T[P]> & MinimizeFunctionHelpers; } : BasicMinimizerImplementation<T> & MinimizeFunctionHelpers} MinimizerImplementation
* @typedef {T extends EXPECTED_ANY[] ? { [P in keyof T]: BasicMinimizerImplementation<T[P]> & MinimizeFunctionHelpers } : BasicMinimizerImplementation<T> & MinimizeFunctionHelpers} MinimizerImplementation
*/

/**
Expand All @@ -110,9 +113,9 @@ const {

/**
* @typedef InternalResult
* @property {Array<{ code: string, map: RawSourceMap | undefined }>} outputs - Outputs
* @property {Array<Warning | WarningObject | string>} warnings - Warnings
* @property {Array<Error | ErrorObject | string>} errors - Errors
* @property {{ code: string, map: RawSourceMap | undefined }[]} outputs - Outputs
* @property {(Warning | WarningObject | string)[]} warnings - Warnings
* @property {(Error | ErrorObject | string)[]} errors - Errors
*/

/** @typedef {undefined | boolean | number} Parallel */
Expand All @@ -137,7 +140,7 @@ const {
*/

/**
* @typedef {ProcessOptions | { from?: string, to?: string, parser?: string | Syntax | Parser, stringifier?: string | Syntax | Stringifier, syntax?: string | Syntax } } ProcessOptionsExtender
* @typedef {ProcessOptions | { from?: string, to?: string, parser?: string | Syntax | Parser, stringifier?: string | Syntax | Stringifier, syntax?: string | Syntax }} ProcessOptionsExtender
*/

/**
Expand Down Expand Up @@ -209,13 +212,13 @@ class CssMinimizerPlugin {
// https://github.com/mozilla/source-map#new-sourcemapconsumerrawsourcemap
return Boolean(
input &&
typeof input === "object" &&
input !== null &&
"version" in input &&
"sources" in input &&
Array.isArray(input.sources) &&
"mappings" in input &&
typeof input.mappings === "string",
typeof input === "object" &&
input !== null &&
"version" in input &&
"sources" in input &&
Array.isArray(input.sources) &&
"mappings" in input &&
typeof input.mappings === "string",
);
}

Expand Down Expand Up @@ -391,10 +394,8 @@ class CssMinimizerPlugin {
// https://github.com/nodejs/node/issues/19022

const cpus =
// eslint-disable-next-line n/no-unsupported-features/node-builtins
typeof os.availableParallelism === "function"
? // eslint-disable-next-line n/no-unsupported-features/node-builtins
{ length: os.availableParallelism() }
? { length: os.availableParallelism() }
: os.cpus() || { length: 1 };

return parallel === true || typeof parallel === "undefined"
Expand All @@ -419,7 +420,7 @@ class CssMinimizerPlugin {
* @param {Compiler} compiler Compiler
* @param {Compilation} compilation Compilation
* @param {Record<string, import("webpack").sources.Source>} assets Assets
* @param {{availableNumberOfCores: number}} optimizeOptions Optimize options
* @param {{ availableNumberOfCores: number }} optimizeOptions Optimize options
* @returns {Promise<void>} Promise
*/
async optimize(compiler, compilation, assets, optimizeOptions) {
Expand Down
30 changes: 16 additions & 14 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/** @typedef {import("./index.js").RawSourceMap} RawSourceMap */
/** @typedef {import("./index.js").MinimizedResult} MinimizedResult */
/** @typedef {import("./index.js").CustomOptions} CustomOptions */
/** @typedef {import("./index.js").EXPECTED_ANY} EXPECTED_ANY */
/** @typedef {import("postcss").ProcessOptions} ProcessOptions */
/** @typedef {import("postcss").Postcss} Postcss */

Expand Down Expand Up @@ -88,7 +89,7 @@ async function cssnanoMinify(
}

if (
/** @type {Error & {code: string}} */
/** @type {Error & { code: string }} */
(err).code === "ERR_REQUIRE_ESM" &&
importESM
) {
Expand Down Expand Up @@ -119,6 +120,7 @@ async function cssnanoMinify(
`Loading PostCSS "${postcssOptions.parser}" parser failed: ${
/** @type {Error} */ (error).message
}\n\n(@${name})`,
{ cause: error },
);
}
}
Expand All @@ -131,6 +133,7 @@ async function cssnanoMinify(
`Loading PostCSS "${postcssOptions.stringifier}" stringifier failed: ${
/** @type {Error} */ (error).message
}\n\n(@${name})`,
{ cause: error },
);
}
}
Expand All @@ -143,6 +146,7 @@ async function cssnanoMinify(
`Loading PostCSS "${postcssOptions.syntax}" syntax failed: ${
/** @type {Error} */ (error).message
}\n\n(@${name})`,
{ cause: error },
);
}
}
Expand Down Expand Up @@ -224,8 +228,7 @@ async function cleanCssMinify(input, sourceMap, minimizerOptions) {

const generatedSourceMap = result.sourceMap
? /** @type {RawSourceMap} */ (
// eslint-disable-next-line jsdoc/no-restricted-syntax
/** @type {any} */ (result.sourceMap).toJSON()
/** @type {EXPECTED_ANY} */ (result.sourceMap).toJSON()
)
: undefined;

Expand Down Expand Up @@ -349,10 +352,10 @@ esbuildMinify.supportsWorkerThreads = () => false;
*/
async function parcelCssMinify(input, sourceMap, minimizerOptions) {
const [[filename, code]] = Object.entries(input);
// eslint-disable-next-line jsdoc/no-restricted-syntax

/**
* @param {Partial<import("@parcel/css").TransformOptions<any>>=} parcelCssOptions Parcel CSS options
* @returns {import("@parcel/css").TransformOptions<any>} Built Parcel CSS options
* @param {Partial<import("@parcel/css").TransformOptions<EXPECTED_ANY>>=} parcelCssOptions Parcel CSS options
* @returns {import("@parcel/css").TransformOptions<EXPECTED_ANY>} Built Parcel CSS options
*/
const buildParcelCssOptions = (parcelCssOptions = {}) =>
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
Expand Down Expand Up @@ -394,10 +397,10 @@ parcelCssMinify.supportsWorkerThreads = () => false;
*/
async function lightningCssMinify(input, sourceMap, minimizerOptions) {
const [[filename, code]] = Object.entries(input);
// eslint-disable-next-line jsdoc/no-restricted-syntax

/**
* @param {Partial<import("lightningcss").TransformOptions<any>>=} lightningCssOptions Lightning CSS options
* @returns {import("lightningcss").TransformOptions<any>} Built Lightning CSS options
* @param {Partial<import("lightningcss").TransformOptions<EXPECTED_ANY>>=} lightningCssOptions Lightning CSS options
* @returns {import("lightningcss").TransformOptions<EXPECTED_ANY>} Built Lightning CSS options
*/
const buildLightningCssOptions = (lightningCssOptions = {}) =>
// Need deep copy objects to avoid https://github.com/terser/terser/issues/366
Expand Down Expand Up @@ -470,11 +473,10 @@ async function swcMinify(input, sourceMap, minimizerOptions) {
? result.errors.map((diagnostic) => {
const error = new Error(diagnostic.message);

// eslint-disable-next-line jsdoc/no-restricted-syntax
/** @type {any} */ (error).span = diagnostic.span;

// eslint-disable-next-line jsdoc/no-restricted-syntax
/** @type {any} */ (error).level = diagnostic.level;
/** @type {EXPECTED_ANY} */
(error).span = diagnostic.span;
/** @type {EXPECTED_ANY} */
(error).level = diagnostic.level;

return error;
})
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/cache-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`"cache" option should work with the "false" value for the "cache" option: assets 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/exclude-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`exclude option should match snapshot for a single RegExp value excluded1: assets 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/include-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`include option should match snapshot for a single RegExp value included1: assets 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/minimizerOptions-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`when applied with "minimizerOptions" option matches snapshot for "discardComments" option (disable): entry.css 1`] = `
"body{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/test-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`when applied with "test" option matches snapshot for a single "test" value (RegExp): assets 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`validation validation 1`] = `
"Invalid options object. Css Minimizer Plugin has been initialized using an options object that does not match the API schema.
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/warningsFilter-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`warningsFilter option should match snapshot for a "function" value: assets 1`] = `
{
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/worker.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`worker should emit error: error 1`] = `
[
Expand Down
2 changes: 1 addition & 1 deletion test/helpers/getErrors.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import normalizeErrors from "./normalizeErrors";

export default (stats) => normalizeErrors(stats.compilation.errors).sort();
export default (stats) => normalizeErrors(stats.compilation.errors).toSorted();
3 changes: 2 additions & 1 deletion test/helpers/getWarnings.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import normalizeErrors from "./normalizeErrors";

export default (stats) => normalizeErrors(stats.compilation.warnings).sort();
export default (stats) =>
normalizeErrors(stats.compilation.warnings).toSorted();
4 changes: 2 additions & 2 deletions test/helpers/normalizeErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ function removeCWD(str) {
}

/**
* @param {Array<Error>} errors Array of errors
* @returns {Array<string>} Normalized error messages
* @param {Error[]} errors Array of errors
* @returns {string[]} Normalized error messages
*/
export default (errors) =>
errors.map((error) =>
Expand Down
2 changes: 0 additions & 2 deletions test/minimizerOptions-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ describe('when applied with "minimizerOptions" option', () => {
});
new CssMinimizerPlugin({
minimizerOptions: {
// eslint-disable-next-line n/no-extraneous-require
preset: require.resolve("cssnano-preset-default"),
},
}).apply(compiler);
Expand All @@ -119,7 +118,6 @@ describe('when applied with "minimizerOptions" option', () => {
});
new CssMinimizerPlugin({
minimizerOptions: {
// eslint-disable-next-line n/no-extraneous-require
preset: require.resolve("cssnano-preset-default"),
},
}).apply(compiler2);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe("parallel option", () => {

const stats = await compile(compiler);

expect(Worker).toHaveBeenCalledTimes(0);
expect(Worker).not.toHaveBeenCalled();

expect(readAssets(compiler, stats, /\.css$/)).toMatchSnapshot("assets");
expect(getErrors(stats)).toMatchSnapshot("errors");
Expand Down
Loading
Loading