277 lines
11 KiB
JavaScript
277 lines
11 KiB
JavaScript
var fs = require("file-system"),
|
|
glob = require("glob"),
|
|
path = require("path-posix"),
|
|
merge = require("merge-stream"),
|
|
gulp = require("gulp"),
|
|
gulpif = require("gulp-if"),
|
|
print = require("gulp-print"),
|
|
debug = require("gulp-debug"),
|
|
newer = require("gulp-newer"),
|
|
plumber = require("gulp-plumber"),
|
|
sourcemaps = require("gulp-sourcemaps"),
|
|
less = require("gulp-less"),
|
|
scss = require("gulp-sass"),
|
|
cssnano = require("gulp-cssnano"),
|
|
typescript = require("gulp-typescript"),
|
|
uglify = require("gulp-uglify"),
|
|
rename = require("gulp-rename"),
|
|
concat = require("gulp-concat"),
|
|
header = require("gulp-header"),
|
|
eol = require("gulp-eol");
|
|
|
|
// For compat with older versions of Node.js.
|
|
require("es6-promise").polyfill();
|
|
|
|
// To suppress memory leak warning from gulp.watch().
|
|
require("events").EventEmitter.prototype._maxListeners = 100;
|
|
|
|
/*
|
|
** GULP TASKS
|
|
*/
|
|
|
|
// Incremental build (each asset group is built only if one or more inputs are newer than the output).
|
|
gulp.task("build", function () {
|
|
var assetGroupTasks = getAssetGroups().map(function (assetGroup) {
|
|
var doRebuild = false;
|
|
return createAssetGroupTask(assetGroup, doRebuild);
|
|
});
|
|
return merge(assetGroupTasks);
|
|
});
|
|
|
|
// Full rebuild (all assets groups are built regardless of timestamps).
|
|
gulp.task("rebuild", function () {
|
|
var assetGroupTasks = getAssetGroups().map(function (assetGroup) {
|
|
var doRebuild = true;
|
|
return createAssetGroupTask(assetGroup, doRebuild);
|
|
});
|
|
return merge(assetGroupTasks);
|
|
});
|
|
|
|
// Continuous watch (each asset group is built whenever one of its inputs changes).
|
|
gulp.task("watch", function () {
|
|
var pathWin32 = require("path");
|
|
getAssetGroups().forEach(function (assetGroup) {
|
|
var watchPaths = assetGroup.inputPaths.concat(assetGroup.watchPaths);
|
|
var inputWatcher;
|
|
function createWatcher() {
|
|
inputWatcher = gulp.watch(watchPaths, function (event) {
|
|
var isConcat = path.basename(assetGroup.outputFileName, path.extname(assetGroup.outputFileName)) !== "@";
|
|
if (isConcat)
|
|
console.log("Asset file '" + event.path + "' was " + event.type + ", rebuilding asset group with output '" + assetGroup.outputPath + "'.");
|
|
else
|
|
console.log("Asset file '" + event.path + "' was " + event.type + ", rebuilding asset group.");
|
|
var doRebuild = true;
|
|
var task = createAssetGroupTask(assetGroup, doRebuild);
|
|
});
|
|
}
|
|
createWatcher();
|
|
gulp.watch(assetGroup.manifestPath, function (event) {
|
|
console.log("Asset manifest file '" + event.path + "' was " + event.type + ", restarting watcher.");
|
|
inputWatcher.remove();
|
|
inputWatcher.end();
|
|
createWatcher();
|
|
});
|
|
});
|
|
});
|
|
|
|
/*
|
|
** ASSET GROUPS
|
|
*/
|
|
|
|
function getAssetGroups() {
|
|
var assetManifestPaths = glob.sync("./src/web/modules/*/assets.json", {});
|
|
var assetGroups = [];
|
|
assetManifestPaths.forEach(function (assetManifestPath) {
|
|
var assetManifest = require("./" + assetManifestPath);
|
|
assetManifest.forEach(function (assetGroup) {
|
|
resolveAssetGroupPaths(assetGroup, assetManifestPath);
|
|
assetGroups.push(assetGroup);
|
|
});
|
|
});
|
|
return assetGroups;
|
|
}
|
|
|
|
function resolveAssetGroupPaths(assetGroup, assetManifestPath) {
|
|
assetGroup.manifestPath = assetManifestPath;
|
|
assetGroup.basePath = path.dirname(assetManifestPath);
|
|
assetGroup.inputPaths = assetGroup.inputs.map(function (inputPath) {
|
|
return path.resolve(path.join(assetGroup.basePath, inputPath));
|
|
});
|
|
assetGroup.watchPaths = [];
|
|
if (!!assetGroup.watch) {
|
|
assetGroup.watchPaths = assetGroup.watch.map(function (watchPath) {
|
|
return path.resolve(path.join(assetGroup.basePath, watchPath));
|
|
});
|
|
}
|
|
assetGroup.outputPath = path.resolve(path.join(assetGroup.basePath, assetGroup.output));
|
|
assetGroup.outputDir = path.dirname(assetGroup.outputPath);
|
|
assetGroup.outputFileName = path.basename(assetGroup.output);
|
|
// Uncomment to copy assets to wwwroot
|
|
//assetGroup.webroot = path.join("./src/OrchardCore.Cms.Web/wwwroot/", path.basename(assetGroup.basePath), path.dirname(assetGroup.output));
|
|
}
|
|
|
|
function createAssetGroupTask(assetGroup, doRebuild) {
|
|
var outputExt = path.extname(assetGroup.output).toLowerCase();
|
|
var doConcat = path.basename(assetGroup.outputFileName, outputExt) !== "@";
|
|
if (doConcat && !doRebuild) {
|
|
// Force a rebuild of this asset group is the asset manifest file itself is newer than the output.
|
|
var assetManifestStats = fs.statSync(assetGroup.manifestPath);
|
|
var outputStats = fs.existsSync(assetGroup.outputPath) ? fs.statSync(assetGroup.outputPath) : null;
|
|
doRebuild = !outputStats || assetManifestStats.mtime > outputStats.mtime;
|
|
}
|
|
switch (outputExt) {
|
|
case ".css":
|
|
return buildCssPipeline(assetGroup, doConcat, doRebuild);
|
|
case ".js":
|
|
return buildJsPipeline(assetGroup, doConcat, doRebuild);
|
|
}
|
|
|
|
if(assetGroup.copy === true){
|
|
return buildCopyPipeline(assetGroup, doRebuild);
|
|
}
|
|
}
|
|
|
|
/*
|
|
** PROCESSING PIPELINES
|
|
*/
|
|
|
|
function buildCssPipeline(assetGroup, doConcat, doRebuild) {
|
|
assetGroup.inputPaths.forEach(function (inputPath) {
|
|
var ext = path.extname(inputPath).toLowerCase();
|
|
if (ext !== ".scss" && ext !== ".less" && ext !== ".css")
|
|
throw "Input file '" + inputPath + "' is not of a valid type for output file '" + assetGroup.outputPath + "'.";
|
|
});
|
|
var generateSourceMaps = assetGroup.hasOwnProperty("generateSourceMaps") ? assetGroup.generateSourceMaps : true;
|
|
var containsLessOrScss = assetGroup.inputPaths.some(function (inputPath) {
|
|
var ext = path.extname(inputPath).toLowerCase();
|
|
return ext === ".less" || ext === ".scss";
|
|
});
|
|
// Source maps are useless if neither concatenating nor transforming.
|
|
if ((!doConcat || assetGroup.inputPaths.length < 2) && !containsLessOrScss)
|
|
generateSourceMaps = false;
|
|
|
|
var minifiedStream = gulp.src(assetGroup.inputPaths) // Minified output, source mapping completely disabled.
|
|
.pipe(gulpif(!doRebuild,
|
|
gulpif(doConcat,
|
|
newer(assetGroup.outputPath),
|
|
newer({
|
|
dest: assetGroup.outputDir,
|
|
ext: ".css"
|
|
}))))
|
|
.pipe(plumber())
|
|
.pipe(gulpif("*.less", less()))
|
|
.pipe(gulpif("*.scss", scss({
|
|
precision: 10,
|
|
|
|
})))
|
|
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
|
|
.pipe(cssnano({
|
|
autoprefixer: { browsers: ["last 2 versions"] },
|
|
discardComments: { removeAll: true },
|
|
discardUnused: false,
|
|
mergeIdents: false,
|
|
reduceIdents: false,
|
|
zindex: false
|
|
}))
|
|
.pipe(rename({
|
|
suffix: ".min"
|
|
}))
|
|
.pipe(eol())
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
// Uncomment to copy assets to wwwroot
|
|
//.pipe(gulp.dest(assetGroup.webroot));
|
|
var devStream = gulp.src(assetGroup.inputPaths) // Non-minified output, with source mapping
|
|
.pipe(gulpif(!doRebuild,
|
|
gulpif(doConcat,
|
|
newer(assetGroup.outputPath),
|
|
newer({
|
|
dest: assetGroup.outputDir,
|
|
ext: ".css"
|
|
}))))
|
|
.pipe(plumber())
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.init()))
|
|
.pipe(gulpif("*.less", less()))
|
|
.pipe(gulpif("*.scss", scss({
|
|
precision: 10
|
|
})))
|
|
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
|
|
.pipe(header(
|
|
"/*\n" +
|
|
"** NOTE: This file is generated by Gulp and should not be edited directly!\n" +
|
|
"** Any changes made directly to this file will be overwritten next time its asset group is processed by Gulp.\n" +
|
|
"*/\n\n"))
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
|
|
.pipe(eol())
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
// Uncomment to copy assets to wwwroot
|
|
//.pipe(gulp.dest(assetGroup.webroot));
|
|
return merge([minifiedStream, devStream]);
|
|
}
|
|
|
|
function buildJsPipeline(assetGroup, doConcat, doRebuild) {
|
|
assetGroup.inputPaths.forEach(function (inputPath) {
|
|
var ext = path.extname(inputPath).toLowerCase();
|
|
if (ext !== ".ts" && ext !== ".js")
|
|
throw "Input file '" + inputPath + "' is not of a valid type for output file '" + assetGroup.outputPath + "'.";
|
|
});
|
|
var generateSourceMaps = assetGroup.hasOwnProperty("generateSourceMaps") ? assetGroup.generateSourceMaps : true;
|
|
// Source maps are useless if neither concatenating nor transforming.
|
|
if ((!doConcat || assetGroup.inputPaths.length < 2) && !assetGroup.inputPaths.some(function (inputPath) { return path.extname(inputPath).toLowerCase() === ".ts"; }))
|
|
generateSourceMaps = false;
|
|
|
|
console.log(assetGroup.inputPaths);
|
|
return gulp.src(assetGroup.inputPaths)
|
|
.pipe(gulpif(!doRebuild,
|
|
gulpif(doConcat,
|
|
newer(assetGroup.outputPath),
|
|
newer({
|
|
dest: assetGroup.outputDir,
|
|
ext: ".js"
|
|
}))))
|
|
.pipe(plumber())
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.init()))
|
|
.pipe(gulpif("*.ts", typescript({
|
|
declaration: false,
|
|
noImplicitAny: true,
|
|
noEmitOnError: true,
|
|
lib: [
|
|
"dom",
|
|
"es5",
|
|
"scripthost",
|
|
"es2015.iterable"
|
|
],
|
|
target: "es5",
|
|
})))
|
|
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
|
|
.pipe(header(
|
|
"/*\n" +
|
|
"** NOTE: This file is generated by Gulp and should not be edited directly!\n" +
|
|
"** Any changes made directly to this file will be overwritten next time its asset group is processed by Gulp.\n" +
|
|
"*/\n\n"))
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
// Uncomment to copy assets to wwwroot
|
|
//.pipe(gulp.dest(assetGroup.webroot))
|
|
.pipe(uglify())
|
|
.pipe(rename({
|
|
suffix: ".min"
|
|
}))
|
|
.pipe(eol())
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
// Uncomment to copy assets to wwwroot
|
|
//.pipe(gulp.dest(assetGroup.webroot));
|
|
}
|
|
|
|
function buildCopyPipeline(assetGroup, doRebuild) {
|
|
var stream = gulp.src(assetGroup.inputPaths);
|
|
|
|
if(!doRebuild) {
|
|
stream = stream.pipe(newer(assetGroup.outputDir))
|
|
}
|
|
|
|
stream = stream.pipe(gulp.dest(assetGroup.outputDir));
|
|
// Uncomment to copy assets to wwwroot
|
|
//.pipe(gulp.dest(assetGroup.webroot));
|
|
|
|
return stream;
|
|
} |