The Freshest Blend

Building the latest version of Bootstrap with Node Package Manager (npm)

by JamesQMurphy | June 2, 2019

Adding npm and package.json

In my previous post, I created a boilerplate MVC web project. The goal was simply to break ground... the first step on my thousand-mile journey. In more practical terms, I wanted to establish the base toolset that would be needed to build the project. I also wanted to keep that toolset minimal and generic... anyone who wanted to build the project shouldn’t need to install dozens of specialized tools. So far, the only pre-requisites are Visual Studio 2017 and ASP.NET Core (which can be installed at the same time).

Enter a third pre-requisite: Node.JS. This is not an unreasonable pre-requisite; chances are, if you are a developer, then you already have it. Node.JS is also a pre-requisite for frameworks such as Angular and React. In fact, if you want to build Angular or React applications in Visual Studio, then you need to install Node.JS yourself. Node.JS is also used to build a custom Bootstrap.css file (it can be done via NuGet, but Node.JS is the primary way to do it). I'll cover building Bootstrap in a later post; for now, I'll just use Node.JS (specifically, Node Package Manager) to download Bootstrap.css and copy it to the proper folder.

creating package.json

Saving it creates node_modules, but not necessarily package-lock.json running npm install does

Tried this at first

"copy-jquery" : "xcopy "node_modules/jquery/dist/*.*" "wwwroot/dist/jquery/*.*" /F /Y"

Using xcopy works, but it isn''t recommended since it''s an OS command.

Tried using npx, but it brought in a whole bunch of packages, plus it flagged a package for audit (regex denial-of-service)

Used copyfiles:

"copy-jquery": "copyfiles node_modules/jquery/dist/** wwwroot/dist/jquery --up 3 --verbose"

Works, but installs over 70 packages!

Made additional for jquery-validation and jquery-validation-unobtrusive. And bootstrap.

This works:

  "version": "1.0.0",
  "name": "jamesqmurphy.web",
  "private": true,
  "scripts": {
    "copydist": "npm run copydist-bootstrap && npm run copydist-jquery && npm run copydist-jquery-validation && npm run copydist-jquery-validation-unobtrusive",
    "copydist-bootstrap": "copyfiles node_modules/bootstrap/dist/** wwwroot/dist/lib/bootstrap --up 2 --verbose",
    "copydist-jquery": "copyfiles node_modules/jquery/dist/** wwwroot/dist/lib/jquery --up 2 --verbose",
    "copydist-jquery-validation": "copyfiles node_modules/jquery-validation/dist/** wwwroot/dist/lib/jquery-validation --up 2 --verbose",
    "copydist-jquery-validation-unobtrusive": "copyfiles node_modules/jquery-validation-unobtrusive/dist/** wwwroot/dist/lib/jquery-validation-unobtrusive --up 2 --verbose"
  "devDependencies": {
    "bootstrap": "^4.3.1",
    "copyfiles": "^2.1.0",
    "jquery": "^3.4.1",
    "jquery-validation": "^1.19.0",
    "jquery-validation-unobtrusive": "^3.2.11",
    "popper.js": "^1.15.0"


Removed dist from project, removed package.json and package-lock.json Added **/wwwroot/dist to .gitignore file

Added dist to published files using ResolvedFileToPublish based on

Updated _Layout.cshtml and _ValidationScriptsPartial.cshtml to point to ~/dist/lib instead of ~/lib