alias-hq icon indicating copy to clipboard operation
alias-hq copied to clipboard

Jest plugin does not properly handle modules in parent dir

Open chrissantamaria opened this issue 3 years ago • 4 comments

👋 big fan of this package! Ran into a subtle issue in my (unconventional) repo structure.

Problem

Consider this highly simplified and somewhat contrived example:

.
├── README.md
├── app
│   ├── jest.config.js
│   ├── package.json
│   └── src
│       └── index.test.js
├── jest.config.js
├── jsconfig.json
├── package.json
├── src
│   ├── index.test.js
│   └── utils
│       └── some-util.js
└── yarn.lock

The bulk of the code lives in src, though there's also an app directory which functionally is its own package. However, it does share modules (and aliases) with src. Consider this jsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "@utils/*": ["./src/utils/*"],
      "@app/*": ["./app/src/*"]
    }
  }
}

Both the top-level package and app have their own set of tests and corresponding jest.config.js files. In the top-level config, I would expect (and do correctly get!) the following moduleNameMapper value generated by alias-hq:

{
  '^@utils/(.*)$': '<rootDir>/src/utils/$1',
  '^@app/(.*)$': '<rootDir>/app/src/$1'
}

Likewise for app, I would expect this in its config (app/jest.config.js):

{
  '^@utils/(.*)$': '<rootDir>/../src/utils/$1',
  '^@app/(.*)$': '<rootDir>/../app/src/$1'
}

However, I instead get this:

{
  '^@utils/(.*)$': 'src/utils/$1',
  '^@app/(.*)$': 'app/src/$1'
}

Root cause

This seems to be due to the Jest plugin's implementation using path.join: https://github.com/davestewart/alias-hq/blob/dfb0446a1af3d8eb2e44cb14ae66a26de7347837/src/plugins/jest/index.js#L16

When baseUrl is .., join removes the <rootDir> segment entirely. However, in this case (I think) we always want that to exist. Paths like <rootDir>/../src/utils/$1 resolve just fine with Jest's parser.

I've created a reproduction repo matching this described case for easier testing. I also have a branch up which (from what I can tell) fixes the issue - happy to open a PR if you think this is sufficient.

Possible misconfiguration

I wasn't entirely sure how to configure alias-hq for this sort of situation. I did the following in app/jest.config.js:

const {
  get: getModuleAliases,
  config: aliasConfig,
  load: loadAliasConfig,
} = require('alias-hq');
const path = require('path');

loadAliasConfig(path.resolve('../jsconfig.json'));
aliasConfig.baseUrl = '..';

module.exports = {
  roots: ['<rootDir>/src'],
  moduleNameMapper: getModuleAliases('jest'),
};

(I think) I had to manually point to jsconfig.json since it's not in a standard location relative to this config. I also manually set a baseUrl so that paths would be set relative to the parent dir. Still fairly new to this package so please let me know if there's a better / simpler way to configure this!

Happy to clarify any details - thanks!

chrissantamaria avatar Feb 20 '22 19:02 chrissantamaria

Hey! Sorry for the delay in seeing this.

Thanks for the detailed issues; I'll be able to take a look in a couple of days.

davestewart avatar Feb 27 '22 19:02 davestewart

Hey FYI I was able to just use the webpack plugin instead of the jest one in my jest.config file and seems to work fine that way.

jensbodal avatar Mar 22 '22 18:03 jensbodal

Hi! Sorry for the bump but just wanted to check in on the status of this. I think my branch may fix the issue, so I'd be happy to open a PR if you'd like and we can go from there. Thanks!

chrissantamaria avatar May 18 '22 19:05 chrissantamaria

Hey Chris!

Sorry to miss this, I've been a bit busy. Have a list of things to get to, so let me review this, add you to the list and let you know at what position of the queue you will be in!

One moment, caller...

davestewart avatar May 22 '22 18:05 davestewart

Blimey, I'm useless at picking up PRs at the moment. Sorry.

davestewart avatar Nov 23 '22 17:11 davestewart