Compare commits

...

10 Commits

Author SHA1 Message Date
Benjamin Toby
e6e2fa65cb First Commit 2025-01-16 07:21:31 +01:00
Benjamin Toby
2cb578d38b Add Less compiler dependency 2023-09-30 19:39:11 +01:00
Benjamin Toby
cb5f1a0efd bugfix 2023-09-30 19:36:01 +01:00
Benoti
59d73239d8 updates 2023-09-01 12:32:35 +01:00
Tben
5dc871d8db Update License 2023-08-04 12:19:46 +01:00
Tben
1ac9bb4fbe updates 2023-08-01 04:07:10 +01:00
Tben
e3498601a1 Bugfixes 2023-07-30 12:38:44 +01:00
Tben
f256310387 Upgrade 2023-07-30 10:06:18 +01:00
Tben
d138241473 Code Upgrade 2023-07-30 07:34:34 +01:00
Tben
d19dc7ae08 Code Upgrade 2023-07-30 07:34:15 +01:00
11 changed files with 769 additions and 404 deletions

View File

@ -30,7 +30,7 @@ There are few different ways to run your less compiler
npx lessc-watcher --src ./folder --dst ./dist/less.css npx lessc-watcher --src ./folder --dst ./dist/less.css
``` ```
This traverses the folder and searches for a `main.less` file. This file serves as the source for your bundled `.css` file. If you want to target a specific file, use: This traverses the `--src` folder and searches for a `main.less` file. This file serves as the source for your bundled `.css` file. If you want to target a specific file, use:
```bash ```bash
npx lessc-watcher --src ./folder/src.less --dst ./dist/less.css npx lessc-watcher --src ./folder/src.less --dst ./dist/less.css

BIN
bun.lockb Executable file

Binary file not shown.

283
dist/index.js vendored
View File

@ -6,111 +6,242 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs")); const fs_1 = __importDefault(require("fs"));
const child_process_1 = require("child_process"); const child_process_1 = require("child_process");
if (fs_1.default.existsSync("./lesscw.config.json")) { const grabSrcDisStrings = () => {
if (process.argv.indexOf("--src") >= 0 || process.argv.indexOf("--dst") >= 0) { let srcArray = [];
let dstArray = [];
if (fs_1.default.existsSync("./lesscw.config.json")) {
if (process.argv.indexOf("--src")) {
try {
process.argv.splice(process.argv.indexOf("--src"));
}
catch (error) { }
}
try { try {
process.argv.splice(process.argv.indexOf("--src")); const configObject = JSON.parse(fs_1.default.readFileSync("./lesscw.config.json", "utf-8"));
process.argv.splice(process.argv.indexOf("--dst")); if ((configObject === null || configObject === void 0 ? void 0 : configObject.src) &&
} (configObject === null || configObject === void 0 ? void 0 : configObject.dst) &&
catch (error) { } typeof configObject.src === "string" &&
} typeof configObject.dst === "string") {
try { srcArray = configObject.src.split(",");
const configObject = JSON.parse(fs_1.default.readFileSync("./lesscw.config.json", "utf-8")); dstArray = configObject.dst.split(",");
if ((configObject === null || configObject === void 0 ? void 0 : configObject.src) && (configObject === null || configObject === void 0 ? void 0 : configObject.dst) && typeof configObject.src === "string" && typeof configObject.dst === "string") { }
process.argv.push("--src", configObject.src); else if ((configObject === null || configObject === void 0 ? void 0 : configObject.src) &&
process.argv.push("--dst", configObject.dst); (configObject === null || configObject === void 0 ? void 0 : configObject.dst) &&
} typeof configObject.src === "object" &&
else if ((configObject === null || configObject === void 0 ? void 0 : configObject.src) && (configObject === null || configObject === void 0 ? void 0 : configObject.dst) && typeof configObject.src === "object" && typeof configObject.dst === "object" && Array.isArray(configObject.src) && Array.isArray(configObject.dst)) { typeof configObject.dst === "object" &&
process.argv.push("--src", configObject.src.join(",")); Array.isArray(configObject.src) &&
process.argv.push("--dst", configObject.dst.join(",")); Array.isArray(configObject.dst)) {
} srcArray = configObject.src;
else if ((configObject === null || configObject === void 0 ? void 0 : configObject.srcDst) && Array.isArray(configObject.srcDst) && configObject.srcDst.length > 0) { dstArray = configObject.dst;
const srcDstArray = configObject.srcDst; }
let srcArray = []; else if ((configObject === null || configObject === void 0 ? void 0 : configObject.srcDst) &&
let dstArray = []; Array.isArray(configObject.srcDst) &&
srcDstArray.forEach((item) => { configObject.srcDst.length > 0) {
if ((item === null || item === void 0 ? void 0 : item.src) && (item === null || item === void 0 ? void 0 : item.dst) && typeof item.src === "string" && typeof item.dst === "string") { const srcDstArray = configObject.srcDst;
srcArray.push(item.src); srcDstArray.forEach((item) => {
dstArray.push(item.dst); if ((item === null || item === void 0 ? void 0 : item.src) &&
} (item === null || item === void 0 ? void 0 : item.dst) &&
}); typeof item.src === "string" &&
if (srcArray.length && dstArray.length) { typeof item.dst === "string") {
process.argv.push("--src", srcArray.join(",")); srcArray.push(item.src);
process.argv.push("--dst", dstArray.join(",")); dstArray.push(item.dst);
}
});
}
else {
console.log("- \x1b[31mERROR:\x1b[0m Your config file has some errors. Please check your config file");
process.exit();
} }
} }
catch (error) {
console.log("- \x1b[31mERROR:\x1b[0m Your config file has some errors. ERROR =>", error.message);
process.exit();
}
} }
catch (error) { else {
console.log("ERROR in your config file =>", error.message); if (process.argv.indexOf("--src") >= 0 &&
process.exit(); process.argv.indexOf("--dst") >= 0) {
try {
srcArray =
process.argv[process.argv.indexOf("--src") + 1].split(",");
dstArray =
process.argv[process.argv.indexOf("--dst") + 1].split(",");
}
catch (error) { }
}
else {
console.log("- \x1b[31mERROR:\x1b[0m Missing source or destination file");
process.exit();
}
} }
return {
sourceFile: srcArray.join(","),
destinationFile: dstArray.join(","),
};
};
const { sourceFile, destinationFile } = grabSrcDisStrings();
if (sourceFile && destinationFile) {
process.argv.push("--src", sourceFile, "--dst", destinationFile);
} }
const sourceFile = process.argv.indexOf("--src") >= 0 ? process.argv[process.argv.indexOf("--src") + 1] : null; console.log("- \x1b[35mStart:\x1b[0m Running Less compiler ...");
const destinationFile = process.argv.indexOf("--dst") >= 0 ? process.argv[process.argv.indexOf("--dst") + 1] : null;
console.log("\x1b[44mRunning Less compiler\x1b[0m ...");
if (!sourceFile || !destinationFile) { if (!sourceFile || !destinationFile) {
console.log("\x1b[33mERROR:\x1b[0m => Missing source or destination file"); console.log("- \x1b[31mERROR:\x1b[0m => Missing source or destination file");
process.exit(); process.exit();
} }
const sourceFiles = sourceFile.split(","); function traverseFiles(src, dst) {
const dstFiles = destinationFile.split(","); var _a;
for (let i = 0; i < sourceFiles.length; i++) { const sourceFiles = src.split(",");
const srcFolder = sourceFiles[i]; const dstFiles = dst.split(",");
const dstFile = dstFiles[i]; for (let i = 0; i < sourceFiles.length; i++) {
if ((srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.[^\/]+$/)) && !(srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/))) { const srcFolder = sourceFiles[i];
console.log("\x1b[33mERROR:\x1b[0m Source must be a folder or a .less file"); const dstFile = dstFiles[i];
process.exit(); if ((srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\/[^\/]+\.[^\/]+$/)) &&
} !(srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/))) {
compile(srcFolder, dstFile, null); console.log("- \x1b[31mERROR:\x1b[0m Source must be a folder or a .less file");
if (!fs_1.default.existsSync(srcFolder)) { process.exit();
}
if (!fs_1.default.existsSync(srcFolder)) {
if (srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/)) {
fs_1.default.mkdirSync(srcFolder.replace(/\/[^\/]+\.less$/, ""), {
recursive: true,
});
fs_1.default.writeFileSync(srcFolder, "", "utf-8");
}
else {
fs_1.default.mkdirSync(srcFolder.replace(/\/[^\/]+\.[^\/]+$/, ""), {
recursive: true,
});
fs_1.default.writeFileSync((srcFolder + "/main.less").replace(/\/\//g, ""), "", "utf-8");
}
}
else if (fs_1.default.existsSync(srcFolder) &&
fs_1.default.existsSync((srcFolder + "/main.less").replace(/\/\//g, ""))) {
}
if (!fs_1.default.existsSync(dstFile)) {
if (dstFile === null || dstFile === void 0 ? void 0 : dstFile.match(/\.css$/)) {
fs_1.default.mkdirSync(dstFile.replace(/\/[^\/]+\.css$/, ""), {
recursive: true,
});
}
else {
fs_1.default.mkdirSync(dstFile.replace(/\/[^\/]+\.[^\/]+$/, ""), {
recursive: true,
});
}
}
compile(srcFolder, dstFile, null);
try {
fs_1.default.readdirSync(srcFolder).forEach((file) => {
if (file === null || file === void 0 ? void 0 : file.match(/^\[.*\.less$/)) {
compile(srcFolder + "/" + file, dstFile, null);
}
});
}
catch (error) { }
if (srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/)) { if (srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/)) {
fs_1.default.mkdirSync(srcFolder.replace(/\/[^\/]+\.less$/, ""), { recursive: true }); fs_1.default.watchFile(srcFolder, { interval: 500 }, (current, previous) => {
fs_1.default.writeFileSync(srcFolder, "", "utf-8"); const dstFilePathRoot = (dstFile === null || dstFile === void 0 ? void 0 : dstFile.match(/\.css$/))
? dstFile
: dstFile + "/" + "_main.css";
try {
const currentProcessArgsSrc = process.argv[process.argv.indexOf("--src") + 1];
const activeSourceFiles = currentProcessArgsSrc.split(",");
if (activeSourceFiles.includes(srcFolder)) {
compile(srcFolder, dstFilePathRoot, null);
}
else {
fs_1.default.unwatchFile(srcFolder);
}
}
catch (error) {
console.log("- \x1b[31mERROR:\x1b[0m Please check your config file =>", error.message);
}
});
}
else if (!(srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.[^\/]+$/))) {
fs_1.default.watch(srcFolder, {
recursive: ((_a = process.platform) === null || _a === void 0 ? void 0 : _a.match(/win32/i))
? true
: undefined,
}, (evtType, fileName) => {
if (!(evtType === null || evtType === void 0 ? void 0 : evtType.match(/change/i))) {
return;
}
if (!fileName)
return;
const srcFilePathRoot = srcFolder + "/main.less";
try {
const currentProcessArgsSrc = process.argv[process.argv.indexOf("--src") + 1];
const activeSourceFiles = currentProcessArgsSrc.split(",");
if (fileName === null || fileName === void 0 ? void 0 : fileName.match(/^\[/)) {
compile(srcFolder + "/" + fileName, dstFile, evtType);
}
else if ((fileName === null || fileName === void 0 ? void 0 : fileName.match(/^\(/)) ||
activeSourceFiles.includes(srcFilePathRoot)) {
return;
}
else {
compile(srcFilePathRoot, dstFile, evtType);
}
}
catch (error) {
console.log("- \x1b[31mERROR:\x1b[0m Please check your config file =>", error.message);
}
});
} }
else { else {
fs_1.default.mkdirSync(srcFolder.replace(/\/[^\/]+\.[^\/]+$/, ""), { recursive: true }); console.log("- \x1b[31mERROR:\x1b[0m Source must be a folder or a .less file");
process.exit();
} }
} }
if (!fs_1.default.existsSync(dstFile)) {
if (dstFile === null || dstFile === void 0 ? void 0 : dstFile.match(/\.css$/)) {
fs_1.default.mkdirSync(dstFile.replace(/\/[^\/]+\.css$/, ""), { recursive: true });
fs_1.default.writeFileSync(dstFile, "", "utf-8");
}
else {
fs_1.default.mkdirSync(dstFile.replace(/\/[^\/]+\.[^\/]+$/, ""), { recursive: true });
fs_1.default.writeFileSync((dstFile + "/_main.css").replace(/\/\//g, ""), "", "utf-8");
}
}
fs_1.default.watch(srcFolder, { recursive: true }, (evtType, fileName) => {
if (!fileName)
return;
const filePathRoot = (srcFolder === null || srcFolder === void 0 ? void 0 : srcFolder.match(/\.less$/)) ? srcFolder : srcFolder + "/" + fileName;
compile(filePathRoot, dstFile, evtType);
});
} }
traverseFiles(sourceFile, destinationFile);
function compile(fileName, dst, evtType) { function compile(fileName, dst, evtType) {
if ((fileName === null || fileName === void 0 ? void 0 : fileName.match(/\(/)) || (fileName.match(/\..{2,4}$/) && !(fileName === null || fileName === void 0 ? void 0 : fileName.match(/\.less$/i)))) { if ((fileName === null || fileName === void 0 ? void 0 : fileName.match(/\(/)) ||
(fileName.match(/\.[\/]$/) && !(fileName === null || fileName === void 0 ? void 0 : fileName.match(/\.less$/i)))) {
return; return;
} }
let finalSrcPath = (fileName === null || fileName === void 0 ? void 0 : fileName.match(/\.less$/)) ? fileName : `${fileName}/main.less`; let finalSrcPath = (fileName === null || fileName === void 0 ? void 0 : fileName.match(/\.less$/))
let finalDstPath = dst; ? fileName
: `${fileName}/main.less`;
const distFolder = (dst === null || dst === void 0 ? void 0 : dst.match(/\.css$/)) ? null : dst === null || dst === void 0 ? void 0 : dst.replace(/\/+$/, "");
let finalDstPath = distFolder ? `${distFolder}/_main.css` : dst;
if (distFolder && !fs_1.default.existsSync(distFolder)) {
fs_1.default.mkdirSync(distFolder, { recursive: true });
}
if (fileName === null || fileName === void 0 ? void 0 : fileName.match(/\[/)) { if (fileName === null || fileName === void 0 ? void 0 : fileName.match(/\[/)) {
const paths = fileName.split("/"); const paths = fileName.split("/");
const targetPathFull = paths[paths.length - 1]; const targetPathFull = paths[paths.length - 1];
const targetPath = targetPathFull.replace(/\[|\]/g, "").replace(/\.less/, ""); const targetPath = targetPathFull
.replace(/\[|\]/g, "")
.replace(/\.less/, "");
const destinationFileParentFolder = dst.replace(/\/[^\/]+\.css$/, ""); const destinationFileParentFolder = dst.replace(/\/[^\/]+\.css$/, "");
const targetDstFilePath = `${destinationFileParentFolder}/${targetPath}.css`; const targetDstFilePath = `${destinationFileParentFolder}/${targetPath}.css`;
finalSrcPath = `${fileName}/${targetPathFull}`; finalSrcPath = fileName;
finalDstPath = targetDstFilePath; finalDstPath = targetDstFilePath;
} }
(0, child_process_1.exec)(`lessc ${finalSrcPath} ${(finalDstPath === null || finalDstPath === void 0 ? void 0 : finalDstPath.match(/\.css$/)) ? finalDstPath : finalDstPath.replace(/\/$/, "") + "/_main.css"}`, (error, stdout, stderr) => { const executionCmd = `lessc ${finalSrcPath} ${finalDstPath}`;
(0, child_process_1.exec)(executionCmd, (error, stdout, stderr) => {
if (error) { if (error) {
console.log("ERROR =>", error.message); console.log("- \x1b[33mWarn:\x1b[0m Compilation didn't run successfully. ERROR =>", error.message);
if (!(evtType === null || evtType === void 0 ? void 0 : evtType.match(/change/i)) && fileName && fileName.match(/\[/)) { if (!(evtType === null || evtType === void 0 ? void 0 : evtType.match(/change/i)) &&
fileName &&
fileName.match(/\[/)) {
fs_1.default.unlinkSync(finalDstPath); fs_1.default.unlinkSync(finalDstPath);
} }
return; return;
} }
console.log("Less Compilation \x1b[32msuccessful\x1b[0m!"); console.log("- \x1b[32mCompiled:\x1b[0m Less Compilation Successful!");
});
}
if (fs_1.default.existsSync("./lesscw.config.json")) {
fs_1.default.watchFile("./lesscw.config.json", { interval: 500 }, (evtType, fileName) => {
console.log("- \x1b[34mInfo:\x1b[0m Restarting process...");
const newSrcDistStrings = grabSrcDisStrings();
if (newSrcDistStrings.destinationFile &&
newSrcDistStrings.sourceFile) {
process.argv.push("--src", newSrcDistStrings.sourceFile, "--dst", newSrcDistStrings.destinationFile);
traverseFiles(newSrcDistStrings.sourceFile, newSrcDistStrings.destinationFile);
}
}); });
} }

22
package-lock.json generated
View File

@ -1,22 +0,0 @@
{
"name": "lessc-watcher",
"version": "1.0.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "lessc-watcher",
"version": "1.0.3",
"license": "ISC",
"devDependencies": {
"@types/node": "^20.4.5"
}
},
"node_modules/@types/node": {
"version": "20.4.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
"integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==",
"dev": true
}
}
}

View File

@ -1,23 +1,30 @@
{ {
"name": "lessc-watcher", "name": "lessc-watcher",
"version": "1.1.4", "version": "1.2.2",
"description": "A minimal package to watch less files and compile them to css", "description": "A minimal package to watch less files and compile them to css",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
"lessc-watcher": "./dist/index.js" "lessc-watcher": "./dist/index.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/BenjaminToby/less-watcher.git" "url": "git+https://github.com/BenjaminToby/less-watcher.git"
}, },
"keywords": [ "keywords": [
"less", "less",
"watcher", "watcher",
"css" "css"
], ],
"author": "Benjamin Toby", "author": "Benjamin Toby",
"license": "ISC", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "^20.4.5" "@types/node": "^20.4.5",
} "@types/bun": "latest"
},
"dependencies": {
"less": "^4.2.0"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
} }

14
publish.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
tsc
if [ -z "$1" ]; then
msg="Updates"
else
msg="$1"
fi
git add .
git commit -m "$msg"
git push
bun publish

11
push.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
if [ -z "$1" ]; then
msg="Updates"
else
msg="$1"
fi
git add .
git commit -m "$msg"
git push

8
src/index.d.ts vendored
View File

@ -1,8 +0,0 @@
export type LessCssWatcherConfigObject = {
src?: string | string[];
dst?: string | string[];
srcDst?: {
src?: string;
dst?: string;
}[];
};

View File

@ -1,112 +1,280 @@
#! /usr/bin/env node
import fs from "fs"; import fs from "fs";
import { exec } from "child_process"; import { exec } from "child_process";
import { LessCssWatcherConfigObject } from "./index.d";
if (fs.existsSync("./lesscw.config.json")) { export type LessCssWatcherConfigObject = {
if (process.argv.indexOf("--src") >= 0 || process.argv.indexOf("--dst") >= 0) { src?: string | string[];
try { dst?: string | string[];
process.argv.splice(process.argv.indexOf("--src")); srcDst?: {
process.argv.splice(process.argv.indexOf("--dst")); src?: string;
} catch (error) {} dst?: string;
} }[];
};
try { const grabSrcDisStrings = () => {
const configObject: LessCssWatcherConfigObject = JSON.parse(fs.readFileSync("./lesscw.config.json", "utf-8")); let srcArray: string[] = [];
let dstArray: string[] = [];
if (configObject?.src && configObject?.dst && typeof configObject.src === "string" && typeof configObject.dst === "string") { if (fs.existsSync("./lesscw.config.json")) {
process.argv.push("--src", configObject.src); if (process.argv.indexOf("--src")) {
process.argv.push("--dst", configObject.dst); try {
} else if (configObject?.src && configObject?.dst && typeof configObject.src === "object" && typeof configObject.dst === "object" && Array.isArray(configObject.src) && Array.isArray(configObject.dst)) { process.argv.splice(process.argv.indexOf("--src"));
process.argv.push("--src", configObject.src.join(",")); } catch (error) {}
process.argv.push("--dst", configObject.dst.join(",")); }
} else if (configObject?.srcDst && Array.isArray(configObject.srcDst) && configObject.srcDst.length > 0) {
const srcDstArray = configObject.srcDst; try {
const configObject: LessCssWatcherConfigObject = JSON.parse(
let srcArray: string[] = []; fs.readFileSync("./lesscw.config.json", "utf-8")
let dstArray: string[] = []; );
srcDstArray.forEach((item) => { if (
if (item?.src && item?.dst && typeof item.src === "string" && typeof item.dst === "string") { configObject?.src &&
srcArray.push(item.src); configObject?.dst &&
dstArray.push(item.dst); typeof configObject.src === "string" &&
} typeof configObject.dst === "string"
}); ) {
srcArray = configObject.src.split(",");
if (srcArray.length && dstArray.length) { dstArray = configObject.dst.split(",");
process.argv.push("--src", srcArray.join(",")); } else if (
process.argv.push("--dst", dstArray.join(",")); configObject?.src &&
} configObject?.dst &&
typeof configObject.src === "object" &&
typeof configObject.dst === "object" &&
Array.isArray(configObject.src) &&
Array.isArray(configObject.dst)
) {
srcArray = configObject.src;
dstArray = configObject.dst;
} else if (
configObject?.srcDst &&
Array.isArray(configObject.srcDst) &&
configObject.srcDst.length > 0
) {
const srcDstArray = configObject.srcDst;
srcDstArray.forEach((item) => {
if (
item?.src &&
item?.dst &&
typeof item.src === "string" &&
typeof item.dst === "string"
) {
srcArray.push(item.src);
dstArray.push(item.dst);
}
});
} else {
console.log(
"- \x1b[31mERROR:\x1b[0m Your config file has some errors. Please check your config file"
);
process.exit();
}
} catch (error: any) {
console.log(
"- \x1b[31mERROR:\x1b[0m Your config file has some errors. ERROR =>",
error.message
);
process.exit();
}
} else {
if (
process.argv.indexOf("--src") >= 0 &&
process.argv.indexOf("--dst") >= 0
) {
try {
srcArray =
process.argv[process.argv.indexOf("--src") + 1].split(",");
dstArray =
process.argv[process.argv.indexOf("--dst") + 1].split(",");
} catch (error) {}
} else {
console.log(
"- \x1b[31mERROR:\x1b[0m Missing source or destination file"
);
process.exit();
} }
} catch (error: any) {
console.log("ERROR in your config file =>", error.message);
process.exit();
} }
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
return {
sourceFile: srcArray.join(","),
destinationFile: dstArray.join(","),
};
};
const { sourceFile, destinationFile } = grabSrcDisStrings();
if (sourceFile && destinationFile) {
process.argv.push("--src", sourceFile, "--dst", destinationFile);
} }
const sourceFile = process.argv.indexOf("--src") >= 0 ? process.argv[process.argv.indexOf("--src") + 1] : null; //////////////////////////////////////////////////////////////////////////////
const destinationFile = process.argv.indexOf("--dst") >= 0 ? process.argv[process.argv.indexOf("--dst") + 1] : null; //////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/** ****************************************************************************** */ console.log("- \x1b[35mStart:\x1b[0m Running Less compiler ...");
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
console.log("\x1b[44mRunning Less compiler\x1b[0m ...");
if (!sourceFile || !destinationFile) { if (!sourceFile || !destinationFile) {
console.log("\x1b[33mERROR:\x1b[0m => Missing source or destination file"); console.log(
"- \x1b[31mERROR:\x1b[0m => Missing source or destination file"
);
process.exit(); process.exit();
} }
const sourceFiles = sourceFile.split(","); //////////////////////////////////////////////////////////////////////////////
const dstFiles = destinationFile.split(","); //////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/** /**
* Loop through source files and destination files and run the compile function * Loop through source files and destination files and run the compile function
*/ */
for (let i = 0; i < sourceFiles.length; i++) { function traverseFiles(src: string, dst: string) {
const srcFolder = sourceFiles[i]; const sourceFiles = src.split(",");
const dstFile = dstFiles[i]; const dstFiles = dst.split(",");
if (srcFolder?.match(/\.[^\/]+$/) && !srcFolder?.match(/\.less$/)) { for (let i = 0; i < sourceFiles.length; i++) {
console.log("\x1b[33mERROR:\x1b[0m Source must be a folder or a .less file"); const srcFolder = sourceFiles[i];
process.exit(); const dstFile = dstFiles[i];
}
compile(srcFolder, dstFile, null); if (
srcFolder?.match(/\/[^\/]+\.[^\/]+$/) &&
!srcFolder?.match(/\.less$/)
) {
console.log(
"- \x1b[31mERROR:\x1b[0m Source must be a folder or a .less file"
);
process.exit();
}
if (!fs.existsSync(srcFolder)) {
if (srcFolder?.match(/\.less$/)) {
fs.mkdirSync(srcFolder.replace(/\/[^\/]+\.less$/, ""), {
recursive: true,
});
fs.writeFileSync(srcFolder, "", "utf-8");
} else {
fs.mkdirSync(srcFolder.replace(/\/[^\/]+\.[^\/]+$/, ""), {
recursive: true,
});
fs.writeFileSync(
(srcFolder + "/main.less").replace(/\/\//g, ""),
"",
"utf-8"
);
}
} else if (
fs.existsSync(srcFolder) &&
fs.existsSync((srcFolder + "/main.less").replace(/\/\//g, ""))
) {
}
if (!fs.existsSync(dstFile)) {
if (dstFile?.match(/\.css$/)) {
fs.mkdirSync(dstFile.replace(/\/[^\/]+\.css$/, ""), {
recursive: true,
});
} else {
fs.mkdirSync(dstFile.replace(/\/[^\/]+\.[^\/]+$/, ""), {
recursive: true,
});
}
}
compile(srcFolder, dstFile, null);
try {
fs.readdirSync(srcFolder).forEach((file) => {
if (file?.match(/^\[.*\.less$/)) {
compile(srcFolder + "/" + file, dstFile, null);
}
});
} catch (error) {}
if (!fs.existsSync(srcFolder)) {
if (srcFolder?.match(/\.less$/)) { if (srcFolder?.match(/\.less$/)) {
fs.mkdirSync(srcFolder.replace(/\/[^\/]+\.less$/, ""), { recursive: true }); fs.watchFile(srcFolder, { interval: 500 }, (current, previous) => {
fs.writeFileSync(srcFolder, "", "utf-8"); const dstFilePathRoot = dstFile?.match(/\.css$/)
? dstFile
: dstFile + "/" + "_main.css";
try {
const currentProcessArgsSrc =
process.argv[process.argv.indexOf("--src") + 1];
const activeSourceFiles = currentProcessArgsSrc.split(",");
if (activeSourceFiles.includes(srcFolder)) {
compile(srcFolder, dstFilePathRoot, null);
} else {
fs.unwatchFile(srcFolder);
}
} catch (error: any) {
console.log(
"- \x1b[31mERROR:\x1b[0m Please check your config file =>",
error.message
);
}
});
} else if (!srcFolder?.match(/\.[^\/]+$/)) {
fs.watch(
srcFolder,
{
recursive: process.platform?.match(/win32/i)
? true
: undefined,
},
(evtType, fileName) => {
if (!evtType?.match(/change/i)) {
return;
}
if (!fileName) return;
const srcFilePathRoot = srcFolder + "/main.less";
try {
const currentProcessArgsSrc =
process.argv[process.argv.indexOf("--src") + 1];
const activeSourceFiles =
currentProcessArgsSrc.split(",");
if (fileName?.match(/^\[/)) {
compile(
srcFolder + "/" + fileName,
dstFile,
evtType
);
} else if (
fileName?.match(/^\(/) ||
activeSourceFiles.includes(srcFilePathRoot)
) {
return;
} else {
compile(srcFilePathRoot, dstFile, evtType);
}
} catch (error: any) {
console.log(
"- \x1b[31mERROR:\x1b[0m Please check your config file =>",
error.message
);
}
}
);
} else { } else {
fs.mkdirSync(srcFolder.replace(/\/[^\/]+\.[^\/]+$/, ""), { recursive: true }); console.log(
"- \x1b[31mERROR:\x1b[0m Source must be a folder or a .less file"
);
process.exit();
} }
} }
if (!fs.existsSync(dstFile)) {
if (dstFile?.match(/\.css$/)) {
fs.mkdirSync(dstFile.replace(/\/[^\/]+\.css$/, ""), { recursive: true });
fs.writeFileSync(dstFile, "", "utf-8");
} else {
fs.mkdirSync(dstFile.replace(/\/[^\/]+\.[^\/]+$/, ""), { recursive: true });
fs.writeFileSync((dstFile + "/_main.css").replace(/\/\//g, ""), "", "utf-8");
}
}
fs.watch(srcFolder, { recursive: true }, (evtType, fileName) => {
if (!fileName) return;
const filePathRoot = srcFolder?.match(/\.less$/) ? srcFolder : srcFolder + "/" + fileName;
compile(filePathRoot, dstFile, evtType);
});
} }
traverseFiles(sourceFile, destinationFile);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/** /**
* Compile less file to css function * Compile less file to css function
* @param fileName - less file path or folder path * @param fileName - less file path or folder path
@ -115,38 +283,94 @@ for (let i = 0; i < sourceFiles.length; i++) {
* @returns * @returns
*/ */
function compile(fileName: string, dst: string, evtType: string | null) { function compile(fileName: string, dst: string, evtType: string | null) {
if (fileName?.match(/\(/) || (fileName.match(/\..{2,4}$/) && !fileName?.match(/\.less$/i))) { if (
fileName?.match(/\(/) ||
(fileName.match(/\.[\/]$/) && !fileName?.match(/\.less$/i))
) {
return; return;
} }
let finalSrcPath = fileName?.match(/\.less$/) ? fileName : `${fileName}/main.less`; let finalSrcPath = fileName?.match(/\.less$/)
let finalDstPath = dst; ? fileName
: `${fileName}/main.less`;
const distFolder = dst?.match(/\.css$/) ? null : dst?.replace(/\/+$/, "");
let finalDstPath = distFolder ? `${distFolder}/_main.css` : dst;
if (distFolder && !fs.existsSync(distFolder)) {
fs.mkdirSync(distFolder, { recursive: true });
}
if (fileName?.match(/\[/)) { if (fileName?.match(/\[/)) {
const paths = fileName.split("/"); const paths = fileName.split("/");
const targetPathFull = paths[paths.length - 1]; const targetPathFull = paths[paths.length - 1];
const targetPath = targetPathFull.replace(/\[|\]/g, "").replace(/\.less/, ""); const targetPath = targetPathFull
.replace(/\[|\]/g, "")
.replace(/\.less/, "");
const destinationFileParentFolder = dst.replace(/\/[^\/]+\.css$/, ""); const destinationFileParentFolder = dst.replace(/\/[^\/]+\.css$/, "");
const targetDstFilePath = `${destinationFileParentFolder}/${targetPath}.css`; const targetDstFilePath = `${destinationFileParentFolder}/${targetPath}.css`;
finalSrcPath = `${fileName}/${targetPathFull}`; finalSrcPath = fileName;
finalDstPath = targetDstFilePath; finalDstPath = targetDstFilePath;
} }
exec(`lessc ${finalSrcPath} ${finalDstPath?.match(/\.css$/) ? finalDstPath : finalDstPath.replace(/\/$/, "") + "/_main.css"}`, (error, stdout, stderr) => { const executionCmd = `npx lessc ${finalSrcPath} ${finalDstPath}`;
exec(executionCmd, (error, stdout, stderr) => {
/** @type {Error} */ /** @type {Error} */
if (error) { if (error) {
console.log("ERROR =>", error.message); console.log(
"- \x1b[33mWarn:\x1b[0m Compilation didn't run successfully. ERROR =>",
error.message
);
if (!evtType?.match(/change/i) && fileName && fileName.match(/\[/)) { if (
!evtType?.match(/change/i) &&
fileName &&
fileName.match(/\[/)
) {
fs.unlinkSync(finalDstPath); fs.unlinkSync(finalDstPath);
} }
return; return;
} }
console.log("Less Compilation \x1b[32msuccessful\x1b[0m!"); console.log("- \x1b[32mCompiled:\x1b[0m Less Compilation Successful!");
}); });
} }
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/**
* watch for changes to the config file
*/
if (fs.existsSync("./lesscw.config.json")) {
fs.watchFile(
"./lesscw.config.json",
{ interval: 500 },
(evtType, fileName) => {
console.log("- \x1b[34mInfo:\x1b[0m Restarting process...");
const newSrcDistStrings = grabSrcDisStrings();
if (
newSrcDistStrings.destinationFile &&
newSrcDistStrings.sourceFile
) {
process.argv.push(
"--src",
newSrcDistStrings.sourceFile,
"--dst",
newSrcDistStrings.destinationFile
);
traverseFiles(
newSrcDistStrings.sourceFile,
newSrcDistStrings.destinationFile
);
}
}
);
}

View File

@ -1,13 +1,21 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es2016", "target": "ES2015",
"module": "commonjs", "module": "commonjs",
"rootDir": "./src", "maxNodeModuleJsDepth": 10,
"outDir": "./dist",
"removeComments": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,
"skipLibCheck": true "skipLibCheck": true,
} "lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"incremental": true,
"resolveJsonModule": true,
"jsx": "preserve",
"moduleResolution": "node",
"declaration": true,
"outDir": "dist"
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist"]
} }