ilearnio / module-alias

Register aliases of directories and custom module paths in Node
MIT License
1.76k stars 69 forks source link

How do I use this in `node_modules/` and prevent overrides? #28

Open Sawtaytoes opened 6 years ago

Sawtaytoes commented 6 years ago

I have multiple treed projects, but in this example, we'll say I have 2.

In my index.js, I have require('module-alias/register'). In the first project, module-alias works fine as this project is the base.

As soon as load up project 2 which has project 1 as a node module, now I run into problems. This is because of layering. It happens because project 1 and 2 share the same base directories and aliases.

One way this causes an issue is if project 2 doesn't preference project 1's index.js, it will error because it can't find those files in the base project. But if I load project 1's index.js, I run into a second problem where now project 2's files are overridden by project 1 since again, they're sharing the same base directories and aliases.

I had this same issue with another library: app-module-path; although, it handled it where project 2 overrode project 1. I relied on this overriding in the past, but I'm wanting to get away from the hacky nature of it.

I'd like to find a solution for my current predicament where '$utils' could reference either the current project or a project in node_modules/ depending on where the file is loaded. As a possible fix, I think module-alias would need to load _moduleAliases in any project require('module-alias/register') is called. This way, when a project uses module-alias in node_modules/ it doesn't cause layering issues.

ilearnio commented 6 years ago

module-alias is not designed to be used inside node-modules. You can see this in README.md

WARNING: This module should not be used in other npm modules since it modifies the default require behavior! It is designed to be used for development of final projects i.e. web-sites, applications etc.

I think it's possible to make some workaround but I don't think it's right

Sawtaytoes commented 6 years ago

I came up with a few ideas on how to fix this.

  1. I could alias my node_modules/ projects with $$$utils and $$utils to separate them, but that's super hacky.
  2. Set the alias to include the project name such as $fwk/utils, and $nm/utils. It allows me to precisely know which project I'm targeting, but the downside is I have to preface my short-hand with namespaces.
  3. Modify the underlying code. For this, I noticed when you create base in init(), we can do some magic here to pull a namespace value. This can optionally be added to the other API functions as well.

I'll create a pull request for the latter.

ilearnio commented 6 years ago

Maybe for your case you can use a custom callback handler? Like:

moduleAlias.addAlias('$utils', path => {
  if (path.startsWith(__dirname + '/node_modules/my-module')) {
    return __dirname + '/node_modules/my-module/utils'
  }
  return __dirname + '/utils'
})