madge icon indicating copy to clipboard operation
madge copied to clipboard

Not working with React.Lazy

Open cyrus-za opened this issue 6 years ago • 2 comments

When using React.lazy madge still loads it as a circular module. Yes the file does depeend on it, but not on initial load so surely this should not count as a circular dependency as this is in fact the way to solve circular dependencies.

Consider the code below

import React from 'react'

export default {
	home: {
		path: '/',
		name: 'Home',
		component: React.lazy(() => import('../containers/Home')),
	},
	not_found: {
		path: '*',
		name: 'Page Not Found',
		component: React.lazy(() => import('../containers/NotFound')),
	},
	login: {
		path: '/login',
		name: 'Login',
		component: React.lazy(() => import('../containers/App/Welcome')),
	},
}

Running madge --circular ./src/index.js returns

1) router/routes.js > containers/Home.js
2) router/routes.js > containers/NotFound.js
3) router/routes.js > containers/App/Welcome.js

The components import routes.js to load the route to redirect to upon events (e.g. after login redirect to home), but the only import statement at the top of routes.js is importing React. The rest are imported with React.lazy and should surely not count when building the tree of circular dependencies.

cyrus-za avatar Jul 08 '19 14:07 cyrus-za

I had the same issue.

I was able to circumvent the problem by putting all Lazy import inside a specific file (LazyComponents.ts for instance) which exports everything, importing the relevant lazy components where needed, then excluding this file from Madge analysis.

So in your case, for instance, you could have a LazyComponents.ts:

import React from 'react'

export const LazyHome = React.lazy(() => import('../containers/App/Home'));
// ...

Then update your original file to import as needed:

import { LazyHome } from LazyComponents;

export default {
	home: {
		path: '/',
		name: 'Home',
		component: LazyHome,
	},
	// ...
}

Then ignore module when calling Madge:

npx madge --exclude "LazyComponents'" --circular .\Src

The nice thing is that you have all your lazy components in one place, which is easier to manage the different chunks and such.

Of course, this only works and scale if you only put the Lazy components in this file. Nothing else should be defined here, since it won't be picked up by Madge.

Indigo744 avatar Jun 22 '20 16:06 Indigo744

I think this is covered by dynamic import #157 . Will try to work on this later.

PabloLION avatar Jan 29 '23 08:01 PabloLION