How to use npm with ASP.NET Core

By publishing your whole node_modules folder you are deploying far more files than you will actually need in production.

Instead, use a task runner as part of your build process to package up those files you require, and deploy them to your wwwroot folder. This will also allow you to concat and minify your assets at the same time, rather than having to serve each individual library separately.

You can then also completely remove the FileServer configuration and rely on UseStaticFiles instead.

Currently, gulp is the VS task runner of choice. Add a gulpfile.js to the root of your project, and configure it to process your static files on publish.

For example, you can add the following scripts section to your project.json:

 "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
  },

Which would work with the following gulpfile (the default when scaffolding with yo):

/// <binding Clean='clean'/>
"use strict";

var gulp = require("gulp"),
    rimraf = require("rimraf"),
    concat = require("gulp-concat"),
    cssmin = require("gulp-cssmin"),
    uglify = require("gulp-uglify");

var webroot = "./wwwroot/";

var paths = {
    js: webroot + "js/**/*.js",
    minJs: webroot + "js/**/*.min.js",
    css: webroot + "css/**/*.css",
    minCss: webroot + "css/**/*.min.css",
    concatJsDest: webroot + "js/site.min.js",
    concatCssDest: webroot + "css/site.min.css"
};

gulp.task("clean:js", function (cb) {
    rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {
    rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css"]);

gulp.task("min:js", function () {
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

gulp.task("min:css", function () {
    return gulp.src([paths.css, "!" + paths.minCss])
        .pipe(concat(paths.concatCssDest))
        .pipe(cssmin())
        .pipe(gulp.dest("."));
});

gulp.task("min", ["min:js", "min:css"]);

enter image description here

  • Using npm for managing client-side libraries is a good choice (as opposed to Bower or NuGet), you're thinking in the right direction :)
  • Split server-side (ASP.NET Core) and client-side (e.g. Angular 2, Ember, React) projects into separate folders (otherwise your ASP.NET project may have lots of noise - unit tests for the client-side code, node_modules folder, build artifacts, etc.). Front-end developers working in the same team with you will thank you for that :)
  • Restore npm modules at the solution level (similarly how you restore packages via NuGet - not into the project's folder), this way you can have unit and integration tests in a separate folder as well (as opposed to having client-side JavaScript tests inside your ASP.NET Core project).
  • Use might not need FileServer, having StaticFiles should suffice for serving static files (.js, images, etc.)
  • Use Webpack to bundle your client-side code into one or more chunks (bundles)
  • You might not need Gulp/Grunt if you're using a module bundler such as Webpack
  • Write build automation scripts in ES2015+ JavaScript (as opposed to Bash or PowerShell), they will work cross-platform and be more accessible to a variety of web developers (everyone speaks JavaScript nowadays)
  • Rename wwwroot to public, otherwise the folder structure in Azure Web Apps will be confusing (D:\Home\site\wwwroot\wwwroot vs D:\Home\site\wwwroot\public)
  • Publish only the compiled output to Azure Web Apps (you should never push node_modules to a web hosting server). See tools/deploy.js as an example.

Visit ASP.NET Core Starter Kit on GitHub (disclaimer: I'm the author)