핵심 기능 구현
1. Babel 변환 과정 3단계
Parsing → Transformation → Generation 각 단계를 독립적으로 실행하고 추적할 수 있도록 분리했습니다.
src/utils/bable.js
export const processBabelSteps = (sourceCode) => {
try {
// 1. Parsing: 코드 → AST
const { ast: initialAst, formatted: formattedAst } = parseSourceCodeToAst(sourceCode);
// 2. Transformation: 각 플러그인 적용 과정 기록
const detectedPlugins = BABEL_PLUGINS.filter((plugin) => plugin.detect(sourceCode));
const transformSteps = [];
let currentCode = sourceCode;
let currentAst = initialAst;
for (const plugin of detectedPlugins) {
// 이전 단계의 결과를 기반으로 현재 플러그인 적용
const { ast: transformedAst, code: transformedCode } = transformAstUsingPlugins(currentAst, plugin.id);
if (!transformedAst) continue;
transformSteps.push({
plugin: { id: plugin.id, name: plugin.name, description: plugin.description },
before: { code: currentCode, ast: currentAst },
after: { code: transformedCode, ast: transformedAst }
});
currentCode = transformedCode;
currentAst = transformedAst;
}
// 3. Generation: AST → 코드
const { code: finalGeneratedCode } = generateAstToSourceCode(currentAst);
return {
parsing: { sourceCode, ast: initialAst, formattedAst },
transformation: { steps: transformSteps, plugins: detectedPlugins },
generation: { ast: currentAst, code: finalGeneratedCode },
result: { originalCode: sourceCode, transformedCode: finalGeneratedCode }
};
} catch (error) {
console.error("Babel processing error:", error);
return {
parsing: { sourceCode, ast: null, formattedAst: null },
transformation: { steps: [], plugins: [] },
generation: { ast: null, code: null },
result: { originalCode: sourceCode, transformedCode: null }
};
}
};이렇게 분리함으로써 각 플러그인이 코드를 어떻게 변환하는지 단계별로 추적 가능하게 되었습니다.
2. 플러그인 자동 감지 시스템
코드를 분석하여 필요한 Babel 플러그인을 자동으로 감지하고 적용하는 시스템을 구현했습니다.
src/constants/transform-process-page-babel-plugins.js
export const BABEL_PLUGINS = [
// 1. 클래스 관련 변환을 가장 먼저
{
id: "proposal-class-properties",
name: "Class Properties",
detect: (code) => /class.*{[^}]*=/.test(code),
sample: "class A { x = 1 }",
description: "클래스 속성 문법 변환"
},
// 2. 기본 문법 변환
{
id: "transform-destructuring",
name: "Destructuring",
detect: (code) => /\{[^}]+\}\s*=/.test(code) || /\[[^\]]+\]\s*=/.test(code),
sample: "const { x, y } = obj",
description: "구조 분해 할당 변환"
}
// ...
];src/utils/bable.js
// 사용 예시
const detectedPlugins = BABEL_PLUGINS.filter(plugin => plugin.detect(sourceCode));3. Transformation 단계별 추적 UI
가장 핵심적인 부분은 각 플러그인이 적용되는 과정을 시각화한 것입니다.
src/components/layout/steps/TransformationStep.jsx
const TransformationStep = ({ steps }) => {
const [currentStep, setCurrentStep] = useState(0);
// 핵심: 변환 전후 코드를 나란히 표시
return (
<>
<div className="grid grid-cols-2 gap-6">
<CodePanel
title={currentStep === 0 ? "Current" : `Current (After ${steps[currentStep - 1]?.plugin?.name})`}
data={step.before}
side="right"
/>
<CodePanel
title={`After ${step.plugin?.name}`}
data={step.after}
side="left"
/>
</div>
{/* ... */}
</>
);
};이를 통해 사용자는 Arrow Functions 플러그인이 화살표 함수 () => {}를 일반 함수 function() {}로 바꾸는 과정을 직접 확인할 수 있고, Template Literals 플러그인이 템플릿 문자열을 일반 문자열 연결로 변환하는 과정도 볼 수 있습니다. 무엇보다 각 변환이 순차적으로 적용되는 전체 과정을 단계별로 추적할 수 있게 되었습니다.
4. 실시간 변환 최적화
사용자가 타이핑할 때마다 변환하면 성능 문제가 발생하기 때문에 500ms 디바운싱을 적용했습니다.
src/pages/PlaygroundPage.jsx
// 500ms 디바운싱으로 성능 최적화
const debouncedTransform = useCallback(
debounce((code) => handleTransform(code), 500),
[handleTransform]
);Last updated on