Gleam FFI 라이브러리 — Mendix Pluggable Widget API 바인딩. React는 redraw/redraw_dom, TEA 패턴은 lustre에 위임한다. Mendix API·위젯·마켓플레이스는 mendraw에 위임한다.
- 언어: Gleam (target: JavaScript)
- 의존성: gleam_stdlib, redraw, redraw_dom, lustre, mendraw
- Peer deps (위젯 프로젝트): react ^19, react-dom ^19, big.js ^6 (decimal 속성 사용 시)
Gleam 문법은 docs/gleam_language_tour.md 를 참조한다.
gleam build # 컴파일
gleam check # 타입 체크만
gleam run -m glendix/install # 의존성 설치 + 바인딩 생성
gleam run -m glendix/dev # 개발 서버 (HMR)
gleam run -m glendix/build # 프로덕션 빌드 (.mpk)
gleam run -m glendix/start # Mendix 테스트 프로젝트 연동
gleam run -m glendix/release # 릴리즈 빌드
gleam run -m glendix/lint # ESLint
gleam run -m glendix/lint_fix # ESLint 자동 수정
gleam run -m mendraw/marketplace # 마켓플레이스 위젯 다운로드변경 후 반드시 gleam build로 빌드 확인한다.
- 비즈니스 로직은
.gleam에 작성..mjs는 JS 런타임 접근 담당. 외부 JS 라이브러리 연동 등 필요한 경우 FFI 어댑터가 두꺼워질 수 있다. - Opaque type으로 JS 값을 감싼다. 내부 구조 직접 접근 금지.
undefined/null↔Option. FFI 경계에서to_option()/from_option()변환. Gleam에서undefined직접 사용 금지.- Gleam 튜플 = JS 배열.
#(a, b)↔[a, b](useState 반환값 등). - Gleam List ↔ JS Array. FFI 경계에서
toList()/.toArray()변환.
- 주석과 doc comment는 한국어로 작성
- 모듈별 단일 책임: 각
.gleam파일은 하나의 타입/도메인 담당 @external어노테이션: 상대 경로로.mjs파일 참조
// React (redraw) 사용
import redraw
import redraw/dom/html
import redraw/dom/attribute
import redraw/dom/events
// 위젯 진입점
import mendraw/mendix.{type JsProps}
import redraw.{type Element}
pub fn widget(props: JsProps) -> Element { ... }
// 조건부 CSS 클래스
mendix.cx([#("active", is_active), #("disabled", is_disabled)])
// 외부 JS 컴포넌트 (widget/binding)
import mendraw/interop
interop.component_el(comp, attrs, children)
// Lustre TEA 패턴
import glendix/lustre as gl
gl.use_tea(#(init_model, effect.none()), update, view)
gl.use_simple(init_model, update, view)
gl.embed(redraw_element) // lustre view 안에 redraw 삽입- FFI
.mjs에 비즈니스 로직 넣기 - Gleam에서 JS
undefined직접 사용 (Option변환 필수)
- 외부 React 컴포넌트:
gleam.toml [tools.glendix.bindings]→glendix/install→glendix/binding사용 - Pluggable .mpk 위젯:
gleam.toml [tools.mendraw.widgets.*](자동 다운로드 →build/widgets/캐시) →mendraw/widget.component("Name") - 위젯 prop 헬퍼:
mendraw/widget.prop(k, v)/widget.editable_prop(k, v, d, set)/widget.action_prop(k, fn) - Classic Dojo .mpk 위젯:
gleam.toml [tools.mendraw.widgets.*]→mendraw/classic.render(widget_id, props) install시 TOML 위젯 다운로드/캐시(mendraw) →binding_ffi.mjs(glendix),widget_ffi.mjs,classic_ffi.mjs,src/widgets/*.gleam자동 생성(mendraw)
editor_config.gleam은 Studio Pro의 Jint(.NET JS 엔진)에서 실행된다.
Gleam List 사용 금지 — WeakMap, Symbol.iterator 미지원. 복수 키는 콤마 구분 String.
gleam.toml의 [tools.glendix] pm = "pnpm" 오버라이드 우선. 없으면 lock 파일 기반: pnpm-lock.yaml → pnpm / bun.lockb·bun.lock → bun / 기본값 → npm
[tools.glendix]
pm = "pnpm" # PM 오버라이드 (pnpm/bun/npm)
[tools.glendix.bindings] # 외부 React 컴포넌트 바인딩
recharts = ["PieChart", "Cell", "Tooltip", "Pie"]
"@mui/material" = ["Button", "TextField"]
[tools.mendraw.widgets.Charts] # 위젯 자동 다운로드
version = "3.0.0"
# id = 106517 ← Content API 검색 후 자동 기록
# s3_id = "com/..." ← 다운로드 URL (있으면 인증 없이 직접 다운로드)install시[tools.mendraw.widgets.*]의 위젯을build/widgets/{name}/에 다운로드/캐시meta.toml의 version과 TOML version 불일치 시 재다운로드gleam clean→build/삭제 → 다음 install에서 재다운로드- marketplace TUI(
mendraw/marketplace) 다운로드 시 자동으로 gleam.toml에 위젯 항목 추가
Mendix 공식 문서(docs.mendix.com) 접근 불가. GitHub 소스 참조:
- API 문서:
github.com/mendix/docs→apidocs-mxsdk/apidocs/pluggable-widgets/ - 위젯 예제:
github.com/mendix/web-widgets→packages/pluggableWidgets/ - 빌드 도구:
github.com/mendix/widgets-tools
핵심 개념:
- 위젯 진입점:
fn(JsProps) -> Element ValueStatus:Available | Loading | Unavailable— 값 읽기 전 확인 필수EditableValue.setValue()값 변경 /ActionValue.execute()액션 실행ListValue: 페이징/정렬/필터 지원mendix/filters/builders→ Rollup external 처리 필요
- glendix_guide.md — 종합 사용 가이드
- README.md — 설치 및 빠른 시작