7

I'm working on an ASP.NET Core 3.1 application and decided to use npm to manage front end libraries, right now they should be few, but that might change in the future.

I have seen several similar questions, but they all seem to be a little outdated:

How to use NPM and install packages inside Visual Studio 2017?

How to use npm with ASP.NET Core

I intend to use npm to install the required libraries on the CI environment, I remember being able to integrate npm commands into the dotnet ones and would like to know if it is possible/recommendable.

What is the recommended approach to use npm in this newer version of ASP.NET Core?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Luiso
  • 4,173
  • 2
  • 37
  • 60
  • I use Visual Studio code for all frontend work and 'npm insall packagename' You can do same thing in Visual Studio via nuget console command line just make sure you are in righr folder. – JWP Mar 21 '20 at 23:48
  • 1
    You don't have to integrate npm into dotnet. You can use post and pre build scripts to achieve that. – Eldar Mar 22 '20 at 08:54

3 Answers3

6

I suggest using Yarn for two reasons:

  • For your use case, it is a drop in replacement for npm.
  • An existing Nuget package, Yarn.MSBuild, integrates Yarn into MSBuild.

Yarn.MSBuild allows you to specify Yarn commands in your .csproj. These commands run when you build your project. For example, to install front end packages on build:

  1. Add a reference to Yarn.MSBuild in your .csproj:

    <ItemGroup>
      <PackageReference Include="Yarn.MSBuild" Version="*" />
    </ItemGroup>
    
  2. Add a YarnBuildCommand property:

    <PropertyGroup>
      <YarnBuildCommand Condition="'$(Configuration)' == 'Release'">install</YarnBuildCommand>
    </PropertyGroup>
    

In the above example, yarn install runs when you build your project in release configuration. You asked specifically about building in CI using dotnet - with this setup, when you run dotnet build -c Release in CI, your front end packages are installed.

Note that by default, the command executes in your .csproj's directory. You can change this by adding a YarnWorkingDir property:

<PropertyGroup>
  <YarnWorkingDir>$(MSBuildProjectDirectory)/wwwroot/</YarnWorkingDir>
</PropertyGroup>
JeremyTCD
  • 695
  • 1
  • 6
  • 11
1

After some research, I ended up using my approach.
I created a Node folder on my web project to hold all the things node/npm, installed all the packages from there and also added gulpfile.js in it. I made the copying of the CSS and JS files I needed part of the build process like this:

<Target Name="ImportLibsAndStyles" BeforeTargets="Build">
    <Exec WorkingDirectory="./Node" Command="gulp build" />
</Target>

and I intend to make the bundling and minification happen on the CI server before deploy. I found this approach easier and with less conofiguration, if anyone can make improvements on it they will be greatly appreciated. I'm not closing the question in the hopes that more people will keep on adding.

Luiso
  • 4,173
  • 2
  • 37
  • 60
0

i am working with asp.net core 3.0 for api and i am using react for front-end

did you try to add your startup.cs

 app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseReactDevelopmentServer(npmScript: "start");
            }
        });

When you start your solution .net will start your front-end project

and my .csproj file like this

  <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\**" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Migrations\" />
  </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 prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  </Target>

  <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)build\**" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>