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

feat(vite-plugin-angular): introduce experimental support for .ng format #823

Merged
merged 17 commits into from
Jan 2, 2024

Conversation

nartc
Copy link
Member

@nartc nartc commented Jan 1, 2024

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

Which package are you modifying?

  • vite-plugin-angular
  • vite-plugin-nitro
  • astro-angular
  • create-analog
  • router
  • platform
  • content
  • nx-plugin
  • trpc

What is the current behavior?

Closes #

What is the new behavior?

This introduces experimental support for a .ng format for components, directives, and pipes.

  • This is enabled with an experimental flag through the Vite config.
  • Components/directives/pipes can be used immediately in the template after imported.
  • Uses Angular's experimental-local compilation mode.
  • SSR is not currently supported.
  • Inputs / Outputs are not currently supported.
  • Deferrable Views are not currently supported.
  • defineComponentMetadata , defineDirectiveMetadata, and definePipeMetadata are used to define metadata for components, directives, and pipes.
/// <reference types="vitest" />

import { defineConfig } from 'vite';
import analog from '@analogjs/platform';

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
  // ... other config
  plugins: [
    analog({
      ssr: false,
      vite: {
        experimental: {
          dangerouslySupportNgFormat: true
        }
      },
    }),
  ],
}));

Component

hello.ng

<template>
  <p>hello works!</p>
</template>

app.component.ng

<script lang="ts">
  import { inject, signal, effect, computed } from '@angular/core';
  import { JsonPipe } from '@angular/common';
  import { HttpClient } from '@angular/common/http';
  import { delay } from 'rxjs';

  import Hello from './hello.ng';
  import Highlight from './highlight.ng';
  import Doubled from './doubled.ng';

  defineComponentMetadata({
    selector: 'app-root',
    imports: [JsonPipe],
  });

  const title = 'Analog';

  const http = inject(HttpClient);

  const counter = signal(1);
  const doubled = computed(() => counter() * 2);
  const todo = signal(null);

  const increment = () => {
    counter.update((value) => value + 1);
  };

  function decrement() {
    counter.update((value) => value - 1);
  }

  effect(() => {
    console.log('counter changed', counter());
  });

  onInit(() => {
    console.log('App init');
    http
      .get('https://jsonplaceholder.typicode.com/todos/1')
      .pipe(delay(2000))
      .subscribe((data) => {
        todo.set(data);
        console.log('data', data);
      });
  });
</script>

<template>
  @if (counter() > 2) {
    <Hello />
  }

  <p>Counter: {{ counter() }}</p>
  <p highlight>Doubled: {{ doubled() }}</p>
  <p>Doubled with Pipe: {{ counter() | doubled }}</p>
  <button (click)="increment()">increment</button>
  <button (click)="decrement()">decrement</button>

  @if (todo(); as todo) {
  <pre>{{todo | json }}</pre>
  } @else {
  <p>Loading todo...</p>
  }
</template>

<style>
  p {
    color: red;
  }

  button {
    background: blue;
    color: white;
    padding: 1rem 0.5rem;
    border-radius: 0.5rem;
  }
</style>

Pipe

doubled.ng

<script lang="ts">
  definePipeMetadata({
    name: 'doubled',
  });

  function transform(value: number) {
    return value * 2;
  }
</script>

Directive

highlight.ng

<script lang="ts">
  import { afterNextRender, ElementRef, inject } from '@angular/core';

  defineDirectiveMetadata({
    selector: 'p[highlight]',
  });

  const elementRef = inject<ElementRef<HTMLElement>>(ElementRef);

  afterNextRender(() => {
    elementRef.nativeElement.style.backgroundColor = 'yellow';
  });
</script>

Lifecycle Hooks

An onInit lifecycle hook can be added for init logic.

<script>
  onInit(() => {
    console.log('App init');
    http
      .get('https://jsonplaceholder.typicode.com/todos/1')
      .pipe(delay(2000))
      .subscribe((data) => {
        console.log('data', data);
      });
  });
</script>

<template>
  <p>Component Init</p>
</template>

The DestroyRef can be used for teardown logic:

<script lang="ts">
  import { DestroyRef, inject } from '@angular/core';

  inject(DestroyRef).onDestroy(() => {
    console.log('hello destroyed');
  });
</script>

<template>
  <p>Component Destroy</p>
</template>

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

[optional] What gif best describes this PR or how it makes you feel?

Copy link

netlify bot commented Jan 1, 2024

Deploy Preview for analog-docs ready!

Name Link
🔨 Latest commit 0ac6817
🔍 Latest deploy log https://app.netlify.com/sites/analog-docs/deploys/659384c3108269000875f07c
😎 Deploy Preview https://deploy-preview-823--analog-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Jan 1, 2024

Deploy Preview for analog-blog ready!

Name Link
🔨 Latest commit 0ac6817
🔍 Latest deploy log https://app.netlify.com/sites/analog-blog/deploys/659384c3ed4f110008cf70ac
😎 Deploy Preview https://deploy-preview-823--analog-blog.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Jan 1, 2024

Deploy Preview for analog-app ready!

Name Link
🔨 Latest commit 0ac6817
🔍 Latest deploy log https://app.netlify.com/sites/analog-app/deploys/659384c348098300083135a9
😎 Deploy Preview https://deploy-preview-823--analog-app.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@brandonroberts brandonroberts marked this pull request as ready for review January 2, 2024 01:48
@brandonroberts brandonroberts changed the title Feat ng component feat(vite-plugin-angular): introduce experimental support for .ng format for components/directives/pipes Jan 2, 2024
@brandonroberts brandonroberts changed the title feat(vite-plugin-angular): introduce experimental support for .ng format for components/directives/pipes feat(vite-plugin-angular): introduce experimental support for .ng format Jan 2, 2024
@brandonroberts brandonroberts merged commit f12beeb into analogjs:main Jan 2, 2024
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants