const fs = require('fs'); const babel = require('@babel/core'); /** * @author : 최정우 * @since : 2022.10.02 * @dscription : JSX파일을 JS파일로 Build 해주는 모듈 입니다. */ const JsxToJsBuild = (function () { //jsx내용을 js내용으로 바꾼 캐시 저장소 //저장양식 -> {jsx 파일 경로: {jsxContent: jsx 내용, jsContent: js 내용, mtime: 파일수정일자}} const cache = {}; /** * @author : 최정우 * @since : 2022.10.02 * @dscription : JSX파일을 JS파일로 Build하는 기능 * @return : Promise, 빌드 성공시 - js내용(text), jsx내용(text) / 빌드 실패시 - error 제공 */ function build(fileFullPath) { const building = new Promise(function (resolve, reject) { //jsx File안에 내용 읽어오기 fs.readFile(fileFullPath, { encoding: 'utf8' }, (error, jsxConent) => { if (!error) { try { // ★★★ Babel을 활용하여 jsx문법을 js문법으로 변경(es6 -> es5 + presets: jsx -> js) ★★★ let jsContent = babel.transform(jsxConent, { "sourceType": "module", presets: ['@babel/preset-react'] }).code; resolve(jsContent, jsxConent);//빌드 성공 } catch (parserError) { reject(parserError);//빌드 실패(jsx to js 실패) - error 제공 } } else { reject(error);//빌드 실패(파일 읽기 실패) - error 제공 } }); }) return building; } /** * @author : 최정우 * @since : 2022.10.03 * @dscription : JSX파일을 JS파일로 Build하는 기능 (+ 캐싱) * @return : Promise, 빌드 성공시 - js내용(text), jsx내용(text) / 빌드 실패시 - error 제공 */ function buildCache(fileFullPath) { /* //[Debug Test] console.log('--------------------------------------'); */ const building = new Promise(function (resolve, reject) { //빌드 필요 여부 let isNeedBuild = true; //현재 jsx File MetaData let currentFileStats; try { //현재 jsx File MetaData 가지고오기 currentFileStats = fs.statSync(fileFullPath); //캐시정보 리턴 여부 (캐시 처리된 파일정보가 있고, 파일 수정이 안되었을때 -> 캐시정보 리턴) let isReturnCache = (cache[fileFullPath] != undefined && cache[fileFullPath].mtimeMs == currentFileStats.mtimeMs); /* //[Debug Test] let tempMtime = cache[fileFullPath] == undefined ? 'undefined' : cache[fileFullPath].mtimeMs; console.log('캐시정보 mtime : ', tempMtime, typeof tempMtime); console.log('현재파일 mtime : ', currentFileStats.mtimeMs, typeof currentFileStats.mtimeMs); console.log('buildCache - isReturnCache 정보 ', cache[fileFullPath] != undefined, tempMtime == currentFileStats.mtimeMs); console.log('buildCache - fileFullPath : ', fileFullPath, '캐시저장소 size : ', Object.keys(cache).length, '캐시정보 존재여부 : ', !!cache[fileFullPath], '캐시정보 리턴 여부 : ', isReturnCache); */ //1. 캐시정보 리턴 여부가 True(isReturnCache:true)이면 -> 빌드 없음(isNeedBuild:false) //2. 캐시정보 리턴 여부가 False(isReturnCache:false)이면 -> 빌드 필요(isNeedBuild:true) isNeedBuild = !isReturnCache; } catch (error) { reject(error);//빌드 실패(파일 읽기 실패) - error 제공 } if (isNeedBuild == true) { /* //[Debug Test] console.log('buildCache - 캐싱 처리진행 : ', fileFullPath); */ //jsx File안에 내용 읽어오기 fs.readFile(fileFullPath, { encoding: 'utf8' }, (error, jsxConent) => { if (!error) { try { // ★★★ Babel을 활용하여 jsx문법을 js문법으로 변경(es6 -> es5 + presets: jsx -> js) ★★★ let jsContent = babel.transform(jsxConent, { "sourceType": "module", presets: ['@babel/preset-react'] }).code; //캐시 처리 cache[fileFullPath] = { 'jsContent': jsContent, 'jsxConent': jsxConent, 'mtimeMs': currentFileStats.mtimeMs }; resolve(jsContent, jsxConent);//빌드 성공 } catch (parserError) { reject(parserError);//빌드 실패(jsx to js 실패) - error 제공 } } else { reject(error);//빌드 실패(파일 읽기 실패) - error 제공 } }); } else { /* //[Debug Test] console.log('buildCache - 캐시 정보반환 : ', fileFullPath); */ resolve(cache[fileFullPath].jsContent, cache[fileFullPath].jsxConent);//캐시 정보 반환 } }) return building; } return { build: build, buildCache: buildCache } })(); //Module Export module.exports = JsxToJsBuild;