MendixWidgetGleam
Gleam 언어로 Mendix Pluggable Widget을 개발하는 프로젝트.
JSX를 사용하지 않고, Gleam 코드만으로 React 컴포넌트를 작성하여 Mendix Studio Pro에서 동작하는 위젯을 만든다. Gleam을 JavaScript로 컴파일하고, Gleam FFI로 React API를 직접 바인딩하는 방식이다.
왜 Gleam인가?
- 정적 타입 안전성 — Gleam의 강력한 타입 시스템으로 런타임 에러를 컴파일 타임에 방지
- 불변 데이터 — 예측 가능한 상태 관리
- JavaScript 타겟 지원 —
gleam build --target javascript로 ES 모듈 출력 - 범용 FFI 계층 —
react_ffi.mjs에 React 원시 함수,mendix_ffi.mjs에 Mendix 런타임 타입 접근자를 분리하고, Gleam 모듈 계층에서 타입 안전한 API 제공 - Mendix API 완전 바인딩 —
EditableValue,ActionValue,ListValue등 모든 Mendix Pluggable Widget API를 Gleam opaque type + FFI 접근자로 지원. 별도의 FFI 수정 없이 바로 사용 가능
아키텍처
src/
widget/ # Gleam 소스 코드
mendix_widget_gleam.gleam # 위젯 메인 모듈 (컴포넌트 로직)
react_ffi.mjs # React FFI 어댑터 (React 원시 함수)
mendix_ffi.mjs # Mendix FFI 어댑터 (Mendix 런타임 타입 접근)
react.gleam # 핵심 타입 + createElement + fragment/text/none
react/
prop.gleam # Props 빌더 (파이프라인 API)
hook.gleam # React Hooks (useState, useEffect 등)
event.gleam # 이벤트 타입 + 값 추출
html.gleam # HTML 태그 편의 함수 (순수 Gleam)
mendix.gleam # Mendix 핵심 타입 + Props 접근자
mendix/
editable_value.gleam # EditableValue (편집 가능한 값)
action.gleam # ActionValue (액션 실행)
dynamic_value.gleam # DynamicValue (동적 값)
list_value.gleam # ListValue + FilterCondition + SortInstruction
list_attribute.gleam # ListAttributeValue 등 리스트 연결 타입
selection.gleam # 단일/다중 선택
reference.gleam # ReferenceValue, ReferenceSetValue
file.gleam # FileValue, WebImage
icon.gleam # WebIcon (Glyph, Image, IconFont)
formatter.gleam # ValueFormatter (format, parse)
filter.gleam # Filter 조건 빌더
editor_config.gleam # Studio Pro 속성 패널 설정
scripts/ # 빌드/개발 스크립트 (gleam run -m으로 실행)
cmd.gleam + cmd_ffi.mjs # 셸 명령어 실행 유틸리티
install.gleam # npm 의존성 설치
build.gleam # 프로덕션 빌드
dev.gleam / start.gleam # 개발 서버 / Mendix 연동
release.gleam # 릴리즈 빌드
lint.gleam / lint_fix.gleam # ESLint
MendixWidgetGleam.js # 브릿지 (Gleam 출력 → Mendix 진입점)
MendixWidgetGleam.editorConfig.js # 브릿지 (editorConfig)
MendixWidgetGleam.xml # 위젯 속성 정의
package.xml # Mendix 패키지 매니페스트
빌드 파이프라인
Gleam 소스 (.gleam) + FFI 어댑터 (react_ffi.mjs, mendix_ffi.mjs)
↓ gleam run -m scripts/build (Gleam 컴파일 자동 수행)
ES 모듈 (.mjs) — build/dev/javascript/...
↓ 브릿지 JS가 import
↓ Rollup (pluggable-widgets-tools)
.mpk 위젯 패키지 — dist/
핵심 원리
Gleam 함수 fn(JsProps) -> ReactElement는 React 함수형 컴포넌트와 동일한 시그니처다. react_ffi.mjs는 React 원시 함수를, mendix_ffi.mjs는 Mendix 런타임 타입 접근자를 노출하는 얇은 래퍼이고, Gleam 모듈 계층이 타입 안전한 API를 제공한다.
// src/widget/mendix_widget_gleam.gleam
import widget/mendix
import widget/react.{type JsProps, type ReactElement}
import widget/react/html
import widget/react/prop
pub fn widget(props: JsProps) -> ReactElement {
let sample_text = mendix.get_string_prop(props, "sampleText")
html.div(prop.new() |> prop.class("widget-hello-world"), [
react.text("Hello " <> sample_text),
])
}
Mendix 복합 타입도 Gleam에서 타입 안전하게 사용할 수 있다:
import widget/mendix
import widget/mendix/editable_value
import widget/mendix/action
pub fn widget(props: JsProps) -> ReactElement {
// EditableValue 접근
let name_attr: EditableValue = mendix.get_prop_required(props, "name")
let display = editable_value.display_value(name_attr)
// ActionValue 실행
let on_save: Option(ActionValue) = mendix.get_prop(props, "onSave")
action.execute_action(on_save)
// ...
}
시작하기
사전 요구사항
- Gleam (v1.0+)
- Node.js (v16+)
- Mendix Studio Pro (위젯 테스트용)
설치
gleam run -m scripts/install # Gleam 의존성 자동 다운로드 + npm 의존성 설치
빌드
gleam run -m scripts/build # Gleam 컴파일 + 위젯 빌드 (.mpk 생성)
빌드 결과물은 dist/ 디렉토리에 .mpk 파일로 생성된다.
개발
gleam run -m scripts/dev # Gleam 컴파일 + 개발 서버 (HMR, port 3000)
gleam run -m scripts/start # Mendix 테스트 프로젝트와 연동 개발
명령어 모음
모든 명령어는 gleam으로 통일. gleam run -m은 Gleam 컴파일을 자동 수행한 뒤 스크립트를 실행한다.
| 명령어 | 설명 |
|---|---|
gleam run -m scripts/install | 의존성 설치 (Gleam + npm) |
gleam run -m scripts/build | 프로덕션 빌드 (.mpk 생성) |
gleam run -m scripts/dev | 개발 서버 (HMR, port 3000) |
gleam run -m scripts/start | Mendix 테스트 프로젝트 연동 |
gleam run -m scripts/lint | ESLint 실행 |
gleam run -m scripts/lint_fix | ESLint 자동 수정 |
gleam run -m scripts/release | 릴리즈 빌드 |
gleam build --target javascript | Gleam → JS 컴파일만 |
gleam test | Gleam 테스트 실행 |
gleam format | Gleam 코드 포맷팅 |
기술 스택
- Gleam — 위젯 로직, UI, 빌드 스크립트 (JavaScript 타겟 컴파일)
- Gleam FFI — React/Mendix API 바인딩 (
@external+react_ffi.mjs+mendix_ffi.mjs) - React 19 — Mendix Pluggable Widget 런타임
- Rollup —
@mendix/pluggable-widgets-tools기반 번들링
제약사항
- Gleam → JS → Mendix Widget 파이프라인은 공식 지원되지 않는 조합이므로 빌드 설정 커스터마이징이 필요할 수 있다
- JSX 파일을 사용하지 않는다 — 모든 React 로직은 Gleam + FFI로 구현
- Redraw 등 외부 Gleam React 라이브러리는 사용하지 않는다
- FFI 파일에는 API 노출만 작성하고, 비즈니스 로직은 반드시 Gleam으로 작성
라이선스
Apache License 2.0 — LICENSE 참조