source: trip-planner-front/node_modules/circular-dependency-plugin/index.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 4.3 KB
Line 
1let path = require('path')
2let extend = require('util')._extend
3let BASE_ERROR = 'Circular dependency detected:\r\n'
4let PluginTitle = 'CircularDependencyPlugin'
5
6class CircularDependencyPlugin {
7 constructor(options) {
8 this.options = extend({
9 exclude: new RegExp('$^'),
10 include: new RegExp('.*'),
11 failOnError: false,
12 allowAsyncCycles: false,
13 onDetected: false,
14 cwd: process.cwd()
15 }, options)
16 }
17
18 apply(compiler) {
19 let plugin = this
20 let cwd = this.options.cwd
21
22 compiler.hooks.compilation.tap(PluginTitle, (compilation) => {
23 compilation.hooks.optimizeModules.tap(PluginTitle, (modules) => {
24 if (plugin.options.onStart) {
25 plugin.options.onStart({ compilation });
26 }
27 for (let module of modules) {
28 const shouldSkip = (
29 module.resource == null ||
30 plugin.options.exclude.test(module.resource) ||
31 !plugin.options.include.test(module.resource)
32 )
33 // skip the module if it matches the exclude pattern
34 if (shouldSkip) {
35 continue
36 }
37
38 let maybeCyclicalPathsList = this.isCyclic(module, module, {}, compilation)
39 if (maybeCyclicalPathsList) {
40 // allow consumers to override all behavior with onDetected
41 if (plugin.options.onDetected) {
42 try {
43 plugin.options.onDetected({
44 module: module,
45 paths: maybeCyclicalPathsList,
46 compilation: compilation
47 })
48 } catch(err) {
49 compilation.errors.push(err)
50 }
51 continue
52 }
53
54 // mark warnings or errors on webpack compilation
55 let error = new Error(BASE_ERROR.concat(maybeCyclicalPathsList.join(' -> ')))
56 if (plugin.options.failOnError) {
57 compilation.errors.push(error)
58 } else {
59 compilation.warnings.push(error)
60 }
61 }
62 }
63 if (plugin.options.onEnd) {
64 plugin.options.onEnd({ compilation });
65 }
66 })
67 })
68 }
69
70 isCyclic(initialModule, currentModule, seenModules, compilation) {
71 let cwd = this.options.cwd
72
73 // Add the current module to the seen modules cache
74 seenModules[currentModule.debugId] = true
75
76 // If the modules aren't associated to resources
77 // it's not possible to display how they are cyclical
78 if (!currentModule.resource || !initialModule.resource) {
79 return false
80 }
81
82 // Iterate over the current modules dependencies
83 for (let dependency of currentModule.dependencies) {
84 if (
85 dependency.constructor &&
86 dependency.constructor.name === 'CommonJsSelfReferenceDependency'
87 ) {
88 continue
89 }
90
91 let depModule = null
92 if (compilation.moduleGraph) {
93 // handle getting a module for webpack 5
94 depModule = compilation.moduleGraph.getModule(dependency)
95 } else {
96 // handle getting a module for webpack 4
97 depModule = dependency.module
98 }
99
100 if (!depModule) { continue }
101 // ignore dependencies that don't have an associated resource
102 if (!depModule.resource) { continue }
103 // ignore dependencies that are resolved asynchronously
104 if (this.options.allowAsyncCycles && dependency.weak) { continue }
105 // the dependency was resolved to the current module due to how webpack internals
106 // setup dependencies like CommonJsSelfReferenceDependency and ModuleDecoratorDependency
107 if (currentModule === depModule) {
108 continue
109 }
110
111 if (depModule.debugId in seenModules) {
112 if (depModule.debugId === initialModule.debugId) {
113 // Initial module has a circular dependency
114 return [
115 path.relative(cwd, currentModule.resource),
116 path.relative(cwd, depModule.resource)
117 ]
118 }
119 // Found a cycle, but not for this module
120 continue
121 }
122
123 let maybeCyclicalPathsList = this.isCyclic(initialModule, depModule, seenModules, compilation)
124 if (maybeCyclicalPathsList) {
125 maybeCyclicalPathsList.unshift(path.relative(cwd, currentModule.resource))
126 return maybeCyclicalPathsList
127 }
128 }
129
130 return false
131 }
132}
133
134module.exports = CircularDependencyPlugin
Note: See TracBrowser for help on using the repository browser.