Created
December 30, 2019 20:39
-
-
Save sfrieson/274a82b50da3e63aa13f6844683d642e to your computer and use it in GitHub Desktop.
Custom configuration around the circular-dependency-plugin to help avoid new ones.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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