add cleanOmittedPaths to safely filter rspack config paths

This commit is contained in:
Nacho Codoñer
2025-08-21 17:55:58 +02:00
parent fe045b15e9
commit a732ead29f
2 changed files with 102 additions and 3 deletions

View File

@@ -173,6 +173,85 @@ export function unique(key, pluginNames = [], getter = item => item.constructor
};
}
/**
* Helper function to clean fields in an object based on omit paths.
* Supports nested path strings like 'output.filename'.
*
* @param {Object} obj - The object to clean
* @param {Object} options - Configuration options
* @param {string[]} [options.omitPaths] - Paths to omit from the object (e.g., 'output.filename')
* @param {Function} [options.warningFn] - Custom warning function that receives the path string
* @returns {Object} The cleaned object with specified paths removed
*/
export function cleanOmittedPaths(obj, options = {}) {
if (!obj || typeof obj !== 'object') {
return obj;
}
const { omitPaths = [], warningFn } = options;
// If no omit paths, return the original object
if (!omitPaths.length) {
return obj;
}
const result = { ...obj };
// Process each omit path
omitPaths.forEach(path => {
// Convert path to array of keys
const pathArray = Array.isArray(path) ? path : path.split('.');
const pathString = Array.isArray(path) ? path.join('.') : path;
// Start with the root object
let current = result;
let parent = null;
let lastKey = null;
// Traverse the path to find the target property
for (let i = 0; i < pathArray.length - 1; i++) {
const key = pathArray[i];
if (current && typeof current === 'object' && key in current) {
parent = current;
lastKey = key;
current = current[key];
} else {
// Path doesn't exist in the object, nothing to remove
return;
}
}
// Get the final key in the path
const finalKey = pathArray[pathArray.length - 1];
// Handle single-level paths (from root)
if (pathArray.length === 1) {
const rootKey = pathArray[0];
if (rootKey in result) {
// Log warning
if (typeof warningFn === 'function') {
warningFn(pathString);
}
delete result[rootKey];
}
return;
}
// If we found the property for nested paths, remove it
if (parent && lastKey && finalKey) {
if (current && typeof current === 'object' && finalKey in current) {
// Log warning
if (typeof warningFn === 'function') {
warningFn(pathString);
}
delete current[finalKey];
}
}
});
return result;
}
/**
* Merges webpack/rspack configs with smart handling of overlapping rules.
*

View File

@@ -5,7 +5,7 @@ import { inspect } from 'node:util';
import path from 'path';
import { merge } from 'webpack-merge';
import { mergeSplitOverlap } from './lib/mergeRulesSplitOverlap.js';
import { cleanOmittedPaths, mergeSplitOverlap } from "./lib/mergeRulesSplitOverlap.js";
import { getMeteorAppSwcConfig } from './lib/swc.js';
import CleanBuildAssetsPlugin from './plugins/CleanBuildAssetsPlugin.js';
import HtmlRspackPlugin from './plugins/HtmlRspackPlugin.js';
@@ -425,11 +425,31 @@ export default function (inMeteor = {}, argv = {}) {
? projectConfig(Meteor, argv)
: projectConfig;
const omitPaths = [
'name',
'target',
'entry',
'output.path',
'output.filename',
'output.publicPath',
];
const warningFn = path => {
console.warn(
`[rspack.config.js] Ignored custom "${path}" — reserved for Meteor-Rspack integration.`,
);
};
if (Meteor.isClient) {
clientConfig = mergeSplitOverlap(clientConfig, userConfig);
clientConfig = mergeSplitOverlap(
clientConfig,
cleanOmittedPaths(userConfig, { omitPaths, warningFn }),
);
}
if (Meteor.isServer) {
serverConfig = mergeSplitOverlap(serverConfig, userConfig);
serverConfig = mergeSplitOverlap(
serverConfig,
cleanOmittedPaths(userConfig, { omitPaths, warningFn }),
);
}
}