/**
* HTML(ejs) 컴파일러
*
* @Modification Information
* 수정일 : 수정자 : 수정내용
* --------------------------
* 2023.12.14 : Mabongpapa : 최초생성
*/
import type {IServer} from "../@types/gulpfile.d";
import path from "path";
import fs from "fs";
import glob from "fast-glob";
import {watch} from "gulp";
import timeStamp from "../util/getTimeStamp";
import getSrcDist from "../util/getSrcDist";
import request from "request";
import {crawler} from "./sitemap"; // dist 목록 가져오기
import * as Config from "../config"; // 해당 포트 및 폴더 변경 가능
import findPidFromPort from "../util/findPidFromPort";
import asyncRequest from "../util/asyncRequestPrettyHtml"; // URL to HTML
// 시작시 전체 컴파일용
export const compiler = async (options:{src:string,base:string,dist:string}) => {
const srcs = await glob(options.src);
const distPath = path.join(__dirname,path.relative(__dirname,"./"),options.dist);
for await (const srcPath_ of srcs){
const srcDist = getSrcDist(Object.assign(options,{src:srcPath_}));
await ejsCompileToHtml(srcDist,"HTML:Compiler");
};
};
// 감시자 적용
export const watcher = (options:{base:string,src:string,dist:string}):Promise => {
return new Promise(async (resolve,reject)=>{
watch(options.src,{usePolling:true}).on("change",async (path)=>{
const srcDist = getSrcDist(Object.assign(options,{src:path}));
await ejsCompileToHtml(srcDist,"HTML:Watcher");
}).on("ready",()=>{
console.log(`${timeStamp().task}[HTML:Watch] Ready`);
resolve();
});
});
};
// 1개씩 처리하는 함수(내부 코어용)
const ejsCompileToHtml = async (options:{src:string,dist:string},callerName?:string) => {
const isPage = (options.src.indexOf("/pages/") != -1); // 페이지 내 html(ejs) 여부
const htmlRaw = fs.readFileSync(options.src,{encoding:"utf8",flag:"r"}); // html(ejs) 원문
const distPath = options.dist.replace(".ejs",".html"); // 저징될 경로(파일명 포함) , .ejs 인경우, .html로 변환 됨.
let _htmlRaw = htmlRaw
.replace(/()(<\/include>)?/gi,"<%-include(`$4`,$9) %>") // 옵션이 포함된 인클루드 구문 변환
.replace(/()(<\/include>)?/gi,"<%-include(`$4`) %>") // 옵션이 없는 인클루드 구문 변환
.replace(/(include\(`)(.+)(.ejs)(`)/gi,"$1$2.html$4"); // ejs로 로드 했을경우, html파일로 변환
_htmlRaw = (!isPage) ? _htmlRaw.replace(/()[\n\d\D])*(-->)/gi,"") : _htmlRaw; // 페이지가 아니라면, PAGEDOC 삭제
fs.mkdirSync(path.dirname(distPath),{recursive:true}); // 저장할 폴더 생성
fs.writeFileSync(distPath,_htmlRaw,{encoding:"utf8"}); // 파일 저장
console.log(`${timeStamp().task}[${callerName}] ${options.src}`);
return;
}
// 시작시 전체 컴파일용
export const dist = (options:{src:string,base:string,dist:string}):Promise => {
return new Promise(async (resolve,reject) => {
const pageMap = await crawler(options);
// 개발서버 실행(기존에 실행되어 있다면 미동작)
let pid = await findPidFromPort(Config.devPort); // 서버실행 여부 확인
let isDevServerReady = !!pid; // 서버가 있다면 true , 없으면 false.
if(!isDevServerReady){ // 서버가 없었으면 실행 시킨다.
const server:IServer = await import("../servers/server");
await server.dev({root:options.base,port:Config.devPort});
};
for await (const page of pageMap){
const url = `http://localhost:${Config.devPort}${page.devUrl}`;
const htmlRaw = await asyncRequest(url);
const buildPath = Config.buildServerRoot+page.buildUrl;
fs.mkdirSync(path.dirname(buildPath),{recursive:true});
fs.writeFileSync(buildPath,htmlRaw,"utf8");
console.log(`${timeStamp().task}[html:dist] ${buildPath}`);
};
if(!isDevServerReady){
pid = await findPidFromPort(Config.devPort); // 서버실행 여부 확인
setTimeout(()=>{
console.log(`${timeStamp().task}[html:dist] process.kill , port ${Config.devPort}`);
process.kill(pid);
},2000);
};
resolve();
});
};