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

RFC: Exploration of use-cases for Angular JIT compilation mode #43133

Closed
IgorMinar opened this issue Aug 12, 2021 · 50 comments
Closed

RFC: Exploration of use-cases for Angular JIT compilation mode #43133

IgorMinar opened this issue Aug 12, 2021 · 50 comments
Labels
action: discuss area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime needs: discussion Indicates than an issue is an open discussion
Milestone

Comments

@IgorMinar
Copy link
Contributor

IgorMinar commented Aug 12, 2021

Note: 📺 Check out the video recording of a community discussion about this RFC @ angularnation.net

Summary

The Angular team would like to understand the remaining use-cases for Angular's JIT compilation mode, and discover any gaps that prevent adoption of the AOT compilation mode for these use-cases.

We'd like you, the community, to share with us how and why you still use JIT mode, and what prevents you from using AOT.

Background information

When Angular launched as v2.0 back in 2016, the template compiler supported two distinct compilation modes: JIT (just in time) and AOT (ahead of time) compilation.

While initially JIT was readily available and the primary mode for both development and production build workflows, our intention has always been to primarily focus on AOT mode which was harder to implement, but offered more opportunities to improve the development experience (e.g. type checking, autocompletion, automated refactoring, and faster development server and unit testing incremental iteration cycle), as well as user experience (faster and smaller apps, thanks to significantly better runtime and payload size optimizations).

