-
Notifications
You must be signed in to change notification settings - Fork 459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(mapper): implement project mapper and tsconfig convenience mapper #1805
Conversation
Hi, thank you for this proposal. In general, I like the idea. FYI, you can even create a custom jest module resolver, the concrete example is from nrwl nx. Talking about the implementation, actually lots of things in your codes have been handled by TypeScript APIs, such as So if exposing helpers like Regarding to the new helper |
Okay, I think the e2e tests are fixed. If there are any more errors, I'll clean them up. I also updated the code to use the typescript API to load tsconfigs, but The only question that remains is: one big magic 'createModuleNameMapper' function, or keep them discrete and separate? We could create one function that accepts various args, including
We could just call the relevant moduleNameMappers accordingly based on what configuration information is available. What do you think? Also, we should update the docs once we've settled on the API. |
Pull Request Test Coverage Report for Build 5413
💛 - Coveralls |
I like this one. The new function can exist next to the old function and put warning message on the old function that it is deprecated and instruct users to use the new one. The deprecated one will be removed in v27. Or can go for complete replacement of the existing function with this new function ? The first choice seems to be safer. |
We can preserve the signature of the original function with the overloads I
listed, but the old name 'pathsToModuleNameMapper' becomes outdated. So I
agree, let's redirect 'pathsToModuleNameMapper' to the new function with
the deprecation message you mentioned, and then offer the
'tsConfigToModuleNameMapper' function as the newer, more intelligent
replacement. We can update the docs accordingly.
…On Wed, Jul 15, 2020 at 4:52 PM Ahn ***@***.***> wrote:
We could create one function that accepts various args, including
- paths object (as per old api),
- tsConfig object,
- dirname to search for tsConfig from, and
- path directly to tsconfig.
We could just call the relevant moduleNameMappers accordingly based on
what configuration information is available.
What do you think?
Also, we should update the docs once we've settled on the API.
I like this one.
The new function can exist next to the old function and put warning
message on the old function that it is deprecated and instruct users to use
the new one. The deprecated one will be removed in v27.
Or can go for complete replacement of the existing function with this new
function ?
The first choice seems to be safer.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1805 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABOXAMV5M3BX57PRV5AR3LLR3WYDFANCNFSM4OZ56K3Q>
.
|
Yes let’s do that way for smoother migration |
Hi, I think the way Ideally, if |
Well... the thing is that if I don't use That leads me to believe that Module name mapper solves the problem, because I'm able to consider |
I'm actually noticing that this mapper doesn't work in all cases. For some reason, it only works when If I disable This matches the error that I get when I run To correctly compile project references, however, I'm not sure what the correct path forward here is. I'm starting to think project references aren't the greatest idea. |
Your work here can be actually reused partially for fixing #1698 so it is still quite helpful to me :) |
No worries, I'm glad it helped! I hope we have a more comprehensive solution to all this soon! |
I checked A new feature can be that, when compiling To alter the final output from compiler, for now I know that only AST transformers can do it. I'm not sure if TypeScript has an API for that without the need of AST transformers. |
In Angular there is a transformer seem to do things like that https://github.com/angular/angular/blob/d1ea1f4c7f3358b730b0d94e65b00bc28cae279c/packages/compiler-cli/src/ngtsc/transform/src/alias.ts Assume it works for normal cases, the rest is about gathering the correct paths configuration for project references This feature can be separated into 2 steps: first make it work without project references. The next phase is support project t references. If you are interested to help, PR is welcome :) |
I don't think that moduleNameMapper is necessarily a bad solution for this... Let me think out loud for a little bit... Obviously it would be handier to not have to use it... But the way I look at it, for a normal typescript build, e.g. in Now Only we don't want to have to run So actually, the moduleNameMapper would probably end up doing duplicate work, since Yeah, I think if ts-jest could use a transformer to map the project package references to its own build output, that would really be the cleanest solution! |
Ah great! If there's already a transformer, then you can actually compose the project reference output path by looking up |
Probably I can check how Angular handles project references as in Angular 10 solution styles is supported. For now, the 1st step to have a transformer to do convert alias to real path is already a handy feature. The whole project reference thing is like replicating the behavior of |
Doesn't |
Partially using. My potential idea is that, this compilation process needs to be aware of the file belongs to which project when project references is used. Right now one single If there are multiple compilerOptions objects (the case of project references), it means that there are the same amounts of I have asked in TypeScript Discord but still no right solution for that, just still my idea. One thing for sure is compilation needs to be similar to |
I see, okay... it's far more complicated than I thought, then... Possibly the moduleNameMapper solution is actually better then, because The only problem with the moduleNameMapper solution at the moment is that typescript errors will cause it to fail... specifically if you run |
The error can be solved with the transformer I believe. Because the output from compilation process (the js output which will be given to
By default, |
Hey! How's it going with getting ts-jest working with project references? What do you want to do with this PR? |
oh I haven't looked into it yet, but I think this PR can be closed. I just wonder if the changes display in this PR will still stay after you delete the branch ? |
This PR hasn't been merged, if that's what you're asking? I also haven't implemented the updated API for the module name mapper that we discussed. I was waiting to see what you came up with with the project references - obviously it would be better to just have them handled naturally by ts-jest. |
Actually the discussion about solution is here #1648 (comment) The general idea I have is
This PR has the part of retrieving tsconfig from different project references' tsconfig, which is necessary imo for the general idea above. That is my idea, look a bit logical but I haven't tried it out yet. |
Cool. Yeah this module mapper is a bit of a hack for it tbh - it actually results in the referenced projects being compiled twice. |
I think I might find the correct solution for project references. If detecting from tsconfig that user is using project references, The idea is: instead of compiling file by file, Not sure how the performance will be, but at least that looks like the correct way to go. There is one downside is this approach might not work well with parallel tests as first run, all workers will attempt to run build mode at the same time. Maybe should not run build mode for all files at once but run build mode per file like current situation. |
It's worth a try. Build mode has incremental recompilation too, but it's hard to say how that would integrate best with ts-jest though. In fuse-box, there is custom code that walks project references when they're encountered and performs a build on it, sourcing the reference's tsconfig. It's completely possible to do it without using build mode as well. |
I think if |
Cool :) |
I just merged a custom AST transformer for If you are interested to try out, you can check out master and look at https://github.com/kulshekhar/ts-jest/tree/master/e2e/__external-repos__/path-mapping for the example. Besides, I have looked a bit into replicating The only way I can think of now about replicating |
Haha awesome!!! I'll have to check this out. I think this'll be far more convenient than the moduleNameMapper.
That's basically how we did it for Fusebox and it works fine. It's a simple approach that opens the door to easy caching. I don't know where I would begin trying to synchronise with some arbitrary
|
I read an issue in ts-node and what I got from it is: project references is just a way of mapping for module resolution. It doesn't do anything about compiling with separate tsconfig options. So what I understood is, it's sort of similar to jest |
I'm not sure what you mean here... each project definitely gets compiled with its own Do you mean that as long as we compile each 'project' independently and correctly set their module paths, we should be good? If that's the case, then my PR is probably fairly handy...! |
What I meant was about using compiler options. The compiler options will come from a single The actual implementation to support project references is implementing how to resolve the referenced import paths, a.k.a module resolution, based on the Your PR will be the core thing to implement that 😀 Generally speaking, project references and jest |
I'm pretty sure |
Actually However, things are still vague when coming to this concept. Needs some times more to check and understand fully. |
Summary
In another issue (#1698), we identified that a moduleNameMapper was required in order to get jest to play nice with project references when
outDir
orrootDir
are used.Doing this manually sucks, particularly in a monorepo where you have lots of
jest.config.js
files, so I wrote a moduleNameMapper to read project references and generate the corresponding map for jest.Test plan
Tests are included in the PR.
Does this PR introduce a breaking change?
It only adds features, without changing any existing functionality.
Other information
I added a dependency on
json5
. My reasoning for this is that in order to read project references correctly, we need to read the name of the package frompackage.json
, and alsooutDir
androotDir
fromtsconfig.json
. If we're reading these files anyway, I figured we might as well use a loader that doesn't punish developers for having comments of trailing commas in their json files.Also, I added a
tsConfigToModuleNameMapper
convenience helper, which does bothpaths
andreferences
mapping at the same time, to keepts-jest
users joyful.I wonder if there's a way to roll this into the
ts-jest
preset?