将Angular的输出目录从wwwroot更改为ASP.NET中的另一个文件夹。

huangapple go评论56阅读模式
英文:

Change Angular output directory from wwwroot to another folder in ASP.NET

问题

目前,我的ASP .NET项目与Angular前端(在一个项目中)在发布时将Angular输出文件夹(dist内容)放在/wwwroot文件夹内。

现在,我不希望将输出放在wwwroot文件夹中,因为这样不够整洁。我希望将其放在根目录下的不同文件夹中,例如ClientApp/dist,并在打开基本URL时提供该文件夹:http://localhost:5000

我不知道需要编辑多少个文件才能实现这一目标,我尝试过在该文件夹上设置一个静态文件目录,但那样会导致Angular无法正常工作。

目前:

app.UseDefaultFiles();
app.UseStaticFiles();

我尝试过:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
           Path.Combine(builder.Environment.ContentRootPath, "ClientApp")),
    RequestPath = "/"
});

我需要编辑多少个文件才能完全更改前端路径,将其放在/wwwroot之外的不同文件夹中,或者至少放在/wwwroot/dist中。

英文:

Currently my ASP .NET project with angular frontend (inside one Project) is putting the Angular output folder (dist content) inside /wwwroot folder when published.

Website_ASP.exe
web.config
wwwroot
    index.html
    scripts ....
    etc..

Now I don't want the output inside wwwroot folder at all. this way it's just not tidy and clean. I want it inside a different folder in root like ClientApp/dist and serve that when opening base url : http://localhost:5000.

I don't know which and how many files I need to edit for this to happen, I've tried setting a staticfile directory on said folder but then the Angular doesn't work properly.

Currently:

app.UseDefaultFiles();
app.UseStaticFiles();

and I have tried :

app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
       Path.Combine(builder.Environment.ContentRootPath, "ClientApp")),
RequestPath = "/"
});

How many files do I need to edit in Angular and ASP to completely change the frontend path to a different folder outside wwwroot, or at the very least inside wwwroot/dist.

答案1

得分: 1

<h3>My test sample:</h3>

**Program.cs or your Startup.cs file**

using Microsoft.Extensions.FileProviders;

namespace AngularSPA
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddControllersWithViews();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            //app.UseStaticFiles();
            // ==========> change here
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                Path.Combine(app.Environment.ContentRootPath, "ClientApp", "dist")),
                RequestPath = ""
            });
            app.UseRouting();

            app.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
    
            app.MapFallbackToFile("index.html");
    
            app.Run();
        }
    }
}

**angular.json**

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "AngularSPA": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "progress": false,
            //"outputPath": "dist",
            //  ======> change here
            "outputPath": "../ClientApp/dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "allowedCommonJsDependencies": [
              "oidc-client"
            ],
            "assets": [
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "AngularSPA:build:production"
            },
            "development": {
              "browserTarget": "AngularSPA:build:development",
              "proxyConfig": "proxy.conf.js"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "AngularSPA:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist-server",
            "main": "src/main.ts",
            "tsConfig": "tsconfig.server.json"
          },
          "configurations": {
            "dev": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": true
            },
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false
            }
          }
        }
      }
    }
  },
  "defaultProject": "AngularSPA",
  "cli": {
    "analytics": false
  }
}

**.csproj**

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <SpaRoot>ClientApp\</SpaRoot>
    <SpaProxyServerUrl>https://localhost:44440</SpaProxyServerUrl>
    <SpaProxyLaunchCommand>npm start</SpaProxyLaunchCommand>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaProxy" Version="7.0.3" />
  </ItemGroup>
  <!-- ==============> add code here to include client\dist folder -->
  <ItemGroup>
    <!-- Don't publish the SPA source files, but do show them in the project files list -->
    <Content Remove="$(SpaRoot)**" />
    <None Remove="$(SpaRoot)**" />
    <None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />

    <Content Include="ClientApp\dist\**">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    <!-- Ensure Node.js is installed -->
    <Exec Command="node --version" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command

