Created
January 24, 2018 01:09
-
-
Save jungleBadger/95290b6333aa0409ec17ca55c086bf59 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
/*jslint node: true, nomen:true*/ | |
/*env:node*/ | |
(function () { | |
"use strict"; | |
require("dotenv").config({"silent": true}); | |
const gulp = require("gulp"); | |
const packageJson = require("./package.json"); | |
const swPrecache = require("sw-precache"); | |
const argv = require("yargs").argv; | |
const browserify = require("browserify"); | |
const cond = require("gulp-cond"); | |
const gutil = require("gulp-util"); | |
const fs = require("fs"); | |
const fse = require("fs-extra"); | |
const uglify = require("gulp-uglify"); | |
const imagemin = require("gulp-imagemin"); | |
const rename = require("gulp-rename"); | |
const cssnano = require("cssnano"); | |
const cache = require("gulp-cache"); | |
const postcss = require("gulp-postcss"); | |
const runSequence = require("run-sequence"); | |
const watchify = require("watchify"); | |
const buffer = require("vinyl-buffer"); | |
const source = require("vinyl-source-stream"); | |
const sourcemaps = require("gulp-sourcemaps"); | |
const sass = require("gulp-sass"); | |
const babelify = require("babelify"); | |
const envify = require("gulp-envify"); | |
const vueify = require("vueify"); | |
const eslint = require("gulp-eslint"); | |
const plumber = require("gulp-plumber"); | |
const path = require("path"); | |
const cssnext = require("postcss-cssnext"); | |
const fetch = require("node-fetch"); | |
const cssUglifier = [ | |
cssnano() | |
]; | |
const childProcess = require("child_process"); | |
const APP_DEPS = ["bulma", "animate.css", "izitoast", "flatpickr"]; | |
const WEBHOOK_ENDPOINT = process.env.WEBHOOK_ENDPOINT || argv.slack; | |
let currentContext = ""; | |
let browserifyInstance; | |
let modulePath; | |
let isProd; | |
let isBluemix = argv.bluemix || argv.bx; | |
vueify.compiler.applyConfig({ | |
"postcss": [cssnext()] | |
}); | |
process.env.NODE_ENV = argv.prod ? "production" : "development"; | |
isProd = process.env.NODE_ENV === "production"; | |
let methods = { | |
"sendSlackMessage": function (payload) { | |
return new Promise(function (resolve, reject) { | |
if (WEBHOOK_ENDPOINT) { | |
fetch(WEBHOOK_ENDPOINT, { | |
"method": "POST", | |
"body": JSON.stringify(payload), | |
"headers": { | |
"Content-Type": "application/json" | |
}, | |
}).then(response => resolve(response)) | |
.catch(error => reject(error)); | |
} else { | |
reject("Webhook ID not available"); | |
} | |
}); | |
}, | |
"errorHandler": function (module, error, stack) { | |
gutil.log(gutil.colors.red("ERROR FOUND BUILDING THIS ARTIFACT:"), gutil.colors.yellow(module)); | |
gutil.log(error); | |
gutil.log(stack); | |
if (isBluemix) { | |
let log_url; | |
if (isProd) { | |
log_url = "https://console.bluemix.net/devops/pipelines/8828557f-bb39-4f96-9d69-2c015ebfabb0?env_id=ibm%3Ayp%3Aus-south"; | |
} else { | |
log_url = "https://console.bluemix.net/devops/pipelines/51d76df7-aed9-4374-8e0c-be1a6c8924df?env_id=ibm%3Ayp%3Aus-south"; | |
} | |
methods.sendSlackMessage({ | |
"username": "BUILD FAILING", | |
"icon_emoji": ":interrobang:", | |
"text": [ | |
"*ENVIRONMENT*: ", process.env.NODE_ENV, "\n", | |
error, "\n", | |
"Check the <", log_url, "|logs>" | |
].join("") | |
}).then(function () { | |
gutil.log("Webhook sent"); | |
return process.exit(1); | |
}).catch(function(error) { | |
gutil.log(error); | |
return process.exit(1); | |
}); | |
} else { | |
return process.exit(1); | |
} | |
}, | |
"bundleJS": function () { | |
if (isProd) { | |
fse.remove(path.join(modulePath, "dist/js/bundle.js.map")); | |
} | |
browserifyInstance.bundle() | |
.on("error", function (err) { | |
gutil.log(err); | |
}) | |
.pipe(source(path.join(modulePath, "js/main.js"))) | |
.pipe(cond(!isProd, plumber())) | |
.pipe(buffer()) | |
.pipe(rename("bundle.js")) | |
.pipe(cond(isProd, uglify())) | |
.pipe(cond(!isProd, sourcemaps.init({"loadMaps": true}))) | |
.pipe(cond(!isProd, sourcemaps.write("./"))) | |
.pipe(gulp.dest(path.join(modulePath, "dist/js/"))); | |
return isProd ? gutil.log("FINISHED PRODUCTION BUILD") : gutil.log("FINISHED DEV BUILD"); | |
}, | |
"createFiles": function (files) { | |
return files.map(function (file) { | |
return new Promise(function (resolve, reject) { | |
fse.outputFile(file.path, file.content || "", "utf-8", function (err) { | |
if (err) { | |
reject(err); | |
} else { | |
resolve("file saved"); | |
} | |
}); | |
}); | |
}); | |
}, | |
"setCFManifest": function () { | |
return fse.copy(path.join("root", isProd ? "manifest.prod.yml" : "manifest.dev.yml"), "manifest.yml", { | |
"overwrite": true | |
}); | |
}, | |
"htmlTemplate": function (module, title) { | |
return [ | |
"<!DOCTYPE html>", | |
`<html lang="en">`, | |
"<head>", | |
` <meta charset="UTF-8">`, | |
` <meta name="viewport" content="width=device-width, initial-scale=1">`, | |
` <link rel="manifest" href="/etc/manifest.json">`, | |
` <meta name="theme-color" content="#4A8FCC">`, | |
` <title>${title || module}</title>`, | |
` <link rel="stylesheet" href="./${module}_module/dist/css/style.css">`, | |
"</head>", | |
"<body>", | |
` <div id="app"></div>`, | |
`<noscript>Your browser does not support Script at this time</noscript>`, | |
`<script defer src="/etc/service-worker-registration.js"></script>`, | |
`<script src="./${module}_module/dist/js/bundle.js"></script>`, | |
"</body>", | |
"</html>"].join("\n"); | |
}, | |
"jsTemplate": function () { | |
return [ | |
"(function () {", | |
` "use strict";`, | |
"}());" | |
].join("\n"); | |
} | |
}; | |
gulp.task("build-all", ["lint:server", "set-manifest"], function () { | |
fs.readdir("./client", function (err, files) { | |
files.forEach(function (file) { | |
let stat = fs.statSync(path.join("client")); | |
if (stat.isDirectory() && file.indexOf("_module") > -1) { | |
let module = file.split("_")[0]; | |
childProcess.exec(["gulp build -m", module, isProd ? "--prod" : ""].join(" "), function (error, stdout) { | |
gutil.log([gutil.colors.blue("MODULE:"), module, gutil.colors.blue("BUILD TYPE:"), process.env.NODE_ENV].join(" ")); | |
if (error) { | |
methods.errorHandler(module, error, stdout); | |
} else { | |
gutil.log(stdout); | |
gutil.log(gutil.colors.green("Module built successfully")); | |
} | |
}); | |
} | |
}); | |
}); | |
}); | |
gulp.task("build", function () { | |
if (argv.w || argv.watch) { | |
runSequence("lint", "js", "css", "watch-css", "generate-sw"); | |
} else { | |
runSequence("lint", "js", "css", "generate-sw"); | |
} | |
}); | |
gulp.task("js", function () { | |
modulePath = currentContext ? currentContext : path.join("client", (argv.module || argv.m || currentContext || "main") + "_module"); | |
browserifyInstance = browserify({ | |
"entries": path.join(modulePath, "js/main.js"), | |
"noParse": ["vue.js"], | |
"plugin": argv.w || argv.watch ? [watchify] : [], | |
"cache": {}, | |
"packageCache": {}, | |
"debug": !isProd | |
}).transform("envify", { | |
"global": true, | |
"NODE_ENV": process.env.NODE_ENV | |
}) | |
.transform(babelify) | |
.transform(vueify) | |
.on("update", methods.bundleJS); | |
return methods.bundleJS(); | |
}); | |
gulp.task("css", function () { | |
modulePath = currentContext ? currentContext : path.join("client", (argv.module || argv.m || currentContext || "main") + "_module"); | |
if (isProd) { | |
fse.remove(path.join(modulePath, "/dist/css/style.css.map")); | |
} | |
return gulp.src([path.join(modulePath, "/css/*.css"), path.join(modulePath, "/css/*.scss")]) | |
.pipe(plumber()) | |
.pipe(postcss([ | |
cssnext({}) | |
])) | |
.pipe(cond(!isProd, sourcemaps.init({"loadMaps": true}))) | |
.pipe(sass().on('error', sass.logError)) | |
.pipe(cond(isProd, postcss(cssUglifier))) | |
.pipe(cond(!isProd, sourcemaps.write("./"))) | |
.pipe(gulp.dest(path.join(modulePath, "/dist/css/"))) | |
}); | |
gulp.task("watch-css", function () { | |
modulePath = currentContext ? currentContext : path.join("client", (argv.module || argv.m || currentContext || "main") + "_module"); | |
return gulp.watch([path.join(modulePath, "/css/*.css"), path.join(modulePath, "/css/*.scss")], ['css']); | |
}); | |
gulp.task("lint", function () { | |
modulePath = currentContext ? currentContext : path.join("client", (argv.module || argv.m || currentContext || "main") + "_module"); | |
return gulp.src([[modulePath, "/js/**/*.js"].join(""), [modulePath, "/js/**/*.vue"].join("")]) | |
.pipe(eslint()) | |
.pipe(eslint.format()) | |
.pipe(eslint.failAfterError()); | |
}); | |
gulp.task("lint:server", function () { | |
return gulp.src(["./app.js", "./server/**/*.js"]) | |
.pipe(eslint()) | |
.pipe(eslint.format()) | |
.pipe(eslint.failAfterError()) | |
.on("error", function (error) { | |
methods.errorHandler("lint:server", error, "Check the logs to see where it fails"); | |
}); | |
}); | |
gulp.task("watch", function() { | |
let modulePath = path.join("./client/", (argv.module || argv.m || currentContext || "main") + "_module"); | |
currentContext = modulePath; | |
gulp.watch([modulePath + "/js/**/*.js", modulePath + "/js/*.js", modulePath + "/css/**/*.css", modulePath + "/js/components/*.vue"], ["build"]); | |
}); | |
gulp.task("images", function () { | |
return gulp.src("public/images/disclaimer/*.+(png|jpg|jpeg|gif|svg)").pipe(cache(imagemin())).pipe(gulp.dest("public/images/disclaimer/dist")); | |
}); | |
gulp.task("generate-sw", function(callback) { | |
swPrecache.write(path.join("./client", "service-worker.js"), { | |
"cacheId": packageJson.name, | |
"logger": gutil.log, | |
"handleFetch": isProd, | |
"staticFileGlobs": [ | |
"./client/etc/libs/bulma/css/bulma.css", | |
"./client/etc/libs/bulma/css/bulma.css.map", | |
"./client/etc/libs/fontawesome/*.js", | |
"./client/etc/libs/animate.css/animate.css", | |
"./client/etc/libs/animate.css/animate.min.css", | |
"./client/etc/libs/izitoast/dist/css/*.css", | |
"./client/etc/libs/izitoast/dist/js/*.js", | |
"./etc/libs/vue-multiselect/vue-multiselect.min.css", | |
"./client/etc/assets/svg/loading.svg", | |
"./client/**/dist/css/libs.css" | |
], | |
"stripPrefix": "./client" | |
}, callback); | |
}); | |
gulp.task("load-deps", function(done) { | |
Promise.all(APP_DEPS.map((dependecy) => { | |
return new Promise((resolve, reject) => { | |
const NPM_LIB_PATH = path.join("client/etc/libs", dependecy); | |
gutil.log(gutil.colors.green(`PREPARING TO INSTALL: ${dependecy}`)); | |
if (fse.pathExistsSync(NPM_LIB_PATH)) { | |
fse.copy( | |
path.join("node_modules", dependecy), | |
NPM_LIB_PATH, | |
(err) => { | |
if (err) { | |
reject(err); | |
reject([gutil.colors.red("ERR LOADING DEP:"), dependecy].join(" ")); | |
} else { | |
resolve(dependecy); | |
} | |
} | |
); | |
} else { | |
childProcess.exec(["npm install", dependecy].join(" "), function (error, stdout) { | |
gutil.log([gutil.colors.blue("NPM:"), stdout].join(" ")); | |
fse.copy( | |
path.join("node_modules", dependecy), | |
NPM_LIB_PATH, | |
(err) => { | |
if (err) { | |
reject(err); | |
reject([gutil.colors.red("ERR LOADING DEP:"), dependecy].join(" ")); | |
} else { | |
resolve(dependecy); | |
} | |
} | |
); | |
}); | |
} | |
}); | |
})).then(() => { | |
done(); | |
}).catch((err) => { | |
gutil.log(err); | |
}); | |
}); | |
gulp.task("set-manifest", function (done) { | |
if (isBluemix) { | |
methods.setCFManifest().then(function () { | |
done(); | |
}).catch(function (error) { | |
methods.errorHandler("set-manifest", error, "Check the logs to see where it fails"); | |
}); | |
} else { | |
done(); | |
} | |
}); | |
gulp.task("notifyBuildSuccess", function () { | |
methods.sendSlackMessage({ | |
"username": "BUILD SUCCESS", | |
"text": "ENVIRONMENT: *" + process.env.NODE_ENV + "* finished building and preparing to deploy", | |
"icon_emoji": ":cat2:" | |
}) | |
}); | |
gulp.task("notifyDeploySuccess", function () { | |
methods.sendSlackMessage({ | |
"username": "DEPLOY SUCCESS", | |
"text": "ENVIRONMENT: *" + process.env.NODE_ENV + "* finished deploy to Bluemix", | |
"icon_emoji": ":bluemix:" | |
}) | |
}); | |
gulp.task("create-module", function () { | |
let module = argv.m || argv.module; | |
let override = argv.o || argv.override; | |
if (!module) { | |
gutil.log("can not proceed without module parameter"); | |
} else { | |
let targetPath = path.join("./client", module + "_module/"); | |
let cssPath = path.join(targetPath, "css"); | |
let jsPath = path.join(targetPath, "js"); | |
let componentPath = path.join(targetPath, "js", "components"); | |
if (fse.pathExistsSync(targetPath) && !override) { | |
gutil.log("Module already exists. Run with -o flag to override"); | |
} else { | |
Promise.all(methods.createFiles([{ | |
"path": path.join(targetPath, "index.html"), | |
"content": methods.htmlTemplate(module) | |
}, { | |
"path": path.join(cssPath, "style.scss"), | |
"content": "" | |
}, { | |
"path": path.join(jsPath, "main.js"), | |
"content": methods.jsTemplate() | |
}, { | |
"path": path.join(componentPath, "app.vue"), | |
"content": methods.jsTemplate() | |
}])).then(function (result) { | |
gutil.log(result); | |
}).catch(function (err) { | |
gutil.log(err); | |
}); | |
} | |
} | |
}); | |
gulp.task("help", function () { | |
/* | |
params to doc | |
@ watch, alias w -> #build | |
@ prod -> #env | |
@ bluemix, alias bx -> #generate-sw | |
@ module, alias m -> #build | |
@ override, alias o -> #create-module | |
*/ | |
gutil.log(gutil.colors.green("Task: build-all"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: build"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: lint"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: lint:server"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: js"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: css"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: generate-sw"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: set-manifest"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: create-module"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: images"), gutil.colors.magenta('#')); | |
gutil.log(gutil.colors.green("Task: load-deps"), gutil.colors.magenta('#')); | |
}); | |
process.on("exit", function(code) { | |
gutil.log("About to exit with code:", code); | |
}); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment