0

When trying to access a module I created util.js inside of a file where I use module.exports in webpack, it results in an empty object at build time. In the image below, my const utils = require(...) returns an empty object.

enter image description here

However, when I inspect my const utils = require(...) inside of my main script background-script.js , which doesn't use a module.exports, it's defined.

enter image description here

Problem Webpack doesn't seem to be resolving the require's inside the modules I'm using i'm exporting.

Project File Structure

  app
  ├──plugins
  │   ├── index.js (exports all my plugins)
  |   ├──plugin1
  |   │   ├── index.js (simply exports an object)
  |   |
  |   |──plugin2
  |       ├── index.js (simply exports an object)
  |
  |--utils.js
  |--background-script.js

app/background-script.js

  const utils = require('../../util.js');

app/utils.js

  const utils ={....};
  utils.plugins = require('./plugins/index.js');
  module.exports = utils;

plugins/index.js

  //require all `index.js` file from each plugin directory; works great.
  const context = require.context('.', true, /index\.js/);
  const requireAllPlugins = function(ctx) {
    const keys = ctx.keys();
    const values = keys.map(ctx);
    return values;
  }
  const allPlugins = requireAllPlugins(context);
  module.exports = [...allPlugins]; 

plugin1/index.js

  //utils is an empty object
  const utils = require('../../util.js');
  module.exports = {action: utils.renderBookmark}
Clifford Fajardo
  • 1,357
  • 1
  • 17
  • 28

1 Answers1

0

Answering my own question

Turns out the reason why my const utils = require('../../utils.js') inside app/plugins/plugin1/index.js was returning an empty object was because I had a circular/cyclic dependency defined. Basically, I was creating an infinite loop with the way I was requiring my modules. NodeJS handles in a very specific way; it returns an empty object. See this Stackoverflow answer here

  //app/background-script.js 
  const utils = require('../../util.js');
    |
    |
    ↓
  //app/utils.js
  const utils = {...}
  utils.plugins = require('./plugins/index.js');
    |
    |
    ↓
    //app/plugins/index.js
    const context = require.context('.', true, /index\.js/);
    const requireAllPlugins = function(ctx) {
      const keys = ctx.keys();
      const values = keys.map(ctx);
      return values;
    }
    const allPlugins = requireAllPlugins(context);
    module.exports = [...allPlugins];
    |
    |
    ↓
    //plugins/plugin1/index.js
    const utils = require('../../util.js'); 
    |    module.exports = {action: utils.renderBookmark}
    |
    ↓
  // app/utils.js
  const utils = {...}
      utils.plugins = require('./plugins/index.js'); //restarts the calls above again.
    |
    |
    ↓ Node detected a circular dependency, so instead of repeating these calls again, forever, return `{}` instead. This `{}` will become the
    value of `utils` inside `plugins/plugin1/index.js`

Circular dependencies usually are a result of bad code organization. To solve my issue, I removed

`require('./plugins/index.js');` from utils

This npm module webpack-cyclic-dependency-checker helped me find the cyclic dependency after I started sensing I had a cyclic dependency somewhere in my codebase.

Clifford Fajardo
  • 1,357
  • 1
  • 17
  • 28