0

I'm looking to create an easy way for users to extend various services within a nodejs app. It uses electron, webpack, and babel.

I found a handy way to dynamically require every file in a given folder:

// At the top of my class file
const thing_files = require.context('./things', false, /\.js$/)

// In my class constructor
this.things = {};

thing_files.keys().forEach(key => {
    try {
        this.things[key.replace(/(\.\/|\.js)/g, '')] = thing_files(key).default; // edit: also tried default()
    } catch(err) {
        process.send({message:`unable to add thing ${key}`});
    }
});

This works great for files that look like the following:

export default {

    getName() {
        return 'thangythang';
    }
}

However, it doesn't work when I export a class:

import Thing from "../base-thing";

export default class extends Thing {

    constructor() {
        super();
    }

    getName() {
        return 'thangythang';
    }
}

Nor with a named class:

export default class ThingOne extends Thing {

These classes otherwise work well when I require them as expected:

const ThingOne = require('./things/thing-one')
var thing = new ThingOne.default();
process.send({message:`thing: ${thing.getName()}`}); // thing: thangythang

How can I work with them using webpack's require.context?

  • You're loading a `thing_files` context but then iterating `exchange_files`, is that a mistake? – loganfsmyth Jul 20 '17 at 19:02
  • A mistake in generic-ifying my post. I have 8 loaders that all look the same. –  Jul 20 '17 at 19:09
  • So if you inspect the object returned by `thing_files(key)` what do you see? Also, does it work if you comment out `import Thing from "../base-thing";` and remove `extends Thing`? – loganfsmyth Jul 20 '17 at 19:10
  • It returns `undefined` when I output it to the console. I haven't quite figured out how to inspect it since this is under a child process. –  Jul 20 '17 at 19:11
  • Cool. Try commenting out the stuff I mentioned, if that works I have a guess what the issue is. Also, do you mean `thing_files(key) === undefined` or `thing_files(key).default === undefined`? – loganfsmyth Jul 20 '17 at 19:12
  • `export default class ThingOne` with the `import` statement commented out still produces `undefined`. `thing_files(key)` is an `Object` while `thing_files(key).default === undefined`. –  Jul 20 '17 at 19:32

1 Answers1

0

After toying with various things, I realized that:

export default {}

Essentially assigns an Object to default, while export default class ThingOne does not. With that in mind, I changed my class file to the following:

import Thing from "../base-thing";

class ThingOne extends Thing {

    constructor() {
        super();
    }

    getName() {
        return 'thangythang';
    }
}


export default new ThingOne();

Which also worked. However, I wanted something more robust just in case I needed to pass parameters during construction, or create more than a single instance of the class. After playing around with alternative ways of instantiating a class, I came across a valid solution!

this.things[key.replace(/(\.\/|\.js)/g, '')] = new (thing_files(key).default)(/* args */);