728x90

안녕하세요! 오늘은 Node.js를 활용해 일반 JavaScript (JS)와 TypeScript (TS) 파일을 파싱하는 다양한 방법을 알아보겠습니다.
파일 파싱은 코드 분석, 자동화 도구 제작, 또는 빌드 프로세스에서 자주 사용되는데요.
이 글에서는 실용적인 예제와 함께 접근 방법을 소개하겠습니다. 그럼 시작해볼까요?
파일 파싱은 코드 분석, 자동화 도구 제작, 또는 빌드 프로세스에서 자주 사용되는데요.
이 글에서는 실용적인 예제와 함께 접근 방법을 소개하겠습니다. 그럼 시작해볼까요?
1. 기본 파일 읽기와 간단한 파싱
가장 간단한 방법은 Node.js의 내장 모듈 fs를 사용해 파일을 읽고 문자열로 다루는 것입니다.
const fs = require('fs');
// JS 파일 읽기
const jsCode = fs.readFileSync('sample.js', 'utf8');
console.log('JS 파일 내용:', jsCode);
// TS 파일 읽기
const tsCode = fs.readFileSync('sample.ts', 'utf8');
console.log('TS 파일 내용:', tsCode);
이 방식은 파일 내용을 단순히 문자열로 가져오는 단계입니다. 여기서 더 나아가 파싱하려면 추가 도구가 필요합니다.
2. acorn으로 JS 파일을 AST로 파싱
acorn은 JavaScript 파일을 Abstract Syntax Tree (AST)로 변환해주는 경량 파서입니다.
const fs = require('fs');
const acorn = require('acorn');
const jsCode = fs.readFileSync('sample.js', 'utf8');
const ast = acorn.parse(jsCode, { ecmaVersion: 2020 });
console.log('AST:', JSON.stringify(ast, null, 2));
설치: npm install acorn
사용 예: 함수 정의, 변수 선언 등을 분석할 때 유용합니다.
3. typescript 모듈로 TS 파일 파싱
TypeScript 파일은 공식 typescript 패키지를 사용해 파싱할 수 있습니다.
const fs = require('fs');
const ts = require('typescript');
const tsCode = fs.readFileSync('sample.ts', 'utf8');
const sourceFile = ts.createSourceFile(
'sample.ts',
tsCode,
ts.ScriptTarget.Latest
);
console.log('TS AST:', sourceFile);
설치: npm install typescript
특징: TS의 타입 정보와 함께 AST를 제공하며, 복잡한 TS 코드를 분석할 때 적합합니다.
특징: TS의 타입 정보와 함께 AST를 제공하며, 복잡한 TS 코드를 분석할 때 적합합니다.
4. esprima로 JS 코드 파싱
esprima는 또 다른 인기 있는 JS 파서로, 상세한 AST를 생성합니다.
const fs = require('fs');
const esprima = require('esprima');
const jsCode = fs.readFileSync('sample.js', 'utf8');
const ast = esprima.parseScript(jsCode);
console.log('AST:', JSON.stringify(ast, null, 2));
설치: npm install esprima
장점: 간단한 인터페이스와 상세한 파싱 결과.
장점: 간단한 인터페이스와 상세한 파싱 결과.
5. @babel/parser로 JS/TS 모두 지원
Babel의 파서는 JS와 TS를 모두 지원하며, 플러그인을 통해 확장 가능합니다.
const fs = require('fs');
const parser = require('@babel/parser');
const code = fs.readFileSync('sample.ts', 'utf8');
const ast = parser.parse(code, {
sourceType: 'module',
plugins: ['typescript'],
});
console.log('Babel AST:', JSON.stringify(ast, null, 2));
설치: npm install @babel/parser
특징: 모던 JS와 TS를 동시에 처리할 수 있어 범용성이 높습니다.
특징: 모던 JS와 TS를 동시에 처리할 수 있어 범용성이 높습니다.
6. 실전 예제: 함수 이름 추출하기
AST를 활용해 실제로 코드를 분석해보겠습니다.
const fs = require('fs');
const acorn = require('acorn');
const jsCode = fs.readFileSync('sample.js', 'utf8');
const ast = acorn.parse(jsCode, { ecmaVersion: 2020 });
function extractFunctionNames(node) {
if (node.type === 'FunctionDeclaration') {
console.log('함수 이름:', node.id.name);
}
for (const key in node) {
if (node[key] && typeof node[key] === 'object') {
extractFunctionNames(node[key]);
}
}
}
extractFunctionNames(ast);
sample.js:
function hello() {
console.log('Hello!');
}
function goodbye() {
console.log('Goodbye!');
}
출력:
함수 이름: hello
함수 이름: goodbye
728x90
728x90
7. TS에서 타입 정보 추출
TS 파일에서 타입 정보를 추출하려면 typescript 모듈을 활용합니다.
const fs = require('fs');
const ts = require('typescript');
const tsCode = fs.readFileSync('sample.ts', 'utf8');
const sourceFile = ts.createSourceFile(
'sample.ts',
tsCode,
ts.ScriptTarget.Latest
);
function extractTypes(node) {
if (node.kind === ts.SyntaxKind.TypeAliasDeclaration) {
console.log('타입 이름:', node.name.text);
}
ts.forEachChild(node, extractTypes);
}
extractTypes(sourceFile);
sample.ts:
type User = { name: string };
type ID = number;
출력:
타입 이름: User
타입 이름: ID
마무리
Node.js로 JS와 TS 파일을 파싱하는 방법은 용도에 따라 다양합니다. 간단한 문자열 분석부터 AST를 활용한 복잡한 코드 분석까지, 필요에 맞는 도구를 선택해 사용해보세요. acorn, esprima, @babel/parser, typescript 등은 모두 강력한 옵션이니 프로젝트 요구사항에 맞춰 골라보시길 추천드립니다.
AST가 뭐야?
AST는 Abstract Syntax Tree(추상 구문 트리)의 줄임말로, 프로그래밍 언어의 코드를 구조화된 트리 형태로 표현한 것을 의미합니다. 쉽게 말해, 사람이 작성한 소스 코드를 컴퓨터가 이해하고 분석할 수 있도록 변환한 데이터 구조라고 생각하면 됩니다.
AST의 개념
코드를 실행하거나 분석하려면 컴파일러나 인터프리터가 그 코드를 이해해야 합니다. 이때 소스 코드(예: JavaScript, TypeScript 등)를 바로 실행하지 않고, 먼저 파싱(Parsing) 과정을 거쳐 AST로 변환합니다. 이 트리는 코드의 문법적 구조를 계층적으로 나타내며, 세부 실행 내용(예: 변수 값 계산)보다는 구문의 구조에 초점을 맞춥니다.
예를 들어, 다음과 같은 JavaScript 코드가 있다고 해보죠:
function add(a, b) {
return a + b;
}
이 코드를 AST로 변환하면 대략 이런 구조가 됩니다:
- FunctionDeclaration
- name: "add"
- params:
- Identifier: "a"
- Identifier: "b"
- body:
- ReturnStatement
- expression:
- BinaryExpression
- operator: "+"
- left: Identifier "a"
- right: Identifier "b"
AST의 특징
-
추상화: 세세한 토큰(공백, 세미콜론 등)은 생략되고, 의미 있는 구조만 남습니다.
-
트리 구조: 노드와 가지로 연결된 계층적 형태로, 각 노드는 코드의 특정 요소(함수, 변수, 연산 등)를 나타냅니다.
-
언어 독립적: 대부분의 프로그래밍 언어에서 비슷한 방식으로 사용됩니다.
AST는 어디에 쓰이나요?
-
컴파일러/인터프리터: 코드를 기계어로 변환하거나 실행하기 전에 구조를 분석합니다.
-
코드 분석 도구: ESLint, Prettier 같은 도구가 AST를 사용해 코드 품질을 체크하거나 포맷을 조정합니다.
-
트랜스파일러: Babel처럼 JS 코드를 다른 버전으로 변환할 때 AST를 수정합니다.
-
자동화: 코드에서 특정 패턴(예: 함수 이름)을 찾아내거나 수정할 때 유용합니다.
간단한 예제
Node.js에서 acorn으로 AST를 만들어보면 감이 올 겁니다:
const acorn = require('acorn');
const code = "let x = 5 + 3;";
const ast = acorn.parse(code, { ecmaVersion: 2020 });
console.log(JSON.stringify(ast, null, 2));
출력 (간략화):
{
"type": "Program",
"body": [
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": { "type": "Identifier", "name": "x" },
"init": {
"type": "BinaryExpression",
"operator": "+",
"left": { "type": "Literal", "value": 5 },
"right": { "type": "Literal", "value": 3 }
}
}
],
"kind": "let"
}
]
}
이렇게 코드가 트리 형태로 분해되어, 각 요소를 쉽게 분석할 수 있습니다.
요약
AST는 소스 코드를 구조화된 트리로 바꾼 것으로, 코드의 뼈대를 분석하거나 조작할 때 핵심적인 역할을 합니다. 프로그래밍에서 "파싱"이나 "코드 변환" 같은 작업을 할 때 자주 만나게 되는 개념이니, 익숙해지면 다양한 도구를 활용하는 데 큰 도움이 될 거예요!
궁금한 점 더 있으면 언제든 물어보세요!
728x90
'Node.js 를 배워보자' 카테고리의 다른 글
Nuxt.js로 오라클 debug_log 테이블 실시간 모니터링 구현하기 (0) | 2025.03.17 |
---|---|
Node.js로 JavaScript 파일의 함수 호출 정보 파싱하기 (1) | 2025.03.02 |
Node.js 모듈 시스템의 심층 분석: cts, cjs, ts, mts, mjs 차이점 (0) | 2025.02.04 |
Node.js 개발의 필수 도구: Nodemon을 활용한 효율적인 개발 환경 구축 (0) | 2025.01.24 |
Node.js Express 환경에서 Swagger와 Redoc을 활용한 API 문서화 (0) | 2025.01.22 |