docs: [standards] Blade + React(JSX) 혼용 정책 문서 추가
- 이중 중괄호 충돌 방지 규칙, 허용/금지 패턴, 체크리스트 포함 - INDEX.md에 등록
This commit is contained in:
2
INDEX.md
2
INDEX.md
@@ -17,6 +17,7 @@
|
||||
| 품질 검증 | `dev/standards/quality-checklist.md` | 코드 품질 체크리스트 |
|
||||
| Swagger | `dev/guides/swagger-guide.md` | API 문서 작성법 |
|
||||
| 이메일 정책 | `dev/standards/email-policy.md` | 멀티테넌시 이메일 발송 아키텍처 |
|
||||
| Blade+React | `dev/standards/blade-react-policy.md` | Blade JSX 이중 중괄호 충돌 방지 |
|
||||
| 이메일 연동 | `dev/guides/tenant-email-integration-guide.md` | 테넌트 메일 연동, SMTP 프리셋, MNG 관리 |
|
||||
| 품목관리 | `rules/item-policy.md` | 품목 정책 |
|
||||
| 단가관리 | `rules/pricing-policy.md` | 원가/판매가, 리비전 |
|
||||
@@ -113,6 +114,7 @@ DB 도메인별:
|
||||
| [options-column-policy.md](dev/standards/options-column-policy.md) | JSON options 컬럼 정책 |
|
||||
| [pdf-font-policy.md](dev/standards/pdf-font-policy.md) | PDF 생성 시 폰트 정책 (DomPDF) |
|
||||
| [email-policy.md](dev/standards/email-policy.md) | 멀티테넌시 이메일 발송 정책 |
|
||||
| [blade-react-policy.md](dev/standards/blade-react-policy.md) | Blade + React(JSX) 혼용 시 이중 중괄호 충돌 방지 정책 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
183
dev/standards/blade-react-policy.md
Normal file
183
dev/standards/blade-react-policy.md
Normal file
@@ -0,0 +1,183 @@
|
||||
# Blade + React(JSX) 혼용 정책
|
||||
|
||||
> **작성일**: 2026-03-12
|
||||
> **상태**: 설계 확정
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
### 1.1 목적
|
||||
|
||||
MNG 프로젝트에서 Blade 템플릿 안에 React(JSX) 코드를 직접 작성할 때 발생하는 문법 충돌을 방지한다.
|
||||
|
||||
### 1.2 배경
|
||||
|
||||
MNG는 Blade + HTMX 기반이지만, 일부 복잡한 UI(모달, 인터랙티브 폼)에는 React 컴포넌트를 Babel 브라우저 트랜스파일링 방식으로 사용한다. React JSX 코드가 `@push('scripts')` 블록 안에 직접 작성되며, Blade 엔진이 이를 먼저 처리하기 때문에 문법 충돌이 발생할 수 있다.
|
||||
|
||||
### 1.3 핵심 원칙
|
||||
|
||||
Blade 엔진은 `@verbatim` 블록 외부의 모든 이중 중괄호(`{{ }}`)를 PHP echo 구문으로 변환한다. JSX의 inline style 문법 `style={{ key: 'value' }}`는 Blade의 이중 중괄호와 동일한 패턴이므로 **PHP ParseError**를 유발한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 문제 상세
|
||||
|
||||
### 2.1 충돌 원인
|
||||
|
||||
Blade 컴파일 과정:
|
||||
|
||||
```
|
||||
Blade 소스 → 컴파일된 PHP
|
||||
style={{ tableLayout: 'fixed' }} → style=<?php echo e( tableLayout: 'fixed' ); ?>
|
||||
```
|
||||
|
||||
`{{ }}` 안의 내용이 PHP 코드로 해석되어 **`Unclosed '(' does not match '}'`** 등의 ParseError 발생.
|
||||
|
||||
### 2.2 영향 범위
|
||||
|
||||
`@verbatim`으로 감싸지 않은 Blade 파일 내 모든 JavaScript/JSX 코드에 해당한다.
|
||||
|
||||
| 패턴 | 위치 | 영향 |
|
||||
|------|------|------|
|
||||
| `style={{ key: 'value' }}` | JSX inline style | 🔴 ParseError |
|
||||
| `{{ }}` 텍스트가 포함된 JS 주석 | `// 주석에 {{ }} 포함` | 🔴 ParseError |
|
||||
| `${{ variable }}` | 템플릿 리터럴 | 🔴 ParseError |
|
||||
| `className="..."` | JSX className | ✅ 정상 (이중 중괄호 없음) |
|
||||
| `` `${variable}` `` | JS 템플릿 리터럴 | ✅ 정상 (단일 중괄호) |
|
||||
| `{ key: value }` | JS 객체 리터럴 | ✅ 정상 (단일 중괄호) |
|
||||
|
||||
### 2.3 실제 사고 사례
|
||||
|
||||
**2026-03-12**: `barobill/ecard/index.blade.php`에서 테이블 레이아웃 수정 시 `style={{ tableLayout: 'fixed' }}` 추가 → 운영서버 500 에러 발생. 주석의 `{{ }}` 텍스트도 동일 에러 유발.
|
||||
|
||||
---
|
||||
|
||||
## 3. 필수 규칙
|
||||
|
||||
### R1. `@verbatim` 사용 여부 확인
|
||||
|
||||
React/JSX 코드를 포함하는 Blade 파일을 수정하기 전에, 해당 코드 블록이 `@verbatim` ~ `@endverbatim`으로 감싸져 있는지 반드시 확인한다.
|
||||
|
||||
```bash
|
||||
# 확인 방법
|
||||
grep -n '@verbatim\|@endverbatim' resources/views/파일.blade.php
|
||||
```
|
||||
|
||||
### R2. `@verbatim` 블록 내부 (안전)
|
||||
|
||||
`@verbatim` 안에서는 Blade가 이중 중괄호를 처리하지 않으므로 JSX 문법을 자유롭게 사용할 수 있다.
|
||||
|
||||
```php
|
||||
@push('scripts')
|
||||
<script>
|
||||
const API = {
|
||||
store: '{{ route("some.route") }}', // Blade 처리 필요 → @verbatim 밖
|
||||
};
|
||||
</script>
|
||||
|
||||
@verbatim
|
||||
<script type="text/babel">
|
||||
// 여기서는 JSX 자유 사용 가능
|
||||
<table style={{ tableLayout: 'fixed' }}>
|
||||
<col style={{ width: '20%' }} />
|
||||
</table>
|
||||
</script>
|
||||
@endverbatim
|
||||
@endpush
|
||||
```
|
||||
|
||||
### R3. `@verbatim` 없는 블록 (주의 필요)
|
||||
|
||||
`@verbatim`이 없는 파일에서는 이중 중괄호를 절대 사용하지 않는다.
|
||||
|
||||
#### 금지 패턴
|
||||
|
||||
```
|
||||
❌ style={{ tableLayout: 'fixed' }}
|
||||
❌ style={{ width: '20%' }}
|
||||
❌ // 이 주석에 {{ }} 가 있으면 안됨
|
||||
❌ const obj = {{ key: 'value' }}
|
||||
```
|
||||
|
||||
#### 허용 패턴: 스타일 객체 변수 분리
|
||||
|
||||
```javascript
|
||||
// 스타일 객체를 변수로 선언
|
||||
const tableFixedStyle = { tableLayout: 'fixed' };
|
||||
const colStyles = [
|
||||
{ width: '10%' }, { width: '22%' }, { width: '28%' },
|
||||
{ width: '17%' }, { width: '17%' }, { width: '6%' }
|
||||
];
|
||||
|
||||
// 단일 중괄호로 참조 (Blade 충돌 없음)
|
||||
<table style={tableFixedStyle}>
|
||||
<colgroup>
|
||||
<col style={colStyles[0]} />
|
||||
<col style={colStyles[1]} />
|
||||
</colgroup>
|
||||
</table>
|
||||
```
|
||||
|
||||
### R4. JS 주석에도 이중 중괄호 금지
|
||||
|
||||
Blade는 주석 내부의 이중 중괄호도 처리한다. 주석에서도 `{{ }}`를 사용하지 않는다.
|
||||
|
||||
```
|
||||
❌ // Blade {{ }} 충돌 방지
|
||||
✅ // Blade 이중중괄호 충돌 방지
|
||||
```
|
||||
|
||||
### R5. `{{ route() }}` 등 Blade 디렉티브 분리
|
||||
|
||||
`@verbatim` 없이 Blade와 JSX를 혼용할 경우, Blade 디렉티브(`{{ route() }}`, `{{ csrf_token() }}` 등)는 JSX 코드와 분리하여 스크립트 상단에 배치한다.
|
||||
|
||||
```php
|
||||
@push('scripts')
|
||||
<script>
|
||||
// Blade 처리 영역 — 여기서만 {{ }} 사용
|
||||
const API = {
|
||||
cards: '{{ route("barobill.ecard.cards") }}',
|
||||
store: '{{ route("finance.journal-entries.store") }}',
|
||||
};
|
||||
</script>
|
||||
<script type="text/babel">
|
||||
// React/JSX 영역 — {{ }} 사용 금지
|
||||
// API 상수는 위 스크립트에서 선언된 것을 참조
|
||||
</script>
|
||||
@endpush
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 현재 파일 현황
|
||||
|
||||
| 파일 | `@verbatim` | 주의 수준 |
|
||||
|------|:-----------:|:---------:|
|
||||
| `finance/journal-entries.blade.php` | ✅ 사용 | 🟢 안전 |
|
||||
| `barobill/ecard/index.blade.php` | ❌ 미사용 | 🔴 주의 필요 |
|
||||
|
||||
> 새로운 Blade + React 파일 작성 시 `@verbatim` 사용을 권장한다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 체크리스트
|
||||
|
||||
Blade 파일에서 React/JSX 코드를 수정할 때:
|
||||
|
||||
- [ ] `@verbatim` 사용 여부 확인 (`grep -n @verbatim 파일명`)
|
||||
- [ ] `@verbatim` 없는 파일에서 `style={{ }}` 미사용 확인
|
||||
- [ ] JS 주석에 이중 중괄호 미포함 확인
|
||||
- [ ] Blade 디렉티브(`{{ route() }}` 등)와 JSX 코드 분리 확인
|
||||
- [ ] 인라인 스타일은 JS 변수로 선언 후 단일 중괄호 참조
|
||||
|
||||
---
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [MNG 구조](../../system/mng-structure.md) — MNG Blade + React 아키텍처
|
||||
- [Tailwind CSS 레이아웃 규칙](../../../mng/CLAUDE.md) — 반응형 클래스 대신 inline style 사용 정책
|
||||
|
||||
---
|
||||
|
||||
**최종 업데이트**: 2026-03-12
|
||||
Reference in New Issue
Block a user