13

I'm slowly transitioning from PHP to Node.js and was trying to find something similar to composer dumpautoload. Thanks to PSR-4, it's easy to get access to any class in any file in PHP when using this command with simple use statements at the beginning of each file.

npm seems to do a great job managing packages and dependencies but having the same flexibility within your own project would avoid creating require statements that can easily break if a file changes path.

Example of what I would be looking for - 2 files in the same folder:

Some testClass.js (class file)

var testClass = {
    sayHello: function () {
        console.log('this is a test');
    }
};

module.exports = testClass ;

Normally this is what you would put in another file index.js file:

var testClass = require('./testClass');

testClass.sayHello();

But imagine you could pre-index all your classes with some app or command (like PHP's composer dumpautoload and simply run this:

var testClass = require('testClass');

testClass.sayHello();

I couldn't find any solution that seems to achieve this.

Did I miss something?

Nicolas Bouvrette
  • 4,295
  • 1
  • 39
  • 53
  • So you want auto-import your classes and constants without the explicit declaration of import/require statements? – Ruslan Zaytsev Aug 27 '18 at 23:35
  • Not exactly, but register unique names to add using require but on local classes. So if you create a "session" project module you could simply require it using the name "session" without the path. – Nicolas Bouvrette Aug 28 '18 at 00:09
  • There are no namespaces in JS and thus no autoloading. *require statements that can easily break if a file changes path* - use IDE to refactor filenames. – Estus Flask Aug 28 '18 at 00:32
  • So I just added more comments, while I understand that some IDEs could help refactor folder paths - is this the standard? I've seen a few threads talking about `require` gone wrong, especially using relative paths. Why can't project have the equivalent of an `npm` to manage local dependencies? – Nicolas Bouvrette Aug 28 '18 at 01:01
  • I get around "require hell" by using the registry pattern and pass that around `module.exports = app => { return testClass; }`. You find that once basics are passed around its only the specifics that need requiring. – Lawrence Cherone Aug 28 '18 at 01:14
  • @LawrenceCherone could you provide examples? Unless I misunderstand, you still need to require all file manually to get the registry populated? – Nicolas Bouvrette Aug 28 '18 at 02:09
  • You manually add `use` in php, so your still defining whats used, I dont see how its diff from require. The point I was making is you dont need to add the entire framework into every file. – Lawrence Cherone Aug 28 '18 at 02:15
  • Yes, you use `use` but you don't have to specify a path which is my main concern. By pre-indexing available local dependency, your `use` call becomes the equivalent of a `require` but using an official npm module (but local). This way you can easily move your files around without having to worry where the dependencies are. – Nicolas Bouvrette Aug 28 '18 at 02:20

2 Answers2

9

Edit December 2020

Yarn2 did release a feature called Plug'n'Play which seems to mimic PHP's autoloader: https://yarnpkg.com/features/pnp

It is known to have issues with some packages but I have not tested it myself.


The short answer is: No

For more details, continue reading:

There are two major challenges around the current way require or import currently work:

  1. Relative paths are hard to read and can become confusing when using files with the same name.
  2. Developers must heavily rely on IDEs to refactor their code or to find where a file is when inside another file.

While PHP seems to have developed its own standard and is a bit in its own league, even if someone would develop an equivalent solution to achieve the same for Node.js/JavaScript, we would still need good IDE support. To get good IDE support, this type of change would either:

  1. Need to be transparent and integrate to the way IDEs currently work.
  2. Be a change that is driven by the community itself (either require or import changes that can support absolute paths)

There are several answers here (https://gist.github.com/branneman/8048520) and they all seem to break IDE support (I only tested with WebStorm):

  1. Using aliases or prepending the path with variables: Breaks IDE support for autocomplete and renaming/refactoring.
  2. Using NODE_PATH as root path: Breaks IDE support for autocomplete and renaming/refactoring.
  3. Wrapping require to support /: Breaks IDE support when renaming/refactoring.
  4. Creating a new custom method: Breaks IDE support for autocomplete.

Overall, given that IDE support take precedence over code readability, it looks like there is no good way to implement changes to the current dependency management using Node.js without having the community behind such change.

Nicolas Bouvrette
  • 4,295
  • 1
  • 39
  • 53
2

While not exactly like PHP, it is similar and very handy. I like this package. It is a bit older, but definitely in the right direction.

https://github.com/Specla/Autoloader

Then for database models if you are using Sequelize like I am it is pretty good. https://github.com/boxsnake/sequelize-autoload

Goddard
  • 2,863
  • 31
  • 37