Over the last many releases we overhauled the AOT compiler and kept on improving it. As of Angular v9 the AOT compilation mode is the default for all development and production workflows for all CLI application and library workflows (it's been the default at Google for much longer than that). There are only a few remaining cases where JIT compilation is still used:

  • unit testing workflows which run either in mixed JIT+AOT mode, or JIT-only mode
  • use-cases relying on dynamically generating templates and views at runtime
  • the legacy and long-deprecated dynamic upgrade layer within @angular/upgrade
  • customized build pipelines of large monolithic projects that use JIT to speed up incremental builds for interactive workflows

The use of the JIT compiler for these use-cases suffers from a lack of type checking, as well as performance and security issues that are a side-effect of compiling code at runtime in the browser (and in the JavaScript context shared with the production application).

The security implications are serious enough that our Information Security Engineering team at Google has early-on disallowed the use of Angular's JIT compiler in production environments at Google.

As of v13, the legacy View Engine compilation pipeline will no longer be part of Angular's stack (more info and also here), which significantly simplifies Angular, especially for library authors, which have had to ensure compatibility of their libraries with both View Engine and Ivy during the transition.

It is our goal to keep making Angular simpler and streamline internal complexity that affects Angular application developers and library authors in direct and indirect ways, and as part of this effort we'd like to evaluate if keeping JIT compilation mode around is still providing Angular developers with value that justifies the increase in complexity, security risks, and maintenance cost for everyone, including Angular application developers, library developers, as well as the Angular team.

There are many benefits to standardizing on AOT compilation mode, the main ones include:

  • consistency and predictability — JIT and AOT modes behave identically once all the templates & metadata are collected, and all the JavaScript references (module imports, class references, etc) are resolved. However, the collection of templates & metadata, and resolution of JavaScript symbols is significantly different between AOT and JIT, and requires special considerations in the application and library code (inconsistent behavior of what can and cannot be declared with Angular's decorators), in the library packaging format (the npm packages must support both JIT and AOT compilation), and also in the Angular compiler and runtime, which needs to accomodate the needs and quirks of both JIT and AOT.

  • fewer runtime performance and security pitfalls, and fewer confusing APIs for developers — for example the @angular/platform-browser-dynamic package and the Compiler APIs could be removed.

  • addition of view composition APIs to support commonly requested use-cases that are currently handled via JIT compilation — for example dynamic view composition (e.g. new core APIs for dynamically assembling and composing views out of directives, and components at runtime to support data-driven form, and other UIs).

  • focus on further build time improvements for AOT — for example by out-of-band type-checking for TypeScript and Template compilation, and transition to parallelizable localized compilation.

Community feedback

We'd like the community to share with us how and why you still use JIT mode, and what prevents you from using AOT.

We are specifically interested to know if there are use-cases that we are not familiar with (not listed in this RFC)?

Additionally, we'd also like to hear if you face organizational or technical restrictions that require you to use the JIT compilation mode?

The information provided by the community will help us understand what gaps we need to fill, and if it is feasible to deprecate and remove the JIT mode some time in the future once all the significant gaps are filled.

This RFC will close on Sep 8, 2021. Thank you for participating!

@IgorMinar IgorMinar added action: discuss needs: discussion Indicates than an issue is an open discussion area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime labels Aug 12, 2021
@ngbot ngbot bot modified the milestone: Backlog Aug 12, 2021
@eugene-stativka
Copy link

I’ve never seen any use case for JIT in any app I worked on over the last 5 years. Always —aot.

@jnizet
Copy link
Contributor

jnizet commented Aug 13, 2021

TBH, I don't know for sure if that involves JIT mode or not, but I suspect it might. What I'm sure is that it's a common practice, so you've probably thought about it already. But many of my unit tests consist in having test host components that are only ever declared in the testing module:

@Component({
  template: '<component-under-test ...></component-under-test>'
})
class TestComponent {
  ...
}

describe('some test', () => {
  beforeEach(() => {
    configureTestingModule({
      declarations: [ComponentUnderTest, TestComponent]
    }
  });

  ...
}

Some times, the template of the test component is dynamic, i.e. it's overridden in each of the tests to test various combinations of inputs and outputs. That's why I guess it uses the JIT. If such a feature wasn't supported anymore, it would imply a huge amount of re-design and rewrite of the tests.

@SanderElias
Copy link
Contributor

SanderElias commented Aug 13, 2021

I would say, get rid of it as soon as the view composition APIs is in a stable state, as that would fulfill all of the use-cases JIT is now used for.
(assuming proper replacements using view composition are in place for testing)

When this, and the related RFC's do speed things up enough, the custom builds using JIT will become unneeded anyway

@IgorMinar
Copy link
Contributor Author

@jnizet great point! Thank you. You are right that the testing components today rely on JIT. Usually not because they are dynamic but because you need the flexibility to declare them inline, usually within functions of a test file as your example shows.

With the right compiler and API modifications we should be able to support this with AOT (thanks to Ivy). This change could be rolled out with an automated migration so nobody has to rewrite their tests.

But as you bring up, this flexibility of testing components means that you could dynamically create a template or modify the component metadata (e.g. use string concat and interpolation to create a unique template for a bunch of components created within a loop that wraps an it or describe.

This is not the most common pattern but I'd be shocked if some codebases didn't rely on it. I currently don't have a solution for this one. Maybe the composition api could be it, but automated migration from unconstrained TS/JS code that generates a component to a component built using the composition API would be tricky and not 100% reliable.

I do appreciate bringing this up though. This is exactly the kind of feedback we are looking for.

@ahnpnl
Copy link
Contributor

ahnpnl commented Aug 13, 2021

We use JIT mainly for unit testing only, especially with Jest. Currently, we follow slightly similar setup how Angular CLI did is that:

  • apply downlevel ctor + replace resources AST transformers during compilation step. We did change a bit in AST like removing css in the emitted codes.

  • With Jest, we use simple ts.LanguageService to compile ts to js because ts.Program is slower when creating multiple instances in Jest workers.

  • Init test environment using platform-browser-dynamic and patch zone, see https://github.com/thymikee/jest-preset-angular/blob/master/src/config/setup-jest.ts
    (Zone patch codes were already migrated to Angular repo).

If removing platform-browser-dynamic, I believe CLI team also needs to change the way to init test environment. It isn’t really a problem for us to migrate if there is a clear way to replace that way of initialization.

Regarding to code emitting, IIRC AOT compiler uses some extra AST transformers besides the above 2 which I think will be the most work for us to replicate the same behavior for Jest.

We would love to use AOT compiler for Jest but will need to spend some time first to experiment. Ofc using everything from Angular is the best way. My concern only is how open the AOT compiler APIs will be so that we can reuse them.

@kroeder
Copy link
Contributor

kroeder commented Aug 13, 2021

@storybook/angular relies on JIT right now.

Storybook users write story files like this one
https://github.com/storybookjs/storybook/blob/next/examples/angular-cli/src/stories/welcome-angular.stories.ts

export default {
  title: 'Welcome/ To Angular',
} as Meta;

export const toAngular: Story = () => ({
  component: AppComponent,
  props: {
    showApp: linkTo('Button'),
  },
});

A story contains metadata to generate the actual NgModule and render the component or template during runtime. This information is not available during compile-time and therefore is not compatible with AoT, right? Actually, the story is. But not the generated NgModule and Component.

Here's one example of what Storybook does with the provided metadata information of a story
https://github.com/storybookjs/storybook/blob/next/app/angular/src/client/preview/angular-beta/StorybookModule.ts#L30

export const createStorybookModule = (ngModule: NgModule): Type<unknown> => {
  @NgModule(ngModule)
  class StorybookModule {}
  return StorybookModule;
};

I talked about this with Alan, Minko and Alex during the Storybook Ivy integration and I remember one of them said: "Maybe, it is possible to partly make Storybook AoT compatible as a second step" but we didn't talk about this any further.

@johncrim
Copy link

We care about Jest tests (for faster dev cycles) and a home-grown app for demoing components using templates that are compiled at runtime. Most developers will probably use Storybook, but we use something similar to this to host angular examples within an angular app:

https://github.com/johncrim/angular-dynamic-styleguide

Here's the part that compiles templates:

https://github.com/johncrim/angular-dynamic-styleguide/blob/master/src/app/examples/template-examples.service.ts

The general problem description is: "How do we render angular component code alongside working examples of that code?" I'm sure that if the problem is solved well for aio and storybook we can use the same approach.

We'd be happy to migrate to a new way to accomplish the same thing once it's available.

@IgorMinar
Copy link
Contributor Author

@ahnpnl, @kroeder, and @johncrim this is exactly the kind of feedback we are looking for! Thank you for sharing the links and examples.

My first impression is that Jest, Storybook, and example use case would be fully supported using a combination of the proposed view composition APIs (primarily for the demo use cases) and whatever solution we implement to AOT compile testing components within unit tests (for jest and storybook).

Do you see any obvious holes in these solutions? (I apologies for the lack of clarity around the solution for unit tests, I'll see if I can write something up in the next few days to make it less ambiguous)

@mattlewis92
Copy link
Contributor

We are still using JiT mode for local development for our large app (~1300 components), as AoT is still noticeably slower for incremental rebuilds. v12 and webpack's in memory caching helped a lot to make this better as previously a single line change in a component would take more than a minute to rebuild, now after a few rebuilds it goes down to about 14s, although it's still double the speed of JiT mode on the same file (apx 7s). The first few changes to the file are always a lot slower as well (1st: ~79s, 2nd: ~28s, 3rd: ~14s). We'd be happy to arrange access to the repo for an angular team member to do some profiling to see if it's possible to get it down to match the speed of JiT mode 😄

@JoostK
Copy link
Member

JoostK commented Aug 13, 2021

@mattlewis92 I'm always interested in real-life repos to do perf tests with, as they often show new insights in ways to optimize builds.

The first rebuild is indeed slower because incremental type checking of TS sources is ineffective in the first rebuild. This is a known limitation because of how template type checking is achieved. I'd be interested to learn where the 7s deficit from JIT mode comes from.

@elvisbegovic
Copy link
Contributor

My team use JIT in spite of themselves: to quick fix never understood OOM & build/rebuild speed.

use case : +150 lazyroutes +1000 components
We have single file for tstypes (models.d.ts), created automatically from backend models (Java). As models.d.ts is imported in practically each angular file, any changes/breaks/rebuild of this file will invalidate cache/modules of entire angular applications and result: potential OOM because whole app is rebuilded and rebuild is long like first build.

Thanks to @JoostK &co a lot of work is done in practically each major release to “get closer” to JIT rebuild time. 🙏

@johncrim
Copy link

johncrim commented Aug 13, 2021

@IgorMinar - thank you for soliciting community feedback! Regarding your statement here:

Dynamic template creation out of (string) templates is something that I'd really like to avoid ...

Thinking about our style-guide app (public starter version here: https://github.com/johncrim/angular-dynamic-styleguide ), my first thought is "oh boy, then we'll have to maintain separate text for the template source code for developers to use, and view composition code that is functionally equivalent to that source code, for each of our examples". Which doesn't seem tenable - if we had to do without runtime compilation from text templates, I'd probably try to come up with a way to compile each of the examples during a custom compilation process, so that we could pull the source code text and the working example into the style-guide app.

It seems pretty difficult right now to come up with a compile-time implementation for this. Though I haven't dug into what aio does (it looks like the code and screenshots are generated), or what Storybook does, a couple years ago I concluded that using the runtime compiler was the easiest way to solve this.

Another possibility is: Could there be a way to compile string templates into view composition code, as part of a custom compilation process?

For this use-case, there's no reason that the compilation has to be done at runtime - all that's needed is a way to compile example templates, and correlate that template text with a loadable component.

The number of developers that care about this case is probably far fewer than the testing use cases, though functionally there may be a lot of overlap. Maybe this is a 3rd party library built on top of Angular APIs. Speaking only for myself, I'm up for recreating this functionality within new constraints, in the interest of reducing Angular surface area.

Another use case to consider:

  • StackBlitz and similar products - I don't know if they use the runtime compiler, or server compilation.

@IgorMinar
Copy link
Contributor Author

IgorMinar commented Aug 14, 2021

Another possibility is: Could there be a way to compile string templates into view composition code, as part of a custom compilation process?

@johncrim maybe, there might be some advanced features in the template syntax that we might initially keep out of the view composition API to focus on what matters the most and delivering this in a reasonable timeline, but I could see how over time, the API could match the full expressiveness of declarative templates.

@IgorMinar
Copy link
Contributor Author

@mattlewis92 and @elvisbegovic please check out #43131 which has some ideas about how to make the builds significantly faster.

@IgorMinar IgorMinar pinned this issue Aug 15, 2021
@IgorMinar
Copy link
Contributor Author

@mattlewis92 and @elvisbegovic, I've also just posted #43165 that proposes changes to make the compilation significantly faster.

@sheshnathverma
Copy link

We have a use case where our app uses a dynamic form(dynamic component HTML + Typescript + CSS) created by end-users and loads it in specific sections in our app.

If angular remove the JIT compiler then we will be screwed :(

@IgorMinar
Copy link
Contributor Author

@sheshnathverma can you please help us understand why wouldn't the proposed view composition API work for you to replace the JIT compiler?

@dylhunn dylhunn unpinned this issue Aug 16, 2021
@sheshnathverma
Copy link

sheshnathverma commented Aug 17, 2021

@sheshnathverma can you please help us understand why wouldn't the proposed view composition API work for you to replace the JIT compiler?

@IgorMinar thanks for replying to my concern.
As of now we store the full component as a text in the database and based on the end-user, we load on demand. The following is a sample code where we need a compiler to compile and load into the module for next use

`
const style = "";
const template = <app-custom [input]=info>;

@component({
selector: "app-demo",
template: template,
style: style
})
export class DemoComponent { info={}; // some custom code by end users }`

Now if the proposed view composition api can handle this scenario then we will be safe. let me also highlight we offer them our inbuild control as well (ex. app-text, app-number etc.).

@mlc-mlapis
Copy link
Contributor

@sheshnathverma It's logical that the proposal won't include your current way of processing.

Probably #43133 (comment) promises a future way how to do it. But it means storing not the plain HTML code but the view composition code (taking the plain HTML and pre-compile it before storing it into a database).

@petebacondarwin
Copy link
Member

@sheshnathverma - Given that you actually control the content for these dynamic templates (even though they can be defined by a user), another solution would be to AOT compile the HTML template strings stored in the database on the server into a JS module that you can load dynamically into an Angular app. The compiled output could be cached at the server to avoid undue compilation cost. This would also speed up and reduce resource usage on the users browser.

@timfogarty1549
Copy link

When I upgraded to Angular 12 and AOT became the default, I found it impossible to develop code the way I was use to. With JIT, I would make a change in my IDE, hit save, and see the change instantly in my browser pointing to localhost:4200. With AOT, it was 10 seconds before the browser refreshed. The most obvious example of this type of programming would be getting CSS exactly right. You make a change then see how it is displayed, then adjust it a little more, save and see it again. If it takes many seconds between save and refreshing the page then I'm not working as fast as I could. I do this type of iterative development with everything, templates, methods, rest endpoints, etc.

@mdunhem
Copy link

mdunhem commented Aug 17, 2021

We have an internal docs site for our design system which has live editable versions of our components. We compile the TS in the browser and then restart the Angular app that's rendered inside of a containing div, running inside of a Gatsby site. This is similar to how Stackblitz worked in the past (or at least based on my naive assumption.) While we don't specifically use the Compiler directly, it is still JIT mode due to not being run through the AOT compiler. I would assume that this setup wouldn't work anymore if JIT mode was removed? Or maybe there is a way to compile it into AOT in the browser when compiling the TS?

The proposed view composition api would most likely work for us although would require a bit of retooling and tinkering to make it work, depending on what the exposed api would end up being. Otherwise we'd need to either go with a static implementation and remove the live-editable feature, or pay for an enterprise version of Stackblitz or something.

I'm all for cleaning up Angular and trimming down the needed code, but it does present some challenges for us in the future. I mostly wanted to inform you of one of the use cases for JIT mode.

@IgorMinar
Copy link
Contributor Author

@mdunhem and @vinayk406 while I believe that the proposed composition API would work for your use-cases, wonder if running the AOT compiler within a service worker would be a better fit for you. It's something we discussed on and off. This is not the simplest approach but it wouldn't be too crazy either.

@IgorMinar
Copy link
Contributor Author

@LayZeeDK thanks for the collection of links and pointing out a great example of an inconsistency between JIT and AOT.

For AOT to work the code does need to be statically analyzable, and we go to great lengths to statically evaluate the expressions to provide better DX, but that has limits. These limits are usually not visible to developers though and we don't currently consider them to be something that needs addressing. Are you suggesting otherwise or is the goal of your comment just to illustrate how JIT and AOT differ?

@IgorMinar
Copy link
Contributor Author

@perjerz thanks for sharing your use-cases.

I believe that would be supported by the composition API. To make it more ergonomic, it would be interesting to discuss a possibility of creating a higher level API which would accept data in JSON (or similar format) and produce the view using the composition API. That way, you'd only need to get your CMS to produce the JSON instead of html to be able to use this API.

An alternative would be something like along the lines of tshtml proposed in one of the comments: #43120 (comment) which uses a html parser to turn strings to structured data. This is not the most efficient solution, but once again, something that could be built (by the community?) on top of the composition APIs.

@LayZeeDK
Copy link
Contributor

@IgorMinar

My comment doesn't have a point other than pointing out that most kinks have been ironed out by the Angular team over the course of time which is great to see. JIT -> AOT was not an easy transition in early versions of Angular.

Based on the remaining caveats listed, I don't have a specific use case in mind although I'm a bit surprised by the synchronous assignment examples.

You list the obvious use cases in the original post, for example dynamic generation of declarables at runtime.

How about testing? Which limitations would be put on automated tests if JIT was removed entirely?

@IgorMinar
Copy link
Contributor Author

@LayZeeDK Any code that dynamically builds up templates of testing components would be affected, but that's about it. I've seen a handful of instances of this pattern at Google and all those cases could use the composition API instead.

@mdunhem
Copy link

mdunhem commented Aug 25, 2021

@mdunhem and @vinayk406 while I believe that the proposed composition API would work for your use-cases, wonder if running the AOT compiler within a service worker would be a better fit for you. It's something we discussed on and off. This is not the simplest approach but it wouldn't be too crazy either.

Thanks for the response. I might tinker with that, especially considering we're already running the TypeScript compiler in the browser. Switching it to use ngc instead and doing it in a service worker might also make it run more efficiently.

@pycka
Copy link

pycka commented Aug 25, 2021

Our use case is a back office application built using module federation approach.
So-called host application is quite dumb, brings Angular Material plus a set of components from our SDK. It learns about available business modules at runtime from API endpoint. It can be taken off the shelf and used by many products without rebuilding.
Business modules are provided as UMD bundles from Angular libraries. Basically, NPM packages (Angular libs) get deployed to particular system and that's it. No rebuilding required.
IEs control what modules are available for particular app instance and when. Deployment of new modules (independently developed in separate Angular projects) doesn't require any rebuilds or releases.
This system was originally built on Angular 9 and we somehow managed to keep it working across updates, including migration from ViewEngine to Ivy.

@flash-me
Copy link
Contributor

flash-me commented Aug 25, 2021

Business modules are provided as UMD bundles from Angular libraries

@pycka

ng-packagr/ng-packagr#2050 might be interesting for your current approach

cheers
flash ⚡

@pycka
Copy link

pycka commented Aug 25, 2021

ng-packagr/ng-packagr#2050 might be interesting for your current approach

@flash-me
Yeah, we knew about this direction and it isn't a problem for us, we should be able to get this functionality back with a few lines of code on our side.
JIT, otoh, is a different story...

@lacolaco
Copy link
Contributor

lacolaco commented Aug 27, 2021

#43133 (comment)
#43120 (comment)

I agree with this opinion, and just like Storybook, Testing Library's API for writing templates in string format and dynamically generating test host components is important for the developer experience.

await render(`<my-button></my-button>`, { 
  imports: [MyButtonModule],
});

The Testing Library is just one example, but in this interest, I hope that directive testing by test hosts will remain the same experience as before.

@xorets
Copy link

xorets commented Aug 27, 2021

@johncrim, you mentioned compiling string templates as a part of custom compilation step:

Another possibility is: Could there be a way to compile string templates into view composition code, as part of a custom compilation process?

For this use-case, there's no reason that the compilation has to be done at runtime - all that's needed is a way to compile example templates, and correlate that template text with a loadable component.

This is exactly what already quoted tshtml does. You basically export a string from TS file, the file is executed at build time and it's output is treated as usual static HTML template.

@matthewjh
Copy link
Contributor

matthewjh commented Sep 1, 2021

At our company, we are using (and are reliant on) JIT to generate and utilise generated mock services/components/directives in tests.

I think there is a use case for JIT in test code.

@LayZeeDK
Copy link
Contributor

LayZeeDK commented Sep 2, 2021

Spectactular's pipe testing API allows the user to decide the template of the (internal) host component for integration testing an Angular pipe. How would we solve this using the imperative view composition API or otherwise, without JIT in tests?

import {
  createPipeHarness,
  SpectacularPipeHarness,
} from '@ngworker/spectacular';

import { PowPipe } from './pow.pipe';

describe(PowPipe.name, () => {
  beforeEach(() => {
    harness = createPipeHarness({
      pipe: PowPipe,
      // template: '{{ value | pow }}' // 👈 Default host component template
      value: 2,
    });
  });

  let harness: SpectacularPipeHarness;
  
  it('raises the base to the specified power', () => {
    harness.value = 5;
    harness.template = '{{ value | pow:3 }}'; // 👈 Resets the Angular testing module and overrides the host component template

    expect(harness.text).toBe('125');
  });
});

@Johnnyrook777
Copy link

I am using the JIT compiler to build up text document fragments. We allow our staff to define templates (HTML) and bind them to a model via JIT and compileModuleAndAllComponentsAsync.
We use a few things to help render text/dom on the screen, namely *ngIf, *ngFor, {{ }}, {{ x | customPipe }}

Its really powerful as we can just point them to some angular basics, build some custom pipes for the tricky stuff, and let them at it.

@IgorMinar
Copy link
Contributor Author

@lacolaco I agree with you that for testing use cases, using strings as inputs is important. I think we can support this by translating/transpiling strings with templates being tested to the view composition API calls.

From the DX perspective it works in the same way, but under the hood it won't require JIT compiler, which would be a huge win for all of us.

@IgorMinar
Copy link
Contributor Author

@matthewjh could you please share some examples that capture various usage patterns? I'd love to know more to determine if these patterns are already captured in the use-cases we discussed above or if they are unique. thanks

@IgorMinar
Copy link
Contributor Author

I really appreciate all the feedback we've received from all of you. This RFC was supposed to close this week, but I like the conversation and I'd like to finish some of the unresolved questions around testing use-cases, and CMS-like use-cases.

From what I've seen in the feedback so far, I think we can have a solid story for all the concerns raised even without JIT compiler, as long as we implement some of the proposed features to fill in the current gaps in AOT capabilities and DX.

If you have more details you'd like to share with us, please do so by next Wednesday, September 8. Thank you! 🙇🏻 🖖🏻

@LayZeeDK
Copy link
Contributor

LayZeeDK commented Sep 4, 2021

@lacolaco I agree with you that for testing use cases, using strings as inputs is important. I think we can support this by translating/transpiling strings with templates being tested to the view composition API calls.

From the DX perspective it works in the same way, but under the hood it won't require JIT compiler, which would be a huge win for all of us.

Yes, this also ties into the Spectacular use case. Having that string template to imperative view composition feature to optionally add would be great. API bundle size doesn't matter as much for testing so it's the perfect companion to keep supporting the rich ecosystem of Angular testing libraries. Maybe it could even be a choice for bundling at runtime for dynamic scripting-like use cases if bundle size is less of a concern, similar to bundling the JIT compiler today for dynamic runtime composition.

@matthewjh
Copy link
Contributor

matthewjh commented Sep 8, 2021

@IgorMinar

@matthewjh could you please share some examples that capture various usage patterns? I'd love to know more to determine if these patterns are already captured in the use-cases we discussed above or if they are unique. thanks

Let's say we are testing a component A that utilises another component or directive B from our codebase (I'll just say "directive" from here onwards). This directive may reside in the app itself or in a library in our monorepo. In the test for A, we will configure the testing module with declarations = [mockDirective(A)]. mockDirective will read the ng metadata for A via ReflectionCapability (semi-protected, I know), and create a new directive class that has the same selector as A, iterating through A's inputs and outputs, recreating them on the mock ADirective. Outputs are initialised with new EventEmitters. The idea is to eliminate boilerplate code in tests, as well as to provide batteries-included mocks, without pulling in implementations of collaborators into unit tests.

So in a nutshell, we would need to be able to:

  1. Read the ng metadata for ng-things
  2. Dynamically create new ng-things with certain pieces of ng metadata, including property metadata like inputs/outputs
  3. Be able to use these dynamically created ng-things with parity to static ng-things

@meriturva
Copy link

Sorry @IgorMinar, I'm late on the discussion.

As already described to @mgechev we have a quite big application where we compose on runtime routing and loading dynamically modules using systemjs (quite old application), of course, based on JIT Compiler.

Just a short question related to Ivy and AOT:

will it be possible to compile single modules (angular library) with ivy compilationMode = full
then use modules compiled as a dynamic import during runtime routing configuration (maybe with a custom webpack configuration)?

Using that approach we will be free to remove jit compiler on our project.

@flash-me
Copy link
Contributor

flash-me commented Sep 16, 2021

@meriturva This is already possible.

UPDATE:
Just in case someone is asking
cheers
flash ⚡

@RobinVdBroeck
Copy link

This RFC will close on Sep 8, 2021. Thank you for participating!

When can we expect the conclusion of the Angular Team? Any timeline?

@IgorMinar IgorMinar unpinned this issue Oct 5, 2021
@IgorMinar
Copy link
Contributor Author

Hey everyone, thanks for participating in this RFC. I'm finally wrapping up this one now that the RFC for standalone components, directives, and pipes is out. Several of the sub-rfc of this RFC referred to the "standalone" design, so I'm glad that all of the information is out there and up for discussion.

The key takeaways from this RFC for me are:

  1. nobody strongly objects to removal of JIT mode as long as all of the existing use-cases are covered

  2. the biggest gaps discovered via this RFC are:

    1. Jest and Storybook integration rely on JIT, so we'd need to work with these teams to get them off. This seems doable.

    2. AOT build speed and edit/refresh latency is a concern for several people with large applications. I think we can tackle this via build latency improvements that are already being planned.

    3. Dynamic view creation is a big deal for several applications that either

      • lazy load templates and compile them on the fly ("federated" apps, or apps with plugins), or
      • enable users to create templates (CMSes, drag&drop UI builders)
      • or unit tests where it's desirable to express the testing component using the Angular template syntax

      All of these use cases can be handled via Imperative View & Template Composition APIs and ability to AOT compile testing components embedded in unit tests, but as surfaced via this RFC, it would be great to also consider providing a simplified declarative API for view creation inspired by tshtml.

Overall, my take on this RFC is that JIT is not going to disappear any time soon, but if we fill in all the gaps, it could disappear in the future. Thank you all for participating in the discussion.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: discuss area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime needs: discussion Indicates than an issue is an open discussion
Projects
None yet
Development

No branches or pull requests