mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 11:44:58 +08:00

NOTE: You need to run "npm update" from the solution folder to download the updated version of the dependencies for the updated Gulpfile to work properly.
198 lines
8.1 KiB
JavaScript
198 lines
8.1 KiB
JavaScript
var fs = require("fs"),
|
|
glob = require("glob"),
|
|
path = require("path-posix"),
|
|
merge = require("merge-stream"),
|
|
gulpif = require("gulp-if"),
|
|
gulp = require("gulp"),
|
|
newer = require("gulp-newer"),
|
|
plumber = require("gulp-plumber"),
|
|
sourcemaps = require("gulp-sourcemaps"),
|
|
less = require("gulp-less"),
|
|
autoprefixer = require("gulp-autoprefixer"),
|
|
minify = require("gulp-minify-css"),
|
|
typescript = require("gulp-typescript"),
|
|
uglify = require("gulp-uglify"),
|
|
rename = require("gulp-rename"),
|
|
concat = require("gulp-concat"),
|
|
header = require("gulp-header");
|
|
|
|
/*
|
|
** 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("Orchard.Web/{Core,Modules,Themes}/*/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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
/*
|
|
** PROCESSING PIPELINES
|
|
*/
|
|
|
|
function buildCssPipeline(assetGroup, doConcat, doRebuild) {
|
|
assetGroup.inputPaths.forEach(function (inputPath) {
|
|
var ext = path.extname(inputPath).toLowerCase();
|
|
if (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;
|
|
return gulp.src(assetGroup.inputPaths)
|
|
.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(doConcat, concat(assetGroup.outputFileName)))
|
|
.pipe(autoprefixer({ browsers: ["last 2 versions"] }))
|
|
// TODO: Start using below whenever gulp-header supports sourcemaps.
|
|
.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" +
|
|
//"** For more information, see the Readme.txt file in the Gulp solution folder.\n" +
|
|
"*/\n\n"))
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
.pipe(minify())
|
|
.pipe(rename({
|
|
suffix: ".min"
|
|
}))
|
|
.pipe(gulp.dest(assetGroup.outputDir));
|
|
}
|
|
|
|
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;
|
|
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,
|
|
sortOutput: true,
|
|
}).js))
|
|
.pipe(gulpif(doConcat, concat(assetGroup.outputFileName)))
|
|
// TODO: Start using below whenever gulp-header supports sourcemaps.
|
|
.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" +
|
|
//"** For more information, see the Readme.txt file in the Gulp solution folder.\n" +
|
|
"*/\n\n"))
|
|
.pipe(gulpif(generateSourceMaps, sourcemaps.write()))
|
|
.pipe(gulp.dest(assetGroup.outputDir))
|
|
.pipe(uglify())
|
|
.pipe(rename({
|
|
suffix: ".min"
|
|
}))
|
|
.pipe(gulp.dest(assetGroup.outputDir));
|
|
}
|