This tutorial will walk you through updating your project to using the latest versions of Node, Gulp and Visual Studio 2019. I will be talking about them together, as it is a common recipe, and after a good few hours of blood sweat and stackoverflow/gitrepo searches, you can learn from my pain.
By following this tutorial, you will be able to run your project in Task Runner Explorer in Visual Studio 2019. Let’s go.
Warning: If you are in the middle of a sprint, maybe now is not quite the time to update. you’ll need a good hour to make sure everything runs smoothly, and you have time to bug fix
Hooray Hooray, with NodeJs’ recent announcement of Node 12 hitting LTS, it’s well worth revisiting legacy projects. Long Term Support essentially means that this version of Node will get bug and security fixes for a Long time. In v12’s case, it will be safe to use until April 2022, meaning updating to it will be all you need to do for another 2 and a bit years.
Current Release windows
If you are running your projects on Node 10, you are good for another year, so no hurry to update, especially if you are using conflict prone older packages.
However, if you are on Node 8 or lower 😬, you will have to upgrade by New Years Eve 2019 to maintain the security of your project.
Node 13 is out too. Why not update to that instead?
Odd numbers of Node versions are experimental branches that won’t receive long term support. If you want to dick around with the latest node has to offer, by all means run your project on Node 13 (although, definitely consider nvm). If you are running a production project for a client or business, stick with the LTS releases.
Pick your installation flavour:
A) Standard install(without nvm) simply download and install
B) nvm installation assuming you are already using nvm(install instructions in the link if not), adding node 12 is still a simple process:
nvm list available
in the long term support row, remember the latest 12 version, so in the example above, it’s 12.13.0
nvm install 12.13.0
// make yourself a cuppa
nvm use 12.13.0
You are now the proud user of a Node.JS 12 instance
Great, but here is the first hiccup, Gulp 3 will start to error
const { Math, Object, Reflect } = primordials;
^
ReferenceError: primordials is not defined
Gulp 3 has dependencies that Node 12 cannot deal with. So next step, is getting gulp updated to version 4, the latest and greatest version of Gulp.
Latest and Greatest, but does need a bit of wrangling
So open up your package.json
for your project and replace your current gulp (3.x.x
) with the latest stable gulp release, at time of writing its ^4.0.2
If you want to use Gulp 4 with task manager explorer in visual studio 2019 then you will need to install it globally too with npm install [email protected]
If you don’t do this Visual studio 2019 will fail to detect gulp, and won’t show the tasks as available.
Once we are done with that, we need to update our gulp dependencies, with is a whole different ball game. Each dependency has its own hell to go through, but a quick check of the inter webs will help you with your particular modules.
However… here are the two that gave me the most grief:
As great as SASS and Gulp are, I cannot think of a single new install for gulp-sass/node-sass that have gone smoothly. Keep a cool head during this process, you will get it running — eventually. The best advice I can give is:
1. Nuke your node_modules directory. Delete it, remove it, wipe it. If a trace of it exists, it will haunt you and fail.
2. Replace with the new version in your package.json
at time or writing I am using ^4.0.2
, which is conveniently the same as, and I am assuming connected to, the version of Gulp you are using.
3. If you are still getting errors, make sure you are running gulp from a console with admin permissions.
4. Read the errors carefully, it may look like a bit wall of text, but there will be a clue as to what’s missing in the message.
This is a bit of a weird dependency and is really only applicable to projects using special frameworks like .NET, so most people can skip it. However if you are using gulp-msbuild
I have one easy tip: remove it, and replace it with [msbuild](https://github.com/jhaker/nodejs-msbuild)
. It’s a much happier, and cleaner package, it makes more sense, and it seems to fail less.
// ReadMe in msbuild repo: https://github.com/jhaker/nodejs-msbuild
var gulp = require("gulp");
var _msbuild = require('msbuild');
var config = require("./gulp-config.json"); // use this to store all your .csproj/.sln related project details
const msbuildTask = function (cb) {
var msbuild = new _msbuild(cb);
msbuild.sourcePath = config.project;
msbuild.config('version', '16.0');
msbuild.configuration = config.buildConfiguration;
msbuild.outputPath = config.websiteRoot;
// msbuild.overrideParams.push('/clp:ErrorsOnly'); // enable to make verbose
msbuild.overrideParams.push('/p:outputPath=' + config.websiteRoot);
msbuild.build();
};
exports.msbuildTask = series(msbuildTask);
msbuildTask.js
With all that added to your package.json, you should be able to run npm install
. If everything has run happily, you should have no errors, and even better, you should have no vulnerabilities.
Given the advice above you should be in good stead, basic migration isn’t too tricky, as it’s more of a syntax shift than a complete rewrite. If you come up with issues with a particular gulp plugin, it is usually the case that you need to replace it with a more modern gulp plugin. gulp-util
has beeen depreceated in favour of individual plugins, so just keep an eye on the console when you run gulp and it will tell you what needs fixing.
// Gulp 3 Task
var gulp = require("gulp");
var rename = require('gulp-rename');
var coreScripts = []; // your main scripts
gulp.task('scripts', function () {
return gulp.src(coreScripts)
.pipe(concat('global.js'))
.pipe(gulp.dest('blah/html/js'))
.pipe(rename('global.min.js'))
.pipe(gulp.dest('blah/html/js'))
//.pipe(browserSync.reload({
// stream: true
//}))
});
// Gulp 4 Task
const { src, dest, series, parallel } = require('gulp');
const rename = require('gulp-rename');
const coreScripts = []; // your main scripts
const scriptsTask = function () {
return src(coreScripts)
.pipe(concat('global.js'))
.pipe(dest('blah/html/js'))
.pipe(rename({ extname: '.min.js' }))
.pipe(dest('blah/html/js'));
};
exports.build = series(buildScripts, xxx, ...); // for tasks that run in series
// or
exports.build = parallel(buildScripts, xxx, ...); // for tasks that run in parallel
gulp3-to-gulp4.js
It’s a little more verbose but overall feels tidier and more modern. Gulp 4 has great docs on this process and the various way you can let Gulp know when your task is done.
All being well, you should now, be able to open up Visual Studio 2019 and see task runner running happily:
Sometimes the most thankless of tasks are the hardest, but for the sake of maintainability, security, and progress, they are the most satisfying. Now go forth fellow Node 12er… and build innovative things.
If you do have vulnerabilities, running an npm audit fix
should resolve a vast majority of them. Anything else that is vulnerable will need some manual tweaking, usually updating packages or replacing them with more modern equivalents. You can find these incorrect packages with npm audit
and then tracing back to your troublesome packages.
For Task Runner Explorer to work with Gulp, quite a few things need to be set up correctly:
gulpfile.js
in the root of your project.package.json
with dependencies or devDependenciespackage.json
)package.json
, the output console will tell you what’s wrong. Again, it may look like a wall of text, but in there will be clues to what is missing.☞ JavaScript Programming Tutorial Full Course for Beginners
☞ Learn JavaScript - Become a Zero to Hero
☞ Javascript Project Tutorial: Budget App
☞ E-Commerce JavaScript Tutorial - Shopping Cart from Scratch