Skip to content

Commit ad6efe8

Browse files
eerhardtdavidfowl
andauthored
Refactor NodeJs Integration (#12530)
* Refactor JavaScript Integration - Obsolete AddNpmApp. - Add JavaScriptAppResource and AddJavaScriptApp extension method - Refactor AddViteApp to be a specialization of AddJavaScriptApp - Replace NodeInstallerResource with JavaScriptInstallerResource - Add JavaScriptPackageManagerAnnotation to handle different package managers - Replace JavaScriptRunCommandAnnotation with JavaScriptRunScriptAnnotation - Replace JavaScriptBuildCommandAnnotation with JavaScriptBuildScriptAnnotation Contributes to #8350 * Default install command args in publish mode. * Only use clean installs when the lock file exists in publish mode. * Address copilot feedback * More PR feedback * Fix PublishAsDockerFile to always clear the args when it is called, even if it is called a second time. * Update npm install command comment in AppHost.cs Clarified npm install command requirement for clean install. --------- Co-authored-by: David Fowler <davidfowl@gmail.com>
1 parent fe02826 commit ad6efe8

27 files changed

+674
-336
lines changed

playground/AspireWithJavaScript/AspireJavaScript.AppHost/AppHost.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,30 @@
33
var weatherApi = builder.AddProject<Projects.AspireJavaScript_MinimalApi>("weatherapi")
44
.WithExternalHttpEndpoints();
55

6-
builder.AddNpmApp("angular", "../AspireJavaScript.Angular")
7-
.WithNpm(install: true)
6+
builder.AddJavaScriptApp("angular", "../AspireJavaScript.Angular")
87
.WithReference(weatherApi)
98
.WaitFor(weatherApi)
109
.WithHttpEndpoint(env: "PORT")
1110
.WithExternalHttpEndpoints()
1211
.PublishAsDockerFile();
1312

14-
builder.AddNpmApp("react", "../AspireJavaScript.React")
15-
.WithNpm(install: true)
13+
builder.AddJavaScriptApp("react", "../AspireJavaScript.React")
1614
.WithReference(weatherApi)
1715
.WaitFor(weatherApi)
1816
.WithEnvironment("BROWSER", "none") // Disable opening browser on npm start
1917
.WithHttpEndpoint(env: "PORT")
2018
.WithExternalHttpEndpoints()
2119
.PublishAsDockerFile();
2220

23-
builder.AddNpmApp("vue", "../AspireJavaScript.Vue")
24-
.WithInstallCommand("npm", ["ci"]) // Use 'npm ci' for clean install
21+
builder.AddJavaScriptApp("vue", "../AspireJavaScript.Vue")
22+
.WithNpm(installCommand: "ci") // Use 'npm ci' for clean install, requires lock file
2523
.WithReference(weatherApi)
2624
.WaitFor(weatherApi)
2725
.WithHttpEndpoint(env: "PORT")
2826
.WithExternalHttpEndpoints()
2927
.PublishAsDockerFile();
3028

3129
var reactvite = builder.AddViteApp("reactvite", "../AspireJavaScript.Vite")
32-
.WithNpm(install: true)
3330
.WithReference(weatherApi)
3431
.WithEnvironment("BROWSER", "none")
3532
.WithExternalHttpEndpoints();

playground/AspireWithNode/AspireWithNode.AppHost/AppHost.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
var weatherapi = builder.AddProject<Projects.AspireWithNode_AspNetCoreApi>("weatherapi");
1212

13-
var frontend = builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
13+
var frontend = builder.AddJavaScriptApp("frontend", "../NodeFrontend", "watch")
1414
.WithReference(weatherapi)
1515
.WaitFor(weatherapi)
1616
.WithReference(cache)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Hosting.ApplicationModel;
5+
6+
namespace Aspire.Hosting;
7+
8+
/// <summary>
9+
/// A resource that represents a JavaScript application.
10+
/// </summary>
11+
/// <param name="name">The name of the resource.</param>
12+
/// <param name="command">The command to execute.</param>
13+
/// <param name="workingDirectory">The working directory to use for the command.</param>
14+
public class JavaScriptAppResource(string name, string command, string workingDirectory)
15+
: ExecutableResource(name, command, workingDirectory), IResourceWithServiceDiscovery, IResourceWithContainerFiles;

src/Aspire.Hosting.NodeJs/JavaScriptBuildCommandAnnotation.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Hosting.ApplicationModel;
5+
6+
namespace Aspire.Hosting.NodeJs;
7+
8+
/// <summary>
9+
/// Represents the annotation for the JavaScript package manager's build script.
10+
/// </summary>
11+
/// <param name="scriptName">The name of the JavaScript package manager's build script.</param>
12+
/// <param name="args">The command line arguments for the JavaScript package manager's build script.</param>
13+
public sealed class JavaScriptBuildScriptAnnotation(string scriptName, string[]? args) : IResourceAnnotation
14+
{
15+
/// <summary>
16+
/// Gets the name of the script used to build.
17+
/// </summary>
18+
public string ScriptName { get; } = scriptName;
19+
20+
/// <summary>
21+
/// Gets the command-line arguments supplied to the build script.
22+
/// </summary>
23+
public string[] Args { get; } = args ?? [];
24+
}

src/Aspire.Hosting.NodeJs/JavaScriptInstallCommandAnnotation.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ namespace Aspire.Hosting.NodeJs;
88
/// <summary>
99
/// Represents the annotation for the JavaScript package manager's install command.
1010
/// </summary>
11-
/// <param name="command">The executable command name</param>
12-
/// <param name="args">The command line arguments for the JavaScript package manager's install command.</param>
13-
public sealed class JavaScriptInstallCommandAnnotation(string command, string[] args) : IResourceAnnotation
11+
/// <param name="args">
12+
/// The command line arguments for the JavaScript package manager's install command.
13+
/// This includes the command itself (i.e. "install").
14+
/// </param>
15+
public sealed class JavaScriptInstallCommandAnnotation(string[] args) : IResourceAnnotation
1416
{
1517
/// <summary>
16-
/// Gets the executable command name.
17-
/// </summary>
18-
public string Command { get; } = command;
19-
20-
/// <summary>
21-
/// Gets the command-line arguments supplied to the application.
18+
/// Gets the command-line arguments supplied to the JavaScript package manager.
2219
/// </summary>
2320
public string[] Args { get; } = args;
2421
}

src/Aspire.Hosting.NodeJs/NodeInstallerResource.cs renamed to src/Aspire.Hosting.NodeJs/JavaScriptInstallerResource.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
namespace Aspire.Hosting.NodeJs;
77

88
/// <summary>
9-
/// A resource that represents a package installer for a node app.
9+
/// A resource that represents a package installer for a JavaScript app.
1010
/// </summary>
1111
/// <param name="name">The name of the resource.</param>
1212
/// <param name="workingDirectory">The working directory to use for the command.</param>
13-
public class NodeInstallerResource(string name, string workingDirectory)
13+
public class JavaScriptInstallerResource(string name, string workingDirectory)
1414
: ExecutableResource(name, "node", workingDirectory);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Hosting.ApplicationModel;
5+
6+
namespace Aspire.Hosting.NodeJs;
7+
8+
/// <summary>
9+
/// Represents the annotation for the JavaScript package manager used in a resource.
10+
/// </summary>
11+
/// <param name="executableName">The name of the executable used to run the package manager.</param>
12+
/// <param name="runScriptCommand">The command used to run a script with the JavaScript package manager.</param>
13+
public sealed class JavaScriptPackageManagerAnnotation(string executableName, string? runScriptCommand) : IResourceAnnotation
14+
{
15+
/// <summary>
16+
/// Gets the executable used to run the JavaScript package manager.
17+
/// </summary>
18+
public string ExecutableName { get; } = executableName;
19+
20+
/// <summary>
21+
/// Gets the command used to run a script with the JavaScript package manager.
22+
/// </summary>
23+
public string? ScriptCommand { get; } = runScriptCommand;
24+
}

src/Aspire.Hosting.NodeJs/JavaScriptRunCommandAnnotation.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Hosting.ApplicationModel;
5+
6+
namespace Aspire.Hosting.NodeJs;
7+
8+
/// <summary>
9+
/// Represents the annotation for the script used during run mode in a JavaScript resource.
10+
/// </summary>
11+
/// <param name="scriptName">The name of the JavaScript package manager's run script.</param>
12+
/// <param name="args">The command line arguments for the JavaScript package manager's run script.</param>
13+
public sealed class JavaScriptRunScriptAnnotation(string scriptName, string[]? args) : IResourceAnnotation
14+
{
15+
/// <summary>
16+
/// Gets the name of the script to run.
17+
/// </summary>
18+
public string ScriptName { get; } = scriptName;
19+
20+
/// <summary>
21+
/// Gets the command-line arguments for the script.
22+
/// </summary>
23+
public string[] Args { get; } = args ?? [];
24+
}

0 commit comments

Comments
 (0)