Rich Harris edited this page Aug 19, 2015 · 2 revisions

You'll often hear people tell you that cyclical dependencies are a symptom of a badly architected codebase. That's rubbish - oftentimes you need cyclical dependencies to model your domain, particularly if you're modeling recursive structures.

So why do people say that? Because with AMD and CommonJS, getting cyclical dependencies to work can be a real challenge, resulting in hacktacular code. It becomes much easier with ES6:

// createObject.js
import createChildren from './createChildren';

export default function createObject ( numChildren ) {
  return {
    children: createChildren( numChildren )

// createChildren.js
import createObject from './createObject';

export default function createChildren ( i ) {
  var children = [];

  while ( i-- ) {
    children[i] = createObject( 0 );

  return children;

// app.js
import createObject from './createObject';

var contrivedExample = createObject( 42 );

Try doing that with AMD. Go on, I'll wait. You can do it in CommonJS, assuming that you know all the relevant hoisting rules, and when to use exports instead of module.exports, and where to put it inside your module...

Rollup will bundle those three modules (app.js, createObject.js and createChildren.js) into a single AMD/CommonJS/UMD file with no problem at all.