Gulp task chaining for SPFx projects
When swapping between debugging using a workbench and deploying to a SharePoint developer tenant, we need to toggle the —ship flags.
Also, we need to chain the Gulp commands. Just running gulp package-solution —ship does not perform the entire chain. This has been discussed before, for example on this Github thread.
First, I set off chaining a custom task for gulp dev, which will clean the project, build, bundle and then launch a serve again to the workbench. I edit my gulpfile.js as:
// Clean and build before 'serve' to get dev settingsgulp.task("dev", ["clean", "bundle"], function() {})// Run 'dev' to clean up after prod packaging, then start 'serve'gulp.task("devserve", ["dev"], function () { gulp.start("serve");})By adding an array of commands as the second parameter on gulp.task, we can set dependency tasks that should execute before the task, therefore chaining the commands. However, I do not want to wait for serve, as this stays open until I quit the workbench, so I use gulp.start which does not wait for the output of serve.
This works well. However, for packaging, we cannot add a parameter/flag to the dependencies, as in:
gulp.task( "package", ["clean", "bundle --ship", "package-solution --ship"], function () { // Will not work!})This will just error, stating that the task cannot be found.
To make this work, you could use gulp-parameterized, but this is not compatible with Gulp 3.x and needs Gulp 4.x, which SPFx currently does not support. If this changes in the future then the next section is moot.
I instead use gulp-run-command to perform the —ship flag, as you cannot method:
// Full clean, version update and package for publishing to prod// npm install gulp-run-commandconst run = require('gulp-run-command').defaultgulp.task("bundleship", run("gulp bundle --ship", { ignoreErrors: true // Warnings are treated as errors otherwise}));gulp.task("package", ["clean", "update-version", "bundleship"], run("gulp package-solution --ship"))Also, I found a neat custom Gulp task by Nakkeeran Natarjan that increments the version number. I modified this to set the minor version number to automate upgrades, which is referenced above as update-version:
// Update minor version, useful when upgradingconst fs = require('fs');build.task('update-version', { execute: () => { return new Promise((resolve, reject) => { let json = JSON.parse(fs.readFileSync("./config/package-solution.json")); let versions = json.solution.version.split("."); versions = (parseInt(versions) + 1).toString(); json.solution.version = versions.join(".") console.log("Solution version updated to " + json.solution.version); fs.writeFileSync('./config/package-solution.json', JSON.stringify(json)); resolve(); }); }});Now, we can quickly move between debugging and uploading packages by:
gulp devservegulp package