Created
November 20, 2016 15:11
-
-
Save pjsvis/50814c48ae0c547e9ecd416b45cef523 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Adapted from the utp gulp file | |
Currently using _LayoutEx.cshtml as master pages | |
Need to include bootstrap | |
*/ | |
// Visual Studio has a binding of BeforeBuild: main | |
// This means that when you build the app the main task will run. | |
// | |
// References | |
// 1. [https://gist.github.com/spboyer/96339ce687b0c79b8258](https://gist.github.com/spboyer/96339ce687b0c79b8258) | |
// 1. [http://stackoverflow.com/questions/32824381/parse-main-bower-files-js-css-scss-images-to-distribution-via-gulp](http://stackoverflow.com/questions/32824381/parse-main-bower-files-js-css-scss-images-to-distribution-via-gulp) | |
'use strict'; | |
// The following dependencies are installed by | |
// ``` | |
// npm install gulp --save-dev | |
// ``` | |
var gulp = require('gulp'); | |
var bower = require('gulp-bower'); | |
var concat = require('gulp-concat'); | |
var uglify = require('gulp-uglify'); | |
var cssnano = require('gulp-cssnano'); | |
var sourcemaps = require('gulp-sourcemaps'); | |
var mainBowerFiles = require('main-bower-files'); | |
var del = require('del'); | |
var ts = require('gulp-typescript'); | |
var runSequence = require('run-sequence'); | |
var htmlhint = require('gulp-htmlhint'); | |
var eslint = require('gulp-eslint'); | |
var less = require('gulp-less'); | |
var typedoc = require("gulp-typedoc"); | |
var docco = require("gulp-docco"); | |
var clean = require('gulp-clean'); | |
var shell = require('gulp-shell'); | |
var npmRun = require('gulp-npm-run')(require('gulp'), { | |
exclude: 'test', | |
include: 'tsc-watch', | |
requireStrict: true, | |
npmRun: true | |
}); | |
var rename = require('gulp-rename'); | |
// Deprecated. Use explicit requires for clarity. | |
var $ = require('gulp-load-plugins')({ | |
lazy: true | |
}); | |
gulp.task('fis', function () { | |
return gulp.src('custom/fis-bootstrap.less') | |
.pipe(sourcemaps.init()) | |
.pipe(less()) | |
.pipe(rename('custom-bootstrap.css')) | |
.pipe(sourcemaps.write('/')) | |
.pipe(gulp.dest('./css')); | |
}); | |
// Clean out the app-docs folder | |
gulp.task('clean-docs', function () { | |
return gulp | |
.src(['app-docs'], { | |
read: false | |
}) | |
.pipe(clean()); | |
}); | |
// Typedoc creates documentation for our Typescript files in ```app-docs/typedoc``` | |
// We use [Typewriter](https://github.com/frhagn/Typewriter) to generate | |
// Typescript interfaces for our WebAPI endpoints and our database models. | |
// We don't need to document angular controllers or componentsas they don't have any interfaces | |
gulp.task("typedoc", function () { | |
return gulp | |
.src(["app/**/*.ts", "!app/**/*.controller.ts", "!app/**/*.component.ts", "!app/globals.ts"]) | |
.pipe(typedoc({ | |
module: "system", | |
target: "es5", | |
out: "app-docs/typedoc", | |
name: "Certification Management Portal", | |
includeDeclarations: true | |
})) | |
; | |
}); | |
// Used to document gulpfile.js | |
// | |
// We document our ```scripts/app/**/*.js``` files using docco-toc which is run from a shell | |
// ``` | |
// docco-toc -o app-docs/docco-toc *.js | |
// ``` | |
gulp.task('docco', function () { | |
var options = { | |
layout: 'parallel', | |
output: 'app-docs/docco', | |
template: null, | |
css: null, | |
extension: null, | |
languages: {}, | |
marked: null | |
}; | |
return gulp.src("gulpfile.js") | |
.pipe(docco(options)) | |
.pipe(gulp.dest('./app-docs/docco')); | |
}); | |
// Some variables used in the config object. | |
// Only used by the templatecache and inject-app tasks | |
// Could be trimmed down | |
// TODO: Try and exclude scratch.tpl.html | |
var client = ''; | |
var clientApp = 'app/'; | |
var layoutSource = 'Views/Shared/'; | |
// bower main files will be stored here | |
var targetDir = 'build/lib'; | |
var config = { | |
client: client, | |
layoutSource: layoutSource, | |
// script/style tags will be injected here | |
index: layoutSource + '_LayoutEx.cshtml', | |
css: [ | |
// Get all css files in all folders | |
targetDir + '/**/*.css' | |
], | |
js: [ | |
// Get all js files in all folders | |
targetDir + '/**/*.js' | |
], | |
htmltemplates: [clientApp + '**/*.html'], | |
templateCache: { | |
file: 'templates.js', | |
options: { | |
module: 'templates', | |
root: 'app/', | |
standAlone: true | |
} | |
}, | |
temp: './.tmp/' | |
}; | |
// Clean the ```build/lib``` folder. | |
// Required to get rid of any deprecated files | |
gulp.task('clean-build-lib', function () { | |
log('Cleaning ./build/lib'); | |
log('NOTE: This is the bower-preinstall task'); | |
return del('./build/lib/'); | |
}); | |
gulp.task('clean-lib', function () { | |
log('Cleaning ./lib'); | |
return del('./lib/'); | |
}); | |
// Copy the main bower files to the ```build/lib``` folder | |
gulp.task('main-bower-files', ['clean-build-lib'], function () { | |
log('Copying main bower files to ./lib/'); | |
return gulp.src(mainBowerFiles({ debugging: true }), { base: 'lib' }) | |
.pipe(gulp.dest('./build/lib')); | |
}); | |
// Lint the app html | |
gulp.task('htmlhint', function () { | |
return gulp.src("./app/**/*.html") | |
.pipe(htmlhint("htmlhintrc.json")) | |
//.pipe(htmlhint()) | |
.pipe(htmlhint.reporter("htmlhint-stylish")) | |
.pipe(htmlhint.failReporter({ suppress: true })); | |
}); | |
// Compile font awesome from the Less sources | |
gulp.task('less-fa', function () { | |
return gulp.src('lib/font-awesome/less/font-awesome.less') | |
.pipe(sourcemaps.init()) | |
.pipe(less()) | |
.pipe(sourcemaps.write('/')) | |
.pipe(gulp.dest('css')); | |
}); | |
// Copy the bootstrap and font-awesome fonts to the ```fonts``` folder | |
gulp.task('copyfonts', function () { | |
gulp.src('./lib/font-awesome/fonts/**/*.{ttf,woff,eof,svg,woff2}') | |
.pipe(gulp.dest('./fonts')); | |
}); | |
// Copy the tree-control images to images folder. | |
// This is required for the release build. | |
// <br>TODO: See if any other components need assets relocated for release | |
gulp.task('copy-tree-images', function () { | |
gulp.src('build/lib/angular-tree-control/images/*.png') | |
.pipe(gulp.dest('images')); | |
}); | |
// Ensure that the vendor script refs are in the correct order in ```_Layout.cshtml``` | |
var vendorSrc = [ | |
'build/lib/console-shim/**/*.js', | |
'build/lib/jquery/**/*.js', | |
'build/lib/signalr/**/*.js', | |
'build/lib/moment/**/*.js', | |
'build/lib/lodash/**/*.js', | |
'build/lib/api-check/dist/api-check.js', | |
'build/lib/codemirror/lib/**/*.js', | |
'build/lib/codemirror/mode/**/*.js', | |
'build/lib/ag-grid/dist/ag-grid.js', | |
'build/lib/angular/**/*.js', | |
'build/lib/angular-formly/dist/*.js', | |
'build/lib/angular-formly-templates-bootstrap/dist/*.js', | |
'build/lib/angular-gantt/assets/angular-gantt.js', | |
'build/lib/angular-gantt/assets/angular-gantt-plugins.js', | |
'build/lib/angular*/**/*.js', | |
'build/lib/**/*.js' | |
]; | |
var vendorCss = 'build/lib/**/*.css'; | |
// Inject our vendor ```*.js``` and ```*.css``` files into ```_Layout.cshtml``` | |
gulp.task('inject-bower', [], function () { | |
log('Injecting bower *.css and *.js files into _layout.cshtml'); | |
var timestamp = getTimestamp(); | |
var params = ['?v=', timestamp].join(''); | |
return gulp | |
.src(config.index) | |
.pipe($.inject(gulp.src(vendorCss), { | |
starttag: '<!-- inject:bower:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src(vendorSrc, { read: false }), { | |
starttag: '<!-- inject:bower:js -->', | |
transform: function (filepath) { | |
return ['<script src="~', filepath, params, '"></script>'].join(''); | |
} | |
})) | |
.pipe(gulp.dest(config.layoutSource)); | |
}); | |
// Update our bower files | |
gulp.task('bower-update', function () { | |
log('Updating bower files'); | |
return bower({ cmd: 'update' }); // Run gulp update | |
}); | |
// Do not use these hooks as Visual Studio forces an update on project open | |
// | |
// Before we do a bower install we clean ```build/lib``` | |
gulp.task('bower-preinstall', ['clean-build-lib']); | |
// After we do a bower install we wire up the dependencies | |
gulp.task('bower-postinstall', ['inject-bower', 'copy-tree-images']); | |
// Create an angular module called templates to hold the minified app html. | |
// The templates module gets injected in to the app module | |
// TODO: Have a look at just https://github.com/laxa1986/gulp-angular-embed-templates | |
// This will include the templates inline | |
// Ref: https://www.npmjs.com/package/gulp-angular-templatecache | |
gulp.task('templatecache', function () { | |
log('Creating an AngularJS $templateCache'); | |
return gulp | |
.src(['app/**/*.html']) | |
.pipe($.minifyHtml({ empty: true })) | |
.pipe($.angularTemplatecache( | |
config.templateCache.file, | |
config.templateCache.options | |
)) | |
.pipe(gulp.dest('./app/')); | |
}); | |
// Define excludes and loading order for the app scripts. | |
// The models/*.ts files are interrfaces that compile down to empty *.js files | |
var appSrc = [ | |
'!app/ts-gen/models/*.js', | |
'app/app.js', | |
'app/app.routes.js', | |
'app/templates.js', | |
'app/*module*.js', | |
'app/directives/angular-affix/**/*.js', | |
'app/**/*.js' | |
]; | |
// Define the loading order for the app style sheets. | |
// Exclude ```brand.css``` as it is injected after the other app styles so that it always overrides them | |
var appCss = [ | |
'!css/brand.css', | |
'css/custom-bootstrap.css', | |
'css/custom-bootstrap-overrides.css', | |
'css/Site.css', | |
'css/app-modals.css', | |
'css/**/*.css']; | |
// Inject our app and brand css files and then our app js files | |
gulp.task('inject-app', function () { | |
log('Injecting app *.css and *.js files into _layoutEx.cshtml'); | |
log('NOTE: All html files will be minified and injected into the cache via ./scripts/app/templates.js'); | |
log('DEPRECATE: *.route.js files should be referenced in their parent MVC views'); | |
log(appCss); | |
var timestamp = getTimestamp(); | |
var params = ['?v=', timestamp].join(''); | |
return gulp | |
.src('Views/Shared/_LayoutEx.cshtml') | |
.pipe($.inject(gulp.src(appCss, { read: false }), { | |
starttag: '<!-- inject:app:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src('css/brand.css', { read: false }), { | |
starttag: '<!-- inject:brand:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src(appSrc, { read: false }), { | |
starttag: '<!-- inject:app:js -->', | |
transform: function (filepath) { | |
return ['<script src="~', filepath, params, '"></script>'].join(''); | |
} | |
})) | |
.pipe(gulp.dest(config.layoutSource)); | |
}); | |
gulp.task('inject-release', function () { | |
log('Injecting dist/[app.min, app.css, vendor.min.js, vendor.min.css] into _layoutEx.cshtml'); | |
log(appCss); | |
var timestamp = getTimestamp(); | |
var params = ['?v=', timestamp].join(''); | |
return gulp | |
.src('Views/Shared/_LayoutEx.cshtml') | |
.pipe($.inject(gulp.src('dist/vendor.min.css', { read: false }), { | |
starttag: '<!-- inject:vendor-dist:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src('dist/app.min.css', { read: false }), { | |
starttag: '<!-- inject:app-dist:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src('css/brand.css', { read: false }), { | |
starttag: '<!-- inject:brand-dist:css -->', | |
transform: function (filepath) { | |
return ['<link href="~', filepath, params, '" rel="stylesheet" />'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src('dist/vendor.min.js', { read: false }), { | |
starttag: '<!-- inject:vendor-dist:js -->', | |
transform: function (filepath) { | |
return ['<script src="~', filepath, params, '"></script>'].join(''); | |
} | |
})) | |
.pipe($.inject(gulp.src('dist/app.min.js', { read: false }), { | |
starttag: '<!-- inject:app-dist:js -->', | |
transform: function (filepath) { | |
return ['<script src="~', filepath, params, '"></script>'].join(''); | |
} | |
})) | |
.pipe(gulp.dest(config.layoutSource)); | |
}); | |
// Declare placeholder for brandName and default it to fis | |
var brandName = 'fis'; | |
// Brand the app for a specific brand name | |
gulp.task('brandCss', function () { | |
var glob = ['branding/', brandName, '/**/*.{css,map}'].join(''); | |
return gulp.src(glob).pipe(gulp.dest('./css')); | |
}); | |
// Brand the app images for a specific brand name | |
gulp.task('brandImages', function () { | |
var glob = ['branding/', brandName, '/**/*.{png,ico}'].join(''); | |
return gulp.src(glob).pipe(gulp.dest('./images')); | |
}); | |
// FIS branding | |
gulp.task('brand-fis', function () { | |
brandName = 'fis'; | |
log(brandName); | |
runSequence('brandImages', 'brandCss'); | |
}); | |
// Concatenate and minify vendor scripts with mangle=false, preserve comments and licenses. | |
// Then copy the output to the ```./dist``` folder | |
// ```_Layout.cshtml``` has a debug flag. When set to false the minified sources will be used. | |
gulp.task('uglify-vendor', function () { | |
log('Concat and minify vendor files to ./dist/vendor.min.js with mangle=false and license=true'); | |
return gulp.src(vendorSrc) | |
.pipe(sourcemaps.init()) | |
.pipe(concat('vendor.min.js')) | |
.pipe(uglify({ mangle: false, preserveComments: true, license: true })) | |
.pipe(sourcemaps.write('.')) | |
.pipe(gulp.dest('./dist')); | |
}); | |
// Minify the vendor css | |
gulp.task('cssnano-vendor', function () { | |
return gulp.src(vendorCss) | |
.pipe(sourcemaps.init()) | |
.pipe(concat('vendor.min.css')) | |
.pipe(cssnano()) | |
.pipe(sourcemaps.write('.')) | |
.pipe(gulp.dest('./dist')); | |
}); | |
// Minify the app scripts | |
gulp.task('uglify-app', function () { | |
return gulp.src(appSrc) | |
.pipe(sourcemaps.init()) | |
.pipe(concat('app.min.js')) | |
.pipe(uglify({ mangle: false, preserveComments: true, license: true })) | |
.pipe(sourcemaps.write('.')) | |
.pipe(gulp.dest('./dist')); | |
}); | |
// Minify the app css | |
gulp.task('cssnano-app', function () { | |
return gulp.src(appCss) | |
.pipe(sourcemaps.init()) | |
.pipe(concat('app.min.css')) | |
.pipe(cssnano()) | |
.pipe(sourcemaps.write('.')) | |
.pipe(gulp.dest('./dist')); | |
}); | |
// Lint the javascript files | |
gulp.task('eslint', function () { | |
return gulp.src([ | |
'scripts/app/**/*.js', | |
'!node_modules/**', | |
'!lib/**', | |
'!build/**', | |
'!scripts/app/templates.js' | |
]) | |
.pipe(eslint()) | |
.pipe(eslint.format()); | |
}); | |
// Compile font-awesome | |
gulp.task('less-fa', function () { | |
return gulp.src('lib/font-awesome/less/font-awesome.less') | |
.pipe(sourcemaps.init()) | |
.pipe(less()) | |
.pipe(sourcemaps.write('/')) | |
.pipe(gulp.dest('css')); | |
}); | |
// Copy font awesome fonts to the fonts folder | |
gulp.task('copyfonts', function () { | |
gulp.src('./lib/font-awesome/fonts/**/*.{ttf,woff,eof,svg,woff2}') | |
.pipe(gulp.dest('./fonts')); | |
}); | |
gulp.task('copy-bootstrap-fonts', function () { | |
gulp.src('./lib/bootstrap/fonts/**/*.{eot,svg,ttf,woff,woff2}') | |
.pipe(gulp.dest('./fonts')); | |
}); | |
// Create a timestamp for cache busting purposes | |
function getTimestamp() { | |
var dt = new Date(); | |
var yy = dt.getFullYear(); | |
var mo = dt.getMonth(); | |
var dd = dt.getDate(); | |
var hh = dt.getHours(); | |
var mm = dt.getMinutes(); | |
var ss = dt.getSeconds(); | |
var ms = dt.getMilliseconds(); | |
return [yy, mo, dd, hh, mm, ss, ms].join(''); | |
} | |
// Log a message or series of messages using chalk's blue color. | |
// Can pass in a string, object or array. | |
function log(msg) { | |
if (typeof (msg) === 'object') { | |
for (var item in msg) { | |
if (msg.hasOwnProperty(item)) { | |
$.util.log($.util.colors.blue(msg[item])); | |
} | |
} | |
} else { | |
$.util.log($.util.colors.blue(msg)); | |
} | |
} | |
// Compile app typescript files. Not currently used. | |
// TODO: Figure out why it does not compile the ts files | |
// Currently we use a command line ```tsc --watch``` | |
gulp.task('tsc', function () { | |
var tsProject = ts.createProject('tsconfig.json', { sortOutput: true }); | |
tsProject.src() // instead of gulp.src(...) | |
.pipe(ts(tsProject)); | |
//var tsResult = tsProject.src() // instead of gulp.src(...) | |
// .pipe(ts(tsProject)); | |
//return tsResult.js.pipe(gulp.dest('release')); | |
}); | |
gulp.task('tsc-watch', function () { | |
return gulp.src('./app/**/*.ts') | |
.pipe(shell(['npm run tsc-watch'])); | |
}); | |
// The watch task is launched from Visual Studio Task Explorer. | |
// This will watch for changes in the app files and run the templatecache and inject-app tasks | |
gulp.task('app-watch', function () { | |
gulp.watch([ | |
//'app/**/*.ts', | |
'app/**/*.js', | |
'config/*.json', | |
'app/**/*.html', | |
'css/*.css' | |
], function () { | |
runSequence('templatecache', 'inject-app'); | |
}); | |
}); | |
// The main task is bound to the beforeBuild event is Visual Studio task explorer. | |
gulp.task('main', function () { | |
runSequence('templatecache', 'inject-app'); | |
}); | |
// Complete font awesome workflow | |
gulp.task('font-awesome', ['less-fa', 'copyfonts']); | |
// Build the app (duplicate of main) | |
// TODO: Add a tsc task | |
gulp.task('build-app', function () { | |
runSequence('templatecache', 'inject-app'); | |
}); | |
// Create the release files. (Not currently used.) | |
gulp.task('release-app', ['uglify-vendor', 'cssnano-vendor', 'uglify-app', 'cssnano-app', 'inject-release']); | |
// Expermimental watch-all method to compile *.ts, templatecache, inject-app | |
gulp.task('watch', ['app-watch', 'tsc-watch']); | |
gulp.task('default', ['watch']); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment