2023-04-11 09:21:20 +00:00
|
|
|
import gulp from "gulp";
|
|
|
|
import sass from "gulp-dart-sass";
|
|
|
|
import rename from "gulp-rename";
|
|
|
|
import rewrite from "gulp-rewrite-css";
|
|
|
|
import concat from "gulp-concat";
|
|
|
|
import lazypipe from "lazypipe";
|
|
|
|
import gulpif from "gulp-if";
|
|
|
|
import terser from "gulp-terser";
|
|
|
|
import sourcemaps from "gulp-sourcemaps";
|
|
|
|
import path, * as pathDir from "path";
|
|
|
|
import fs from "fs";
|
|
|
|
import rtlcss from "gulp-rtlcss";
|
|
|
|
import cleancss from "gulp-clean-css";
|
|
|
|
import yargs from "yargs";
|
|
|
|
import {hideBin} from 'yargs/helpers'
|
2023-09-26 09:39:39 +00:00
|
|
|
import {glob} from "glob";
|
2023-04-11 09:21:20 +00:00
|
|
|
import {fileURLToPath} from 'url';
|
|
|
|
import {build} from "./build.js";
|
|
|
|
|
|
|
|
const argv = yargs(hideBin(process.argv)).argv;
|
|
|
|
|
|
|
|
// merge with default parameters
|
|
|
|
const args = Object.assign(
|
|
|
|
{
|
|
|
|
prod: false,
|
|
|
|
sass: false,
|
|
|
|
js: false,
|
|
|
|
media: false,
|
|
|
|
},
|
|
|
|
argv
|
|
|
|
);
|
|
|
|
|
|
|
|
let allAssets = false;
|
|
|
|
if (args.sass === false && args.js === false && args.media === false) {
|
|
|
|
allAssets = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// default variable config
|
|
|
|
const config = Object.assign(
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
demo: "",
|
|
|
|
debug: true,
|
|
|
|
compile: {
|
|
|
|
jsMinify: false,
|
|
|
|
cssMinify: false,
|
|
|
|
jsSourcemaps: false,
|
|
|
|
cssSourcemaps: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
build.config
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Walk into object recursively
|
|
|
|
* @param array
|
|
|
|
* @param funcname
|
|
|
|
* @param userdata
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
function objectWalkRecursive(array, funcname, userdata) {
|
|
|
|
if (!array || typeof array !== 'object') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (typeof funcname !== 'function') {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let key in array) {
|
|
|
|
// apply "funcname" recursively only on object
|
|
|
|
if (Object.prototype.toString.call(array[key]) === '[object Object]') {
|
|
|
|
const funcArgs = [array[key], funcname];
|
|
|
|
if (arguments.length > 2) {
|
|
|
|
funcArgs.push(userdata);
|
|
|
|
}
|
|
|
|
if (objectWalkRecursive.apply(null, funcArgs) === false) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// continue
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
if (arguments.length > 2) {
|
|
|
|
funcname(array[key], key, userdata);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
funcname(array[key], key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
console.error('e', e);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add JS compilation options to gulp pipe
|
|
|
|
*/
|
|
|
|
const jsChannel = () => {
|
|
|
|
const { compile } = config;
|
|
|
|
const { jsSourcemaps, jsMinify } = compile;
|
|
|
|
return lazypipe()
|
|
|
|
.pipe(() => {
|
|
|
|
return gulpif(
|
|
|
|
jsSourcemaps,
|
2023-09-26 09:39:39 +00:00
|
|
|
sourcemaps.init({ loadMaps: true, debug: config.debug }),
|
|
|
|
sourcemaps.init({ loadMaps: true, debug: config.debug }),
|
2023-04-11 09:21:20 +00:00
|
|
|
);
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
|
|
|
return gulpif(jsMinify, terser());
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
2023-09-26 09:39:39 +00:00
|
|
|
return gulpif(
|
|
|
|
jsSourcemaps,
|
|
|
|
sourcemaps.write("./"),
|
|
|
|
sourcemaps.write(null, {addComment: false})
|
|
|
|
);
|
2023-04-11 09:21:20 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add CSS compilation options to gulp pipe
|
|
|
|
*/
|
|
|
|
const cssChannel = (rtl, includePaths) => {
|
|
|
|
const { compile } = config;
|
|
|
|
const { cssSourcemaps, cssMinify } = compile;
|
|
|
|
return lazypipe()
|
|
|
|
.pipe(() => {
|
|
|
|
return gulpif(
|
|
|
|
cssSourcemaps,
|
|
|
|
sourcemaps.init({ loadMaps: true, debug: config.debug })
|
|
|
|
);
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
|
|
|
return sass({
|
|
|
|
errLogToConsole: true,
|
|
|
|
includePaths: [build.config.path.src + "/sass", "node_modules"].concat(
|
|
|
|
includePaths
|
|
|
|
),
|
|
|
|
// outputStyle: config.cssMinify ? 'compressed' : '',
|
|
|
|
}).on("error", sass.logError);
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
|
|
|
// convert rtl for style.bundle.css only here, others already converted before
|
|
|
|
return gulpif(rtl, rtlcss());
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
|
|
|
return gulpif(cssMinify, cleancss());
|
|
|
|
})
|
|
|
|
.pipe(() => {
|
|
|
|
return gulpif(cssSourcemaps, sourcemaps.write("./"));
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiple output paths by output config
|
|
|
|
* @param path
|
|
|
|
* @param outputFile
|
|
|
|
* @param type
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
const outputChannel = (path, outputFile, type) => {
|
|
|
|
if (!allAssets) {
|
|
|
|
if (args.sass && ["styles"].indexOf(type) === -1) {
|
|
|
|
return lazypipe().pipe(() => {
|
|
|
|
// noop
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (args.js && ["scripts"].indexOf(type) === -1) {
|
|
|
|
return lazypipe().pipe(() => {
|
|
|
|
// noop
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (args.media && ["media", "fonts", "images"].indexOf(type) === -1) {
|
|
|
|
return lazypipe().pipe(() => {
|
|
|
|
// noop
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof path === "undefined") {
|
|
|
|
console.log("Output path not defined");
|
|
|
|
}
|
|
|
|
if (typeof outputFile === "undefined") {
|
|
|
|
outputFile = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
let piping = lazypipe();
|
|
|
|
|
|
|
|
if (type === "styles") {
|
|
|
|
piping = piping.pipe(() => {
|
|
|
|
return gulpif(
|
|
|
|
build.config.compile.cssMinify,
|
|
|
|
rename({ suffix: args.suffix ? ".min" : "" })
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type === "scripts") {
|
|
|
|
piping = piping.pipe(() => {
|
|
|
|
return gulpif(
|
|
|
|
build.config.compile.jsMinify,
|
|
|
|
rename({ suffix: args.suffix ? ".min" : "" })
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const regex = new RegExp(/\{\$.*?\}/);
|
|
|
|
const matched = path.match(regex);
|
|
|
|
// {$config.dist}/plugins/global/fonts/fonticon
|
|
|
|
if (matched) {
|
|
|
|
const outputs = build.config.dist;
|
|
|
|
outputs.forEach((output) => {
|
|
|
|
let outputPath = path.replace(matched[0], output).replace(outputFile, "");
|
|
|
|
(function (_output) {
|
|
|
|
piping = piping.pipe(() => {
|
|
|
|
return gulp.dest(_output);
|
|
|
|
});
|
|
|
|
})(outputPath);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof cb !== 'undefined') {
|
|
|
|
cb();
|
|
|
|
}
|
|
|
|
|
|
|
|
return piping;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert string path to actual path
|
|
|
|
* @param path
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
const dotPath = (path) => {
|
|
|
|
const regex = new RegExp(/\{\$(.*?)\}/),
|
|
|
|
dot = (obj, i) => {
|
|
|
|
return obj[i];
|
|
|
|
};
|
|
|
|
const matched = path.match(regex);
|
|
|
|
if (matched) {
|
|
|
|
const realpath = matched[1].split(".").reduce(dot, build);
|
|
|
|
return path.replace(matched[0], realpath);
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert multiple paths
|
|
|
|
* @param paths
|
|
|
|
*/
|
|
|
|
const dotPaths = (paths) => {
|
|
|
|
paths.forEach((path, i) => {
|
|
|
|
paths[i] = dotPath(path);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Css path rewriter when bundle files moved
|
|
|
|
* @param bundle
|
|
|
|
*/
|
|
|
|
const cssRewriter = (bundle) => {
|
|
|
|
const imgRegex = new RegExp(/\.(gif|jpg|jpeg|tiff|png|ico|svg)$/i);
|
|
|
|
|
|
|
|
return lazypipe().pipe(() => {
|
|
|
|
// rewrite css relative path
|
|
|
|
return rewrite({
|
|
|
|
destination: bundle["styles"],
|
|
|
|
debug: config.debug,
|
|
|
|
adaptPath: (ctx) => {
|
|
|
|
const isCss = ctx.sourceFile.match(/\.[css]+$/i);
|
|
|
|
// process css only
|
|
|
|
if (isCss[0] === ".css") {
|
|
|
|
if (/plugins.*?bundle/.test(bundle["styles"])) {
|
|
|
|
const pieces = ctx.sourceDir.split(/\\|\//);
|
|
|
|
// only vendors/base pass this
|
|
|
|
let vendor = pieces[pieces.indexOf("node_modules") + 1];
|
|
|
|
if (pieces.indexOf("node_modules") === -1) {
|
|
|
|
vendor = pieces[pieces.indexOf("plugins") + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
let extension = "fonts/";
|
|
|
|
if (imgRegex.test(ctx.targetFile)) {
|
|
|
|
extension = "images/";
|
|
|
|
}
|
|
|
|
|
|
|
|
return path.join(extension, vendor, path.basename(ctx.targetFile));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.targetFile.replace(/\.?\.\//, "");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get end filename from path
|
|
|
|
* @param path
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
const baseFileName = (path) => {
|
|
|
|
const maybeFile = path.split("/").pop();
|
|
|
|
if (maybeFile.indexOf(".") !== -1) {
|
|
|
|
return maybeFile;
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
};
|
|
|
|
|
|
|
|
const baseName = (str, extension) => {
|
|
|
|
let base = new String(str).substring(str.lastIndexOf("/") + 1);
|
|
|
|
if (!extension && base.lastIndexOf(".") != -1) {
|
|
|
|
base = base.substring(0, base.lastIndexOf("."));
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove file name and get the path
|
|
|
|
*/
|
|
|
|
const pathOnly = (str) => {
|
|
|
|
const array = str.split("/");
|
|
|
|
if (array.length > 0) {
|
|
|
|
array.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
return array.join("/");
|
|
|
|
};
|
|
|
|
|
|
|
|
const getDemos = () => {
|
|
|
|
if (build.build.demos) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
let demos = Object.keys(build.build.demos);
|
|
|
|
// build by demo, leave demo empty to generate all demos
|
|
|
|
if (typeof build.config.demo !== "undefined" && build.config.demo !== "") {
|
|
|
|
demos = build.config.demo.split(",").map((item) => {
|
|
|
|
return item.trim();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return demos;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getFolders = (dir) => {
|
|
|
|
try {
|
|
|
|
return fs.readdirSync(dir).filter((file) => {
|
|
|
|
return fs.statSync(path.join(dir, file)).isDirectory();
|
|
|
|
});
|
|
|
|
}catch(e) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const getParameters = () => {
|
|
|
|
// remove first 2 unused elements from array
|
|
|
|
let argv = JSON.parse(process.env.npm_config_argv).cooked.slice(2);
|
|
|
|
argv = argv.map((arg) => {
|
|
|
|
return arg.replace(/--/i, "");
|
|
|
|
});
|
|
|
|
return argv;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getDemo = () => {
|
|
|
|
// get demo from parameters
|
|
|
|
let demo = Object.keys(argv)
|
|
|
|
.join(" ")
|
|
|
|
.match(/(demo\d+)/gi) || "";
|
|
|
|
|
|
|
|
if (typeof demo === "object") {
|
|
|
|
demo = demo[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
return demo;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getTheme = () => {
|
|
|
|
// get demo from parameters
|
|
|
|
const theme = Object.keys(argv)[1];
|
|
|
|
const folders = getFolders(build.config.path.src.split("{theme}")[0]);
|
|
|
|
if (folders.indexOf(theme) !== -1) {
|
|
|
|
return theme;
|
|
|
|
}
|
|
|
|
// default theme
|
|
|
|
return "";
|
|
|
|
};
|
|
|
|
|
|
|
|
const bundleStreams = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bundle
|
|
|
|
* @param bundle
|
|
|
|
*/
|
|
|
|
const bundle = (bundle) => {
|
|
|
|
let stream;
|
|
|
|
|
|
|
|
if (bundle.hasOwnProperty("src") && bundle.hasOwnProperty("dist")) {
|
|
|
|
// for images & fonts as per vendor
|
|
|
|
if ("mandatory" in bundle.src && "optional" in bundle.src) {
|
|
|
|
let vendors = {};
|
|
|
|
|
|
|
|
for (let key in bundle.src) {
|
|
|
|
if (!bundle.src.hasOwnProperty(key)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (key === "override") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
vendors = Object.assign(vendors, bundle.src[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let vendor in vendors) {
|
|
|
|
if (!vendors.hasOwnProperty(vendor)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const vendorObj = vendors[vendor];
|
|
|
|
|
|
|
|
for (let type in vendorObj) {
|
|
|
|
if (!vendorObj.hasOwnProperty(type)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
dotPaths(vendorObj[type]);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case "fonts":
|
|
|
|
stream = gulp.src(vendorObj[type], { allowEmpty: true });
|
|
|
|
const outputFonts = outputChannel(bundle.dist[type] + "/" + vendor, undefined, type)();
|
|
|
|
if (outputFonts) {
|
|
|
|
stream.pipe(outputFonts);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
break;
|
|
|
|
case "images":
|
|
|
|
stream = gulp.src(vendorObj[type], { allowEmpty: true });
|
|
|
|
const outputImages = outputChannel(bundle.dist[type] + "/" + vendor, undefined, type)();
|
|
|
|
if (outputImages) {
|
|
|
|
stream.pipe(outputImages);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// flattening array
|
|
|
|
if (!("styles" in bundle.src) && !("scripts" in bundle.src)) {
|
|
|
|
const src = { styles: [], scripts: [] };
|
|
|
|
objectWalkRecursive(bundle.src, (paths, type) => {
|
|
|
|
switch (type) {
|
|
|
|
case "styles":
|
|
|
|
case "scripts":
|
|
|
|
src[type] = src[type].concat(paths);
|
|
|
|
break;
|
|
|
|
case "images":
|
|
|
|
// images for mandatory and optional vendor already processed
|
|
|
|
if (!"mandatory" in bundle.src || !"optional" in bundle.src) {
|
|
|
|
src[type] = src[type].concat(paths);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
bundle.src = src;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let type in bundle.src) {
|
|
|
|
if (!bundle.src.hasOwnProperty(type)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// skip if not array
|
|
|
|
if (
|
|
|
|
Object.prototype.toString.call(bundle.src[type]) !== "[object Array]"
|
|
|
|
) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// skip if no bundle output is provided
|
|
|
|
if (typeof bundle.dist[type] === "undefined") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
dotPaths(bundle.src[type]);
|
|
|
|
const outputFile = baseFileName(bundle.dist[type]);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case "styles":
|
|
|
|
if (bundle.dist.hasOwnProperty(type)) {
|
|
|
|
|
|
|
|
// rtl css bundle
|
|
|
|
if (
|
|
|
|
typeof build.config.compile.rtl !== "undefined" &&
|
|
|
|
build.config.compile.rtl.enabled
|
|
|
|
) {
|
|
|
|
let toRtlFiles = [];
|
|
|
|
let rtlFiles = [];
|
|
|
|
bundle.src[type].forEach((path) => {
|
|
|
|
// get rtl css file path
|
|
|
|
let cssFile =
|
|
|
|
pathOnly(path) + "/" + baseName(path) + ".rtl.css";
|
|
|
|
// check if rtl file is exist
|
|
|
|
if (
|
|
|
|
fs.existsSync(cssFile) &&
|
|
|
|
build.config.compile.rtl.skip.indexOf(baseName(path)) === -1
|
|
|
|
) {
|
|
|
|
rtlFiles = rtlFiles.concat(cssFile);
|
|
|
|
} else {
|
|
|
|
// rtl css file not exist, use default css file
|
|
|
|
cssFile = path;
|
|
|
|
}
|
|
|
|
toRtlFiles = toRtlFiles.concat(cssFile);
|
|
|
|
});
|
|
|
|
|
|
|
|
let shouldRtl = false;
|
|
|
|
if (baseName(bundle.dist[type]) === "style.bundle") {
|
|
|
|
shouldRtl = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const rtlOutput = pathOnly(bundle.dist[type]) + "/" + baseName(bundle.dist[type]) + ".rtl.css";
|
|
|
|
stream = gulp
|
|
|
|
.src(toRtlFiles, { allowEmpty: true })
|
|
|
|
.pipe(cssRewriter(bundle.dist)())
|
|
|
|
.pipe(concat(baseName(bundle.dist[type]) + ".rtl.css"))
|
|
|
|
.pipe(cssChannel(shouldRtl)());
|
|
|
|
const outputRTLCSS = outputChannel(rtlOutput, baseName(bundle.dist[type]) + ".rtl.css", type)();
|
|
|
|
if (outputRTLCSS) {
|
|
|
|
stream.pipe(outputRTLCSS);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
// default css bundle
|
|
|
|
stream = gulp
|
|
|
|
.src(bundle.src[type], { allowEmpty: true })
|
|
|
|
.pipe(cssRewriter(bundle.dist)())
|
|
|
|
.pipe(concat(outputFile))
|
|
|
|
.pipe(cssChannel()());
|
|
|
|
const outputDefaultCSSBundle = outputChannel(bundle.dist[type], outputFile, type)();
|
|
|
|
if (outputDefaultCSSBundle) {
|
|
|
|
stream.pipe(outputDefaultCSSBundle);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "scripts":
|
|
|
|
if (bundle.dist.hasOwnProperty(type)) {
|
|
|
|
stream = gulp
|
|
|
|
.src(bundle.src[type], { allowEmpty: true })
|
|
|
|
.pipe(concat(outputFile))
|
|
|
|
.pipe(jsChannel()())
|
|
|
|
.on("error", console.error.bind(console));
|
|
|
|
const outputScripts = outputChannel(bundle.dist[type], outputFile, type)();
|
|
|
|
if (outputScripts) {
|
|
|
|
stream.pipe(outputScripts);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2023-09-26 09:39:39 +00:00
|
|
|
case "media":
|
2023-04-11 09:21:20 +00:00
|
|
|
case "fonts":
|
|
|
|
case "images":
|
|
|
|
if (bundle.dist.hasOwnProperty(type)) {
|
|
|
|
stream = gulp.src(bundle.src[type], { allowEmpty: true });
|
|
|
|
const outputImages = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (outputImages) {
|
|
|
|
stream.pipe(outputImages);
|
|
|
|
}
|
|
|
|
bundleStreams.push(stream);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bundleStreams;
|
|
|
|
};
|
|
|
|
|
|
|
|
const outputFuncStreams = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy source to output destination
|
|
|
|
* @param bundle
|
|
|
|
*/
|
|
|
|
const outputFunc = (bundle) => {
|
|
|
|
let stream;
|
|
|
|
|
|
|
|
if (bundle.hasOwnProperty("src") && bundle.hasOwnProperty("dist")) {
|
|
|
|
for (let type in bundle.src) {
|
|
|
|
if (!bundle.src.hasOwnProperty(type)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
dotPaths(bundle.src[type]);
|
|
|
|
|
|
|
|
if (bundle.dist.hasOwnProperty(type)) {
|
|
|
|
switch (type) {
|
|
|
|
case "styles":
|
|
|
|
// non rtl styles
|
|
|
|
stream = gulp
|
|
|
|
.src(bundle.src[type], { allowEmpty: true })
|
|
|
|
.pipe(cssChannel()());
|
|
|
|
const outputStyles = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (outputStyles) {
|
|
|
|
stream.pipe(outputStyles);
|
|
|
|
}
|
|
|
|
outputFuncStreams.push(stream);
|
|
|
|
|
|
|
|
// rtl styles for scss
|
|
|
|
let shouldRtl = false;
|
|
|
|
if (
|
|
|
|
typeof build.config.compile.rtl !== "undefined" &&
|
|
|
|
build.config.compile.rtl.enabled
|
|
|
|
) {
|
|
|
|
bundle.src[type].forEach((output) => {
|
|
|
|
if (output.indexOf(".scss") !== -1) {
|
|
|
|
shouldRtl = true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
stream = gulp
|
|
|
|
.src(bundle.src[type], { allowEmpty: true })
|
|
|
|
.pipe(cssChannel(shouldRtl)())
|
|
|
|
.pipe(rename({ suffix: ".rtl" }));
|
|
|
|
const rtlOutput = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (rtlOutput) {
|
|
|
|
stream.pipe(rtlOutput);
|
|
|
|
}
|
|
|
|
outputFuncStreams.push(stream);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "scripts":
|
|
|
|
/**
|
|
|
|
* START: bundle by folder
|
|
|
|
*/
|
|
|
|
bundle.src[type].forEach((file) => {
|
|
|
|
const needBundleFileWildLocation = file.replace(
|
|
|
|
"*.js",
|
|
|
|
"bundle/*.js"
|
|
|
|
);
|
|
|
|
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
|
|
const __dirname = pathDir.dirname(__filename);
|
|
|
|
const needBundleFiles = glob.sync(
|
|
|
|
path.resolve(__dirname, "../" + needBundleFileWildLocation)
|
|
|
|
);
|
|
|
|
if (needBundleFiles.length > 0) {
|
|
|
|
const needBundleByGroup = [];
|
|
|
|
needBundleFiles.forEach((js) => {
|
|
|
|
const p = path.dirname(js);
|
|
|
|
if (typeof needBundleByGroup[p] === "undefined") {
|
|
|
|
needBundleByGroup[p] = [];
|
|
|
|
}
|
|
|
|
needBundleByGroup[p].push(js);
|
|
|
|
});
|
|
|
|
|
|
|
|
for (let g in needBundleByGroup) {
|
|
|
|
if (!needBundleByGroup.hasOwnProperty(g)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const files = needBundleByGroup[g];
|
|
|
|
|
|
|
|
// remove ${config.dist}
|
|
|
|
const separatorDir = bundle.dist[type].replace(
|
|
|
|
/{\$config\.dist}/,
|
|
|
|
""
|
|
|
|
);
|
|
|
|
// get sub dir
|
|
|
|
const needBundleDir = files[0].split(separatorDir)[1];
|
|
|
|
const needBundleOutputPath = needBundleDir.replace(
|
|
|
|
/^(.*?)\/(bundle)\/.*?\.(js)$/,
|
|
|
|
"$1.$2.$3"
|
|
|
|
);
|
|
|
|
|
|
|
|
const needBundleStream = gulp
|
|
|
|
.src(files)
|
|
|
|
.pipe(concat(needBundleOutputPath))
|
|
|
|
.pipe(jsChannel()())
|
|
|
|
.on("error", console.error.bind(console));
|
|
|
|
const needBundleOutput = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (needBundleOutput) {
|
|
|
|
needBundleStream.pipe(needBundleOutput);
|
|
|
|
}
|
|
|
|
outputFuncStreams.push(needBundleStream);
|
|
|
|
|
|
|
|
// exclude bundle folder from next gulp process
|
|
|
|
bundle.src[type].push(
|
|
|
|
"!" +
|
|
|
|
path
|
|
|
|
.dirname(needBundleFileWildLocation)
|
|
|
|
.replace(/\*+?\/bundle/, "") +
|
|
|
|
needBundleDir.replace(/\/bundle.*?$/, "/**")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
/**
|
|
|
|
* END: bundle by folder
|
|
|
|
*/
|
|
|
|
|
|
|
|
stream = gulp
|
|
|
|
.src(bundle.src[type], { allowEmpty: true })
|
|
|
|
.pipe(jsChannel()())
|
|
|
|
.on("error", console.error.bind(console));
|
|
|
|
const output2 = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (output2) {
|
|
|
|
stream.pipe(output2);
|
|
|
|
}
|
|
|
|
outputFuncStreams.push(stream);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
stream = gulp.src(bundle.src[type], { allowEmpty: true });
|
|
|
|
const outputDefault = outputChannel(bundle.dist[type], undefined, type)();
|
|
|
|
if (outputDefault) {
|
|
|
|
stream.pipe(outputDefault);
|
|
|
|
}
|
|
|
|
outputFuncStreams.push(stream);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputFuncStreams;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Exports
|
|
|
|
export {
|
|
|
|
argv,
|
|
|
|
getDemo,
|
|
|
|
getTheme,
|
|
|
|
objectWalkRecursive,
|
|
|
|
dotPath,
|
|
|
|
pathOnly,
|
|
|
|
outputFunc,
|
|
|
|
bundle,
|
|
|
|
getFolders,
|
|
|
|
};
|