Skip to content

Instantly share code, notes, and snippets.

@edwinwright
Forked from sfrieson/circ-dep-plugin-config.js
Created November 30, 2021 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edwinwright/d0244ac383536bdea66ab75b1e5d5339 to your computer and use it in GitHub Desktop.
Save edwinwright/d0244ac383536bdea66ab75b1e5d5339 to your computer and use it in GitHub Desktop.
Custom configuration around the circular-dependency-plugin to help avoid new ones.
const CircularDependencyPlugin = require('circular-dependency-plugin');
const CIRC_DEP_MAX = 238;
const defaultConfig = {
aggregateDirDepth: 2,
exclude: /node_modules/,
include: /.*/,
logWarnings: true,
logErrors: true,
logSubsequentRuns: false
};
module.exports = function create(userConfig) {
const config = { ...defaultConfig, ...userConfig };
const state = {
chains: new Set(),
chainRoots: {},
firstRun: true,
};
return new CircularDependencyPlugin({
onStart() {
console.log(' -- DETECTING CIRCULAR DEPENDENCIES -- ');
this.run = {
count: 0,
fileCounts: {}
};
},
onDetected({ paths, compilation }) {
const chain = paths.join(' -> ');
// First pass collect the chains
if (!config.exclude.test(paths[0]) && config.include.test(paths[0])) {
this.run.count++;
// Aggregate counts by directory
const root = paths[0].split('/').slice(0, config.aggregateDirDepth).join('/');
if (!state.chainRoots[root]) state.chainRoots[root] = 0;
state.chainRoots[root]++;
// count paths
paths.forEach(path => {
if (!this.run.fileCounts[path]) this.run.fileCounts[path] = 0;
this.run.fileCounts[path]++;
});
if (state.firstRun) state.chains.add(chain);
if ((state.firstRun || config.logSubsequentRuns) && config.logWarnings) compilation.warnings.push(new Error(chain));
// Error if a new one is added after the first run.
if (!state.firstRun && !state.chains.has(chain) && config.logErrors) compilation.errors.push(`New circular dependency detected.\n${chain}`);
}
},
onEnd({ compilation }) {
const warnings = [
'Circular Dependencies plugin.',
`There are ${this.run.count} circular dependencies.`
];
if (state.firstRun && this.run.count) {
warnings.push('Count | Directory');
warnings.push(Object.keys(state.chainRoots)
.map(key => [state.chainRoots[key], key])
.sort((a, b) => b[0] - a[0])
.map(([count, curPath]) => `${count.toString().padStart(5, ' ')} | ${curPath}`)
.join('\n'));
}
compilation.warnings.push(warnings.join('\n'));
if (this.run.count > CIRC_DEP_MAX) {
compilation.errors.push([
'Circular Dependencies Plugin',
`Count of circular dependencies (${this.run.count}) is above the max allowed (${CIRC_DEP_MAX}). You likely introduced one with your code change.`,
].join('\n'));
}
state.firstRun = false;
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment