1


I am setting up a brand new project in Express using Babel and ESLint, and am trying to setup dynamic routes. The only issue is that I cannot figure out how to call the loader for the routes. This is my current code regarding the loader.

routes/index.js

import fs from 'fs';

/**
 * Register Default Routes
 * @param {Object} app express.Application
 */
export default function(app) {
    fs.readdirSync(__dirname).forEach((fileName) => {
        if (fileName == __filename.slice(__dirname.length + 1)) return;
        let fileNameStripped = fileName.substring(0, fileName.lastIndexOf('.'));
        require('./' + fileNameStripped)(app); // does not work
    });
}

index.js

import express from 'express';
import routes from './routes/index.js';

const app = express();

app.use(express.static('public'));

routes(app); // works now

...

Babel Error

TypeError: require(...) is not a function
    at /app/build/routes/index.js:1:314
    at Array.forEach (<anonymous>)
    at exports.default (/app/build/routes/index.js:1:195)
    at Object.<anonymous> (/app/build/index.js:1:393)    
    at Module._compile (module.js:649:30)
    at Object.Module._extensions..js (module.js:660:10)
    at Module.load (module.js:561:32)
    at tryModuleLoad (module.js:501:12)
    at Function.Module._load (module.js:493:3)
    at Function.Module.runMain (module.js:690:10)

The issue appears to be related to https://github.com/babel/babel/issues/2683

  • This was based off of https://stackoverflow.com/questions/29923879/pass-options-to-es6-module-imports, although it did not work. –  Mar 19 '18 at 12:45
  • 1
    It's unclear what the problem is. Does the code above not work for you, and if it doesn't, what's wrong with it? I don't see why it's important that it's an import. It's a function that can accept an argument, imported or not. – Estus Flask Mar 19 '18 at 12:48
  • This issue is that the function is not called, the one in routes/index.js and index.js –  Mar 19 '18 at 12:50
  • 1
    Well, it should, because you call it. If there are problems, there should be errors. Currently nobody but you can debug it. Consider providing http://stackoverflow.com/help/mcve that can replicate the problem - a repo, online service or else. Otherwise the question is considered off-topic. – Estus Flask Mar 19 '18 at 13:02
  • Alright, editing.. –  Mar 19 '18 at 13:50
  • You haven't posted nested route files. But I guess they use ES module `default` exports too, so `require('./' + fileNameStripped)` is module object, and it should be `require('./' + fileNameStripped).default(app)`. – Estus Flask Mar 19 '18 at 14:07
  • Thanks @estus, can you create a answer with the content from the comment above this as it solved my issue. –  Mar 19 '18 at 14:53

1 Answers1

0

Since nested route files are supposed to be ES modules with default exports, require('./' + fileNameStripped) is module object and not a function. It should be:

require('./' + fileNameStripped).default(app);

Depending on Babel configuration (dynamic-import-node plugin is required), require() can be replaced with dynamic import() but it's less desirable here, because dynamic import is not synchronous and can cause race conditions.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565