Skip to content

Add functions in other folder, to an object in this folder

I want to create an object that would import functions from another folder and it would look something like this:

class = {
  functions: {
    //All functions here
  }
}

The functions would be inside of a different folder, however, I want to make some sort of importer in which it would make new classes for each new function/file it finds inside of the folder.

someFunction.js Function File:

function someFunction() {
   console.log("this is some function");
}

So I would like for something to look like this:

class.functions.someFunction()

No, I do not want to have it hard coded into the object, I want to import all functions from a folder and create functions like that.

Answer

Well, first I wan’t to answer your question as I think you want, even if I also think it is not the correct way to proceed.

I’ll also assume that with class you are not referring to an actual ES6 Class, but we are talking about a plain object.

So this is the code:

const fs = require('fs');
const path = require('path');

function importer(dirPath) {
    const absoluteDirPath = path.normalize(
        path.isAbsolute(dirPath)
            ? dirPath
            : path.resolve(process.cwd(), dirPath)
    );

    const output = {
        functions: {}
    };

    const content = fs.readdirSync(path.normalize(absoluteDirPath));

    content.forEach((basename) => {
        const absoluteItemPath = path.join(absoluteDirPath, basename);

        if (fs.statSync(absoluteItemPath).isFile() && /.js$/i.test(basename)) {
            output.functions[basename.slice(-3)] = require(path.relative(
                __dirname,
                absoluteItemPath
            ));
        }
    });

    return output;
}

module.exports = importer;

For this to work, all your functions in your files should be exported like:

module.exports = function myFunction() {};

To use the ‘importer’, you just do:

const artemis = importer('/path/to/directory'); // PATH MUST BE ABSOLUTE OR RELATIVE TO CWD.

/*
SUPPOSING THAT YOUR DIRECTORY CONTAINS THE FOLLOWING FILES:

function1.js
function2.js

Then you can do:

artemis.function1();
artemis.function2();

Please note that your files must be named in a JS friendly way (a valid string for an object key).

*/

A final important note about this odd method: This will only ever work in a NodeJS environment. Even if functions could have worked in other environments (like a browser). The next method, will work for any ECMAScript environment after proper building process: transpilation (EX: Babel) and bundling (EX: Webpack).


Suggested Solution

Use ES6 Static import / export like modern JS libraries do. This comes with huge benefits, from static code analysis to tree shaking and more.

Let’s suppose the following hierarchy:

//  - index.js
//  - internals/
//    - index.js
//    - module-1.js
//    - module-2.js

internals/module-1.js

function module1() {}

export {module1};

internals/module-2.js

import {module1} from 'module-1.js';

function module2() {
  // YOU CAN USE module1 IF YOU NEED. (AVOID CIRCULAR REFERENCES)
  module1();
}

export {module2};

internals/index.js

import {module1} from './module-1.js';
import {module2} from './module-2.js';

export {module1, module2};

index.js

import * as moduleGroup from './internals/index.js';

export {moduleGroup};

Finally, where you import your moduleGroup, you can do:

moduleGroup.module1();
moduleGroup.module2();

Obviously this is a basic scenario, but this is, IMHO, the correct way to deliver a group of functions and other stuff. Please let me know if you have any doubt.