Search code examples
javascriptnode.jsrequirefs

NodeJS fs and require looking in different places


I am trying to loop through a directory and require every file in it. My code is working, but I was wondering why I had to modify the path in fs functions. (Code below stripped of useless info)

Folder structure:

project
|-- bin
|   `-- start
|-- modules
|   |-- file1.js
|   `-- file2.js
`-- package.json

/bin/start:

#!/usr/bin/env node

// Require dependencies
var fs = require('fs')

// Get modules
// NOTE: fs is looking in the project folder, but this file is in the bin folder
fs.readdir('./modules', function (err, files) {
  // Handle error
  if (err) {
    console.log(err)
    process.exit(1)
  }

  // Loop through files
  files.forEach(function (file, index) {
    // Get info about file
    fs.stat('./modules/' + file, function (err, stat) {
      // Handle error
      if (err) {
        console.log(err)
        process.exit(1)
      }

      // If it is a file
      if (stat.isFile()) {
        // NOTE: require is looking in the bin folder, and this file is in the bin folder
        require('../modules/' + file)
      }
    })
  })
})

package.json:

{
  "name": "modular-chat",
  "version": "1.0.0",
  "description": "A simple modular example of a chat application",
  "scripts": {
    "start": "node ./bin/start"
  },
  "author": "JoshyRobot",
  "license": "MIT"
}

Solution

  • require is a Node function. It's just that require uses __dirname as the basename when resolving relative paths rather than the current working directory which is also the result of process.cwd().

    You simply need to join __dirname to your relative paths before passing them to fs functions. Using using path.join(__dirname, '../modules') and path.join(__dirname, '../modules', file). Use these in your fs.readdir and fs.stat calls:

    fs.readdir(path.join(__dirname, '../modules'), function (err, files) {
    
    fs.stat(path.join(__dirname, '../modules', file), function (err, stat) {
    

    This makes both your fs calls and the require align so that the right files are loaded.


    It is also not that hard to do the reverse and make require load any path:

    Rather than require(path.join('../modules/', file)):

    require(path.join(process.cwd(), '../modules/', file))
    

    This works because require doesn't change absolute paths as it does with relative paths by prepending __dirname.