<details>
<summary>英文:</summary>

&lt;h3&gt;My test sample:&lt;/h3&gt;

**Program.cs or your Startup.cs file**

    using Microsoft.Extensions.FileProviders;
    
    namespace AngularSPA
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = WebApplication.CreateBuilder(args);
    
                // Add services to the container.
                builder.Services.AddControllersWithViews();
    
                var app = builder.Build();
    
                // Configure the HTTP request pipeline.
                if (!app.Environment.IsDevelopment())
                {
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                //app.UseStaticFiles();
                // ==========&gt; change here
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(
                    Path.Combine(app.Environment.ContentRootPath, &quot;ClientApp&quot;, &quot;dist&quot;)),
                    RequestPath = &quot;&quot;
                });
                app.UseRouting();
    
    
                app.MapControllerRoute(
                    name: &quot;default&quot;,
                    pattern: &quot;{controller}/{action=Index}/{id?}&quot;);
    
                app.MapFallbackToFile(&quot;index.html&quot;);
    
                app.Run();
            }
        }
    }

**angular.json**

    {
      &quot;$schema&quot;: &quot;./node_modules/@angular/cli/lib/config/schema.json&quot;,
      &quot;version&quot;: 1,
      &quot;newProjectRoot&quot;: &quot;projects&quot;,
      &quot;projects&quot;: {
        &quot;AngularSPA&quot;: {
          &quot;projectType&quot;: &quot;application&quot;,
          &quot;schematics&quot;: {
            &quot;@schematics/angular:application&quot;: {
              &quot;strict&quot;: true
            }
          },
          &quot;root&quot;: &quot;&quot;,
          &quot;sourceRoot&quot;: &quot;src&quot;,
          &quot;prefix&quot;: &quot;app&quot;,
          &quot;architect&quot;: {
            &quot;build&quot;: {
              &quot;builder&quot;: &quot;@angular-devkit/build-angular:browser&quot;,
              &quot;options&quot;: {
                &quot;progress&quot;: false,
                //&quot;outputPath&quot;: &quot;dist&quot;,
                //  ======&gt; change here
                &quot;outputPath&quot;: &quot;../ClientApp/dist&quot;,
                &quot;index&quot;: &quot;src/index.html&quot;,
                &quot;main&quot;: &quot;src/main.ts&quot;,
                &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
                &quot;tsConfig&quot;: &quot;tsconfig.app.json&quot;,
                &quot;allowedCommonJsDependencies&quot;: [
                  &quot;oidc-client&quot;
                ],
                &quot;assets&quot;: [
                  &quot;src/assets&quot;
                ],
                &quot;styles&quot;: [
                  &quot;node_modules/bootstrap/dist/css/bootstrap.min.css&quot;,
                  &quot;src/styles.css&quot;
                ],
                &quot;scripts&quot;: []
              },
              &quot;configurations&quot;: {
                &quot;production&quot;: {
                  &quot;budgets&quot;: [
                    {
                      &quot;type&quot;: &quot;initial&quot;,
                      &quot;maximumWarning&quot;: &quot;500kb&quot;,
                      &quot;maximumError&quot;: &quot;1mb&quot;
                    },
                    {
                      &quot;type&quot;: &quot;anyComponentStyle&quot;,
                      &quot;maximumWarning&quot;: &quot;2kb&quot;,
                      &quot;maximumError&quot;: &quot;4kb&quot;
                    }
                  ],
                  &quot;fileReplacements&quot;: [
                    {
                      &quot;replace&quot;: &quot;src/environments/environment.ts&quot;,
                      &quot;with&quot;: &quot;src/environments/environment.prod.ts&quot;
                    }
                  ],
                  &quot;outputHashing&quot;: &quot;all&quot;
                },
                &quot;development&quot;: {
                  &quot;buildOptimizer&quot;: false,
                  &quot;optimization&quot;: false,
                  &quot;vendorChunk&quot;: true,
                  &quot;extractLicenses&quot;: false,
                  &quot;sourceMap&quot;: true,
                  &quot;namedChunks&quot;: true
                }
              },
              &quot;defaultConfiguration&quot;: &quot;production&quot;
            },
            &quot;serve&quot;: {
              &quot;builder&quot;: &quot;@angular-devkit/build-angular:dev-server&quot;,
              &quot;configurations&quot;: {
                &quot;production&quot;: {
                  &quot;browserTarget&quot;: &quot;AngularSPA:build:production&quot;
                },
                &quot;development&quot;: {
                  &quot;browserTarget&quot;: &quot;AngularSPA:build:development&quot;,
                  &quot;proxyConfig&quot;: &quot;proxy.conf.js&quot;
                }
              },
              &quot;defaultConfiguration&quot;: &quot;development&quot;
            },
            &quot;extract-i18n&quot;: {
              &quot;builder&quot;: &quot;@angular-devkit/build-angular:extract-i18n&quot;,
              &quot;options&quot;: {
                &quot;browserTarget&quot;: &quot;AngularSPA:build&quot;
              }
            },
            &quot;test&quot;: {
              &quot;builder&quot;: &quot;@angular-devkit/build-angular:karma&quot;,
              &quot;options&quot;: {
                &quot;main&quot;: &quot;src/test.ts&quot;,
                &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
                &quot;tsConfig&quot;: &quot;tsconfig.spec.json&quot;,
                &quot;karmaConfig&quot;: &quot;karma.conf.js&quot;,
                &quot;assets&quot;: [
                  &quot;src/assets&quot;
                ],
                &quot;styles&quot;: [
                  &quot;src/styles.css&quot;
                ],
                &quot;scripts&quot;: []
              }
            },
            &quot;server&quot;: {
              &quot;builder&quot;: &quot;@angular-devkit/build-angular:server&quot;,
              &quot;options&quot;: {
                &quot;outputPath&quot;: &quot;dist-server&quot;,
                &quot;main&quot;: &quot;src/main.ts&quot;,
                &quot;tsConfig&quot;: &quot;tsconfig.server.json&quot;
              },
              &quot;configurations&quot;: {
                &quot;dev&quot;: {
                  &quot;optimization&quot;: true,
                  &quot;outputHashing&quot;: &quot;all&quot;,
                  &quot;sourceMap&quot;: false,
                  &quot;namedChunks&quot;: false,
                  &quot;extractLicenses&quot;: true,
                  &quot;vendorChunk&quot;: true
                },
                &quot;production&quot;: {
                  &quot;optimization&quot;: true,
                  &quot;outputHashing&quot;: &quot;all&quot;,
                  &quot;sourceMap&quot;: false,
                  &quot;namedChunks&quot;: false,
                  &quot;extractLicenses&quot;: true,
                  &quot;vendorChunk&quot;: false
                }
              }
            }
          }
        }
      },
      &quot;defaultProject&quot;: &quot;AngularSPA&quot;,
      &quot;cli&quot;: {
        &quot;analytics&quot;: false
      }
    }


