Skip to content
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

run ngcc when using ng test to run test with ivy #679

Closed
pkaufi opened this issue Feb 12, 2020 · 7 comments · Fixed by #685
Closed

run ngcc when using ng test to run test with ivy #679

pkaufi opened this issue Feb 12, 2020 · 7 comments · Fixed by #685
Labels
builders:jest enhancement New feature or request

Comments

@pkaufi
Copy link

pkaufi commented Feb 12, 2020

Describe the solution you'd like
When running ng test with

"test": {
          "builder": "@angular-builders/jest:run",
          "options": {
          }

inside angular.json, it should run ngcc beforehand as angular-cli already does (see: angular/angular-cli#15044 (comment)). Otherwise, tests are not running with ivy, which should be the default for angular 9.
As this might break existing tests, an options flag like "enableIvy": false could still be added in order to run them the old way. Or just use the configuration that's already existing in tsconfig.spec.ts which usually points to tsconfig.ts that has "enableIvy": false already defined.

Describe alternatives you've considered
The only way I could make it work is by defining a scripts inside package.json.

{
  "scripts": {
    "test": "ngcc && ng test"
  }
}

and then execute it with npm run test.
It would still be great to just run it with ng test

@pkaufi pkaufi changed the title run ngcc when using ng test to run test with ivy run ngcc when using ng test to run test with ivy Feb 12, 2020
@just-jeb
Copy link
Owner

I agree, this should be a part of the builder. Thanks for the investigation. Would you like to make a PR?

@pkaufi
Copy link
Author

pkaufi commented Feb 12, 2020

Let me give it a try. I'm currently struggling with finding out how the angular team runs ngcc before they run karma. I'm completely new to that code so I need some time there.

@just-jeb
Copy link
Owner

Also, I wonder, maybe for the sake of compatibility we should first look for the flag in tsconfig.spec.json in angularCompilerOptions and only then in builder options. What do you think?

@pkaufi
Copy link
Author

pkaufi commented Feb 13, 2020

In my opinion, we should just check for the flag in tsconfig.spec.json. Having 2 places to configure it makes it a bit repetitive. We either want to run the app with ivy, then the tests should also run it, or we don't, and then we have to anyway set a flag in our tsconfig. And usually, tsconfig.spec.json extends from tsconfig.json where it's configured.

@just-jeb just-jeb added enhancement New feature or request builders:jest labels Feb 17, 2020
@just-jeb
Copy link
Owner

Here are my findings:

  • ngcc transforms libraries, typically node_modules (js files and dts), to make them Ivy compatible. It is necessary, especially if you want to have meaningful error messages when your test fails.
  • For node_modules it's enough to run ngcc only once, for example in postinstall hook to ensure compatibility.
  • There is a very specific use case when you need to run ngcc on modules other than node_modules - when you have a monorepo with libraries and you reference the production bundles of these libraries (dist folders) from your app's tsconfig.
  • Angular CLI commands (build, serve, karma) use ngtools/webpack and as part of Webpack compilation they run ngcc_processor on each non-relative module, which essentially handles the case of monorepo with libraries. It also eliminates the need to run ngcc for the whole node_modules and only runs it for the files that are part of the compilation.

Conclusion:
Running ngcc as a postinstall hook might be a viable workaround for 95% of projects, so we have to include it in the documentation and the migration guide.
However, the only solution that will handle all the use cases properly is adding a custom Jest transformer that will apply ngcc_processor from ngtools/webpack to all the non-relative modules similarly to Angular CLI.
I seriously doubt though that this transformer should be implemented here and not in jest-preset-angular.

@DrNoksy
Copy link

DrNoksy commented May 8, 2020

So, the only way, for now, is the running ngcc manually before running the tests (in postinstall, for example)? But this is a problem for our CI to execute ngcc for packages of the whole monorepo on every test run because of our CI workers install all packages from zero every time and ngcc in additional takes as much as 10 minutes in each build.

@just-jeb
Copy link
Owner

Unfortunately, currently this is the only way. A few things you can do:

  1. Cache node_modules on CI workers
  2. Identify the modules that require ngcc run and run it on them specifically (instead of the whole node_modules folder).
  3. Watch this issue to see whether there will be some solution. Here is some more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
builders:jest enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants