Dave Paquette

Caffeine Driven Development

Integrating Gulp and Bower with Visual Studio Online Hosted Builds

April 8, 2015

In previous posts, I talked about using Gulp to manage client side builds and using Bower as a package manager for client side packages.

Shane Courtrille asked me if I could do a follow up post showing how to integrate these concepts with a build hosted on Visual Studio Online. It took me some time and a long list of failures to get this working, but here it is.

Build Server Requirements

In order to successfully use Gulp and Bower on your build server, you will need both Node and Git installed. Luckily, the hosted Visual Studio Online build controllers already have these tools installed. If you are hosting your own build server, you will need to install node.js and Git on the server. When installing these tools, make sure you login to the server as the same user that executes the build process.

Adding a PreBuild Script to Visual Studio Build

The next step is to ensure that we call the default gulp task before attempting to compile our application with msbuild. Using the gulp file from the blog post on using Bower, calling the default gulp task will ensure that all bower packages are installed and all our JavaScript and CSS bundles are created and copied to the expected locations.

Gulp requires a number of node packages to be installed. Before we can call gulp, we need to call npm install to ensure that those packages have been downloaded locally on the build controller.

The easiest way to do this is to create a simple PowerShell script that is executed as a Pre Build step for our Visual Studio build. Pre Build Steps are only available if GitTemplate.12.xaml as your build process template.

image

I added a PreBuild.ps1 script to the root folder for my solution and added that file as my Pre-build script path.

Push-Location "BowerInVS2013"
& npm install
& gulp default
Pop-Location
Push-Location "BowerInVS2013"
& npm install
& gulp default
Pop-Location

 

In theory, that’s all we needed to do. Unfortunately, theory and practice are rarely align…especially when working with Visual Studio builds.

When I tried to run this build in Visual Studio Online, I got the following error:

Error: ENOENT, stat ‘C:\Users\buildguest\AppData\Roaming\npm’

For some reason, the buildguests user that runs the build on Visual Studio online has trouble with the call to npm install. A quick workaround for this is to create the missing npm folder if it does not exist.

$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& gulp default
Pop-Location
$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& gulp default
Pop-Location

 

This brings us to my next failure: Gulp is not installed globally on the hosted build controller so the call to gulp default failed.

To solve this I added added a gulp script to my npm package file (package.json). This gives me a convenient way to call gulp via npm.

{
  "name": "BowerInVS2013",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    "del": "^1.1.1",
    "gulp": "^3.8.10",
    "gulp-bower": "0.0.7",
    "gulp-concat": "^2.4.2",
    "gulp-copy": "0.0.2",
    "gulp-minify-css": "^0.3.11",
    "gulp-sourcemaps": "^1.3.0",
    "gulp-uglify": "^1.0.2"
  },
  "scripts": {
    "gulp": "./node_modules/.bin/gulp"
  }
}
{
  "name": "BowerInVS2013",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    "del": "^1.1.1",
    "gulp": "^3.8.10",
    "gulp-bower": "0.0.7",
    "gulp-concat": "^2.4.2",
    "gulp-copy": "0.0.2",
    "gulp-minify-css": "^0.3.11",
    "gulp-sourcemaps": "^1.3.0",
    "gulp-uglify": "^1.0.2"
  },
  "scripts": {
    "gulp": "./node_modules/.bin/gulp"
  }
}

The updated PreBuild.ps1 script looks like this:

$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& npm gulp
Pop-Location
$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& npm gulp
Pop-Location

 

We still get one warning from npm and I’m not sure how to fix it.

npm WARN deprecated deflate-crc32-stream@0.1.2: module has been merged into crc32-stream

This warning seems to be a known issue with node on Windows and in this case it seems to be safe to ignore it. The compiled output from the build contains everything that we expect.

Conclusion

With a few minor workarounds, we are able to get Bower and Gulp working with the Visual Studio Online hosted build controllers.

Prairie Dev Con Wrap Up

March 4, 2015

I just returned from Prairie Dev Con (PrDC) in Winnipeg. As with every previous Prairie Dev Con, I was not disappointed. Every PrDC I have attended has been fantastic and yet each year it continues to get better.

My Favorite Session

I attended a number of sessions related to improving the performance of web applications. I learned something in every session, but Nik Molnar’s session on Full Stack Web Performance particularly stood out for me. I picked up countless web performance tips that I was able to apply to my current project as soon as I got back to work. Some of the tips he covered can be found at http://jankfree.org/.

My Sessions

I was fortunate enough to present two sessions. I have posted the slides on SlideShare for anyone who is interested.

The State of Entity Framework

Visual Studio 2013 with Link and Bower

Sessions I did not get to attend

There are two sessions that everyone was talking about and I was unable to attend because they were at the same time as my sessions. Luckily for me (and you), these sessions were recorded and are available on YouTube:

The Empathy Equation – Dave Mosher

The 5 Stages of Entrepreneurial Grief – Derick Bailey