**.csproj**

    &lt;Project Sdk=&quot;Microsoft.NET.Sdk.Web&quot;&gt;
    
      &lt;PropertyGroup&gt;
        &lt;TargetFramework&gt;net7.0&lt;/TargetFramework&gt;
        &lt;Nullable&gt;enable&lt;/Nullable&gt;
        &lt;IsPackable&gt;false&lt;/IsPackable&gt;
        &lt;SpaRoot&gt;ClientApp\&lt;/SpaRoot&gt;
        &lt;SpaProxyServerUrl&gt;https://localhost:44440&lt;/SpaProxyServerUrl&gt;
        &lt;SpaProxyLaunchCommand&gt;npm start&lt;/SpaProxyLaunchCommand&gt;
        &lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
      &lt;/PropertyGroup&gt;
    
      &lt;ItemGroup&gt;
        &lt;PackageReference Include=&quot;Microsoft.AspNetCore.SpaProxy&quot; Version=&quot;7.0.3&quot; /&gt;
      &lt;/ItemGroup&gt;
      &lt;!-- ==============&gt; add code here to include client\dist folder --&gt;
      &lt;ItemGroup&gt;
        &lt;!-- Don&#39;t publish the SPA source files, but do show them in the project files list --&gt;
        &lt;Content Remove=&quot;$(SpaRoot)**&quot; /&gt;
        &lt;None Remove=&quot;$(SpaRoot)**&quot; /&gt;
        &lt;None Include=&quot;$(SpaRoot)**&quot; Exclude=&quot;$(SpaRoot)node_modules\**&quot; /&gt;

        &lt;Content Include=&quot;ClientApp\dist\**&quot;&gt;
          &lt;CopyToOutputDirectory&gt;PreserveNewest&lt;/CopyToOutputDirectory&gt;
        &lt;/Content&gt;
      &lt;/ItemGroup&gt;
    
      &lt;Target Name=&quot;DebugEnsureNodeEnv&quot; BeforeTargets=&quot;Build&quot; Condition=&quot; &#39;$(Configuration)&#39; == &#39;Debug&#39; And !Exists(&#39;$(SpaRoot)node_modules&#39;) &quot;&gt;
        &lt;!-- Ensure Node.js is installed --&gt;
        &lt;Exec Command=&quot;node --version&quot; ContinueOnError=&quot;true&quot;&gt;
          &lt;Output TaskParameter=&quot;ExitCode&quot; PropertyName=&quot;ErrorCode&quot; /&gt;
        &lt;/Exec&gt;
        &lt;Error Condition=&quot;&#39;$(ErrorCode)&#39; != &#39;0&#39;&quot; Text=&quot;Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE.&quot; /&gt;
        &lt;Message Importance=&quot;high&quot; Text=&quot;Restoring dependencies using &#39;npm&#39;. This may take several minutes...&quot; /&gt;
        &lt;Exec WorkingDirectory=&quot;$(SpaRoot)&quot; Command=&quot;npm install&quot; /&gt;
      &lt;/Target&gt;
    
      &lt;Target Name=&quot;PublishRunWebpack&quot; AfterTargets=&quot;ComputeFilesToPublish&quot;&gt;
        &lt;!-- As part of publishing, ensure the JS resources are freshly built in production mode --&gt;
        &lt;Exec WorkingDirectory=&quot;$(SpaRoot)&quot; Command=&quot;npm install&quot; /&gt;
        &lt;Exec WorkingDirectory=&quot;$(SpaRoot)&quot; Command=&quot;npm run build -- --configuration production&quot; /&gt;
    
        &lt;!-- Include the newly-built files in the publish output --&gt;
        &lt;ItemGroup&gt;
          &lt;DistFiles Include=&quot;$(SpaRoot)dist\**; $(SpaRoot)dist-server\**&quot; /&gt;
          &lt;ResolvedFileToPublish Include=&quot;@(DistFiles-&gt;&#39;%(FullPath)&#39;)&quot; Exclude=&quot;@(ResolvedFileToPublish)&quot;&gt;
            &lt;RelativePath&gt;wwwroot\%(RecursiveDir)%(FileName)%(Extension)&lt;/RelativePath&gt;
            &lt;CopyToPublishDirectory&gt;PreserveNewest&lt;/CopyToPublishDirectory&gt;
            &lt;ExcludeFromSingleFile&gt;true&lt;/ExcludeFromSingleFile&gt;
          &lt;/ResolvedFileToPublish&gt;
        &lt;/ItemGroup&gt;
      &lt;/Target&gt;
    &lt;/Project&gt;

&lt;h3&gt;My test result&lt;/h3&gt;

[![enter image description here][1]][1]

[![enter image description here][2]][2]


  [1]: https://i.stack.imgur.com/ldiIv.png
  [2]: https://i.stack.imgur.com/w9U4i.gif

</details>



huangapple
  • 本文由 发表于 2023年2月13日 22:44:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75437392.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定