Repository navigation
Add default init behavior: look for package.json in process.cwd() - #31
Conversation
- When running the node app with a node_modules that is linked from
somewhere else in the filesystem, the automatic registration
`requires('module-alias/register')` breaks, because it assumes
that the `module-alias` package is two levels above package.json.
However, another sensible default is to assume `package.json` is
in the Node process' current working directory ; this is usually
true when using a package manager (npm / yarn) to launch the app.
- Slightly refactored the init function so that it tries to find
package.json is three directories before bailing: the user-provided
path, the '../..' path and 'process.cwd()'. The last two are somewhat
redundant.
Signed-off-by: Sandrine Piriou <spiriou@pivotal.io>
ilearnio
left a comment
There was a problem hiding this comment.
Why not to detect the path before initializing module-alias and then pass it into init function?
| for (var i in candidatePackagePath) { | ||
| try { | ||
| base = candidatePackagePath[i] | ||
| npmPackage = require(base + '/package.json') |
There was a problem hiding this comment.
Please use nodePath.join here to avoid any cross-platform issues.
npmPackage = require(nodePath.join(base, 'package.json'))
| // Or that package.json is in the node process' current working directory (when | ||
| // running a package manager script, e.g. `yarn start` / `npm run start`) | ||
| var candidatePackagePath = [ | ||
| (options.base || '').replace(/\/package\.json$/, ''), |
There was a problem hiding this comment.
What if options.base is not defined? Then it will add '' to the candidatePackagePath array, so it will then call require with '/package.json' as an argument.
I would change it to
var basePath = options.base
? options.base.replace(/\/package\.json$/, '')
: nodePath.join(__dirname, '../..')
var candidatePackagePaths = [basePath]
if (basePath !== process.cwd()) {
candidatePackagePaths.push(process.cwd())
}
There was a problem hiding this comment.
Now that I re-read my code and your comment ; I'm thinking that if options.base is defined, we should use that and we should not even try to use process.cwd().
Thoughts ?
|
|
||
| if (typeof npmPackage !== 'object') { | ||
| throw new Error('Unable to read ' + packagePath) | ||
| throw new Error('Unable to read any of [' + candidatePackagePath.map(function(path) { return base + '/package.json'}).join(', ') + ']') |
There was a problem hiding this comment.
base inside of map function should be changed to path, also would be good to put the map function result into it's own line.
var pathsString = candidatePackagePaths.map(function(path) {
return nodePath.join(path, '/package.json')
}).join('\n ')
throw new Error('Unable to find package.json in:\n ' + pathsString + ']')
|
Thanks for all the feedback. Yes for now we initialize the module manually, we thought it'd be nice if we could auto-detect. I've changed the behavior to use options.base if defined (even if wrong); otherwise try the parent dir/process.cwd(). I've added a spec for process.cwd(), it's simple but a bit weird as I do a process.chdir(). However I have not added a spec for default settings in the parent directory. This would require importing module alias from somewhere else than the source itself... I was thinking of dynamically copying index.js to test/src/node_modules before running a test, importing that copy, testing, then deleting it. What do you think ? |
- Clean the error message - Use nodePath.join instead of manual path building - First stab at process.cwd() testing, by changing the working dir of the node process in the tests
|
|
||
| var candidatePackagePaths | ||
| if(options.base) { | ||
| candidatePackagePaths = [options.base.replace(/\/package\.json$/, '')] |
There was a problem hiding this comment.
Please wrap the options.base.replace(/\/package\.json$/, '') with nodePath.resolve, so it will fix the slashes to be cross-platform
|
|
||
| if (typeof npmPackage !== 'object') { | ||
| throw new Error('Unable to read ' + packagePath) | ||
| var pathString = candidatePackagePaths.join('\n, ') |
There was a problem hiding this comment.
Could you please swap \n and , in places, so it will look like .join(',\n ')
| // Or that package.json is in the node process' current working directory (when | ||
| // running a package manager script, e.g. `yarn start` / `npm run start`) | ||
| var candidatePackagePath = [ | ||
| (options.base || '').replace(/\/package\.json$/, ''), |
- Also, fix a typo in the error log
- To check the relative path lookup, index.js must be in a very specific location. This requires copying index.js before a test and importing that. - Requires some infrastructure change in the spec.js to handle importing the regular index.js and importing the copied one ; this means we re-require the module before each test.
|
I've taken your feedback into account and tried a few things. Some of them might be a bit bold.
Try commenting out either Cheers ! |
|
Hi Nick, Just a bump ... Have you had a chance to review the latest changes ? Sorry to ping you here, I'd just like to avoid having this PR too outdated :) Cheers ! |
|
Hey, sorry for so big delay. Very busy recently at my job since we have deadlines and a lot of stuff to do, so really not much time left for other stuff. I'll try to get my hands around it on weekend, maybe earlier |
|
Thanks for answering :) No worries, take your time, doesn't have to be this week-end ! |
|
Hello! Are you planning to merge this any time soon? I'm having the same problem when using this module in Docker 😞 |
|
Hey @ilearnio, It seems you haven't had much time to work on module-alias for a while. Would you be interested in some help ? It'd require to spend a bit of time to bring me up to speed on some things, maybe review a few PRs I do, but I'd love to contribute a bit more, triage issues, work on PRs, fix some outstanding issues (as much as I can, I am a bit busy as well). Let me know ! Again, sorry to contact you here, couldn't find another way :( |
|
@jlsan92 - take a look at : #43 (comment) ... The suggested fix might help. If it doesn't, maybe open another issue with additional details ? e.g. your package.json, your Dockerfile, logs, etc. |
|
Hey guys. Sorry for not being active in this project for a while, have crazy schedule at my work. Didn't have a normal weekend for long time. @Kehrlann It would be really great if you can help to make it better, because I will be busy next couple of weeks for sure. I can add you as a collaborator. But please make sure that the specs are covering well every new case, especially if it's someone else's PRs. This package has more than million of installs as of now so don't want to ruin anybody's site, or my personal projects haha 😄 |

We ran an issue with the default require('module-alias/register') because the node_modules in our prod environment was soft-linked to the current working directory.
Trying to load package.json from Node's current working directory does the trick, because we are running the app from a package manager ; so we added this as a possibility the init script will try out.
The no-argument init relies on the position of index.js in the filesystem, so it's tricky to test. And the default behavior currently has no test covering it - so we did not add a test.
Lines 147 and 148 seem redundant, you might want to have a look.