Skip to content

Commit

Permalink
More JavaScript content (#1646)
Browse files Browse the repository at this point in the history
* Add missing app host package

* Add the other Node.JS sample link

* Add missing details about Node.js as a server app

* Add details about server differences, and links to resources

* Add more displayName search terms

* Edit pass

* Acrolinx updates

* Add sentence

* Add link to CORS config

* Add params

* Apply suggestions from code review

Co-authored-by: Tom Dykstra <[email protected]>

---------

Co-authored-by: Tom Dykstra <[email protected]>
  • Loading branch information
IEvangelist and tdykstra authored Sep 11, 2024
1 parent db14b34 commit 296ef57
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
53 changes: 44 additions & 9 deletions docs/get-started/build-aspire-apps-with-nodejs.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: Orchestrate Node.js apps in .NET Aspire
description: Learn how to integrate Node.js and npm apps into a .NET Aspire App Host project.
ms.date: 06/13/2024
ms.date: 09/11/2024
---

# Orchestrate Node.js apps in .NET Aspire

In this article, you learn how to use Node.js and Node Package Manager (`npm`) apps in a .NET Aspire project. The sample app in this article demonstrates [Angular](https://angular.io), [React](https://react.dev/), and [Vue](https://vuejs.org/) client experiences. The following .NET Aspire APIs exist to support these scenarios:
In this article, you learn how to use Node.js and Node Package Manager (`npm`) apps in a .NET Aspire project. The sample app in this article demonstrates [Angular](https://angular.io), [React](https://react.dev/), and [Vue](https://vuejs.org/) client experiences. The following .NET Aspire APIs exist to support these scenarios—and they're part of the [Aspire.Hosting.NodeJS](https://nuget.org/packages/Aspire.Hosting.NodeJS) NuGet package:

- [Node.js](https://nodejs.org/): <xref:Aspire.Hosting.NodeAppHostingExtension.AddNodeApp%2A>.
- [`npm` apps](https://docs.npmjs.com/cli/using-npm/scripts): <xref:Aspire.Hosting.NodeAppHostingExtension.AddNpmApp%2A>.
Expand All @@ -16,6 +16,9 @@ The difference between these two APIs is that the former is used to host Node.js
> [!TIP]
> The sample source code for this article is available on [GitHub](https://github.com/dotnet/aspire-samples/tree/main/samples/AspireWithJavaScript), and there are details available on the [Code Samples: .NET Aspire with Angular, React and Vue](/samples/dotnet/aspire-samples/aspire-angular-react-vue) page.
> [!IMPORTANT]
> While this article is focused on Single-Page App (SPA) frontend bits, there's an additional Node.js sample available on the [Code Samples: .NET Aspire Node.js sample](/samples/dotnet/aspire-samples/aspire-nodejs) page, that demonstrates how to use Node.js as a server app with [express](https://expressjs.com/).
[!INCLUDE [aspire-prereqs](../includes/aspire-prereqs.md)]

Additionally, you need to install [Node.js](https://nodejs.org/en/download/) on your machine. The sample app in this article was built with Node.js version 20.12.2 and npm version 10.5.1. To verify your Node.js and npm versions, run the following commands:
Expand Down Expand Up @@ -104,13 +107,17 @@ The [.NET Aspire dashboard](../fundamentals/dashboard/overview.md) launches in y

:::image type="content" source="media/aspire-dashboard-with-nodejs.png" lightbox="media/aspire-dashboard-with-nodejs.png" alt-text=".NET Aspire dashboard with multiple JavaScript client apps.":::

The `weatherapi` service endpoint resolves to a Swagger UI page that documents the HTTP API. This service is consumed by each client app to display the weather forecast data. You can view each client app by navigating to the corresponding endpoint in the .NET Aspire dashboard. Their screenshots and the modifications made from the template starting point are detailed in the following sections.
The `weatherapi` service endpoint resolves to a Swagger UI page that documents the HTTP API. Each client app consumes this service to display the weather forecast data. You can view each client app by navigating to the corresponding endpoint in the .NET Aspire dashboard. Their screenshots and the modifications made from the template starting point are detailed in the following sections.

In the same terminal session that you used to run the app, press <kbd>Ctrl</kbd> + <kbd>C</kbd> to stop the app.

## Explore the app host

To help understand how each client app resource is orchestrated, look to the app host project. The app host code declares the client app resources using the `AddNpmApp` API.
To help understand how each client app resource is orchestrated, look to the app host project. The app host requires the [Aspire.Hosting.NodeJS](https://nuget.org/packages/Aspire.Hosting.NodeJS) NuGet package to host Node.js apps:

:::code language="xml" highlight="13,20-28" source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj":::

The project file also defines a build target that ensures that the npm dependencies are installed before the app host is built. The app host code (_Program.cs_) declares the client app resources using the `AddNpmApp` API.

:::code source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.AppHost/Program.cs":::

Expand All @@ -125,17 +132,23 @@ The preceding code:

For more information on inner-loop networking, see [.NET Aspire inner-loop networking overview](../fundamentals/networking-overview.md). For more information on deploying apps, see [.NET Aspire manifest format for deployment tool builders](../deployment/manifest-format.md).

When the app host orchestrates the start up of each client app, it uses the `npm run start` command. This command is defined in the `scripts` section of the _package.json_ file for each client app. The `start` script is used to start the client app on the specified port. Each client app relies on a proxy to request the "weatherapi" service. The proxy is configured in the _proxy.conf.js_ file for the Angular client, _webpack.config.js_ for the React client, and in the _vite.config.ts_ file for the Vue client.
When the app host orchestrates the launch of each client app, it uses the `npm run start` command. This command is defined in the `scripts` section of the _package.json_ file for each client app. The `start` script is used to start the client app on the specified port. Each client app relies on a proxy to request the "weatherapi" service.

The proxy is configured in:

- The _proxy.conf.js_ file for the Angular client.
- The _webpack.config.js_ file for the React client.
- The _vite.config.ts_ file for the Vue client.

## Explore the Angular client

There are several key modifications from the original Angular template. The first is the addition of a _proxy.conf.js_ file. This file is used to proxy requests from the Angular client to the "weatherapi" service.

:::code language="javascript" source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.Angular/proxy.conf.js":::

The preceding configuration proxies HTTP requests that start with `/api` to target the URL within the `services__weatherapi__http__0` environment variable. This environment variable is set by the .NET Aspire app host and is used to resolve the "weatherapi" service endpoint.
The .NET Aspire app host sets the `services__weatherapi__http__0` environment variable, which is used to resolve the "weatherapi" service endpoint. The preceding configuration proxies HTTP requests that start with `/api` to the target URL specified in the environment variable.

The second update is the to the _package.json_ file. This file is used to configure the Angular client to run on a different port than the default port. This is achieved by using the `PORT` environment variable, and the `run-script-os` npm package to set the port.
The second update is to the _package.json_ file. This file is used to configure the Angular client to run on a different port than the default port. This is achieved by using the `PORT` environment variable, and the `run-script-os` npm package to set the port.

:::code language="json" source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.Angular/package.json":::

Expand Down Expand Up @@ -209,14 +222,36 @@ To visualize the Vue client app, navigate to the "vue" endpoint in the .NET Aspi

## Deployment considerations

The sample source code for this article is designed to run locally. It has also been developed to deploy each client app as a container image. The _Dockerfile_ for each client app is used to build the container image. Each _Dockerfile_ is identical, using a multistage build to create a production-ready container image.
The sample source code for this article is designed to run locally. Each client app deploys as a container image. The _Dockerfile_ for each client app is used to build the container image. Each _Dockerfile_ is identical, using a multistage build to create a production-ready container image.

:::code language="dockerfile" source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.Angular/Dockerfile":::

The client apps are currently configured to run as true SPA apps, and are not configured to run in a server-side rendered (SSR) mode. They sit behind **nginx**, which is used to serve the static files. They leverage a simple _default.conf.template_ file to configure **nginx** to proxy requests to the client app.
The client apps are currently configured to run as true SPA apps, and aren't configured to run in a server-side rendered (SSR) mode. They sit behind **nginx**, which is used to serve the static files. They use a _default.conf.template_ file to configure **nginx** to proxy requests to the client app.

:::code language="nginx" source="~/aspire-samples/samples/AspireWithJavaScript/AspireJavaScript.Angular/default.conf.template":::

## Node.js server app considerations

While this article focuses on client apps, you might have scenarios where you need to host a Node.js server app. The same semantics are required to host a Node.js server app as a SPA client app. The .NET Aspire app host requires a package reference to the [Aspire.Hosting.NodeJS](https://nuget.org/packages/Aspire.Hosting.NodeJS) NuGet package and the code needs to call either `AddNodeApp` or `AddNpmApp`. These APIs are useful for adding existing JavaScript apps to the .NET Aspire app host.

When configuring secrets and passing environment variables to JavaScript-based apps, whether they are client or server apps, use parameters. For more information, see [.NET Aspire: External parameters—secrets](../fundamentals/external-parameters.md#secret-values).

### Use the OpenTelemetry JavaScript SDK

To export OpenTelemetry logs, traces, and metrics from a Node.js server app, you use the [OpenTelemetry JavaScript SDK](https://opentelemetry.io/docs/languages/js/).

For a complete example of a Node.js server app using the OpenTelemetry JavaScript SDK, you can refer to the [Code Samples: .NET Aspire Node.js sample](/samples/dotnet/aspire-samples/aspire-nodejs) page. Consider the sample's _instrumentation.js_ file, which demonstrates how to configure the OpenTelemetry JavaScript SDK to export logs, traces, and metrics:

:::code language="javascript" source="~/aspire-samples/samples/AspireWithNode/NodeFrontend/instrumentation.js":::

> [!TIP]
> To configure the .NET Aspire dashboard OTEL CORS settings, see the [.NET Aspire dashboard OTEL CORS settings](../fundamentals/dashboard/configuration.md#otlp-cors) page.
## Summary

While there are several considerations that are beyond the scope of this article, you learned how to build .NET Aspire projects that use Node.js and Node Package Manager (`npm`). You also learned how to use the <xref:Aspire.Hosting.NodeAppHostingExtension.AddNpmApp%2A> APIs to host Node.js apps and apps that execute from a _package.json_ file, respectively. Finally, you learned how to use the `npm` CLI to create Angular, React, and Vue client apps, and how to configure them to run on different ports.

## See also

- [Code Samples: .NET Aspire with Angular, React, and Vue](/samples/dotnet/aspire-samples/aspire-angular-react-vue)
- [Code Samples: .NET Aspire Node.js App](/samples/dotnet/aspire-samples/aspire-nodejs)
1 change: 1 addition & 0 deletions docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ items:
href: fundamentals/app-host-overview.md
- name: Orchestrate Node.js apps in .NET Aspire
href: get-started/build-aspire-apps-with-nodejs.md
displayName: node.js,node,express,typescript,javascript,spa,client-side,server-side
- name: Orchestrate Python apps in .NET Aspire
href: get-started/build-aspire-apps-with-python.md
- name: Add Dockerfiles to the app model
Expand Down

0 comments on commit 296ef57

Please sign in to comment.