create-mendix-widget-gleam 1.0.8 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,7 +27,7 @@ my-widget/
27
27
  editor_preview.gleam # Studio Pro 디자인 뷰 미리보기
28
28
  components/
29
29
  hello_world.gleam # Hello World 공유 컴포넌트
30
- gleam.toml # Gleam 프로젝트 설정 (glendix >= 1.1.0 의존성 포함)
30
+ gleam.toml # Gleam 프로젝트 설정 (glendix >= 1.2.0 의존성 포함)
31
31
  CLAUDE.md # AI 어시스턴트용 프로젝트 컨텍스트
32
32
  ```
33
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mendix-widget-gleam",
3
- "version": "1.0.8",
3
+ "version": "1.1.1",
4
4
  "description": "Scaffold a Mendix Pluggable Widget powered by Gleam",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/src/index.mjs CHANGED
@@ -176,7 +176,7 @@ Gleam 언어로 Mendix Pluggable Widget을 개발하여 "Hello World"를 화면
176
176
  - **Gleam** → JavaScript 컴파일 (target: javascript)
177
177
  - **[glendix](https://hexdocs.pm/glendix/)** — React + Mendix Pluggable Widget API의 Gleam FFI 바인딩 (Hex 패키지)
178
178
  - **Mendix Pluggable Widget** (React 19)
179
- - **Package Manager**: ${pm} (npm 의존성은 \`gleam run -m glendix/install\`로 설치)
179
+ - **Package Manager**: ${pm} (기본 npm 의존성은 \`gleam run -m glendix/install\`로 설치, \`bindings.json\` 외부 React 패키지는 수동 설치 필요)
180
180
  - **Build**: \`@mendix/pluggable-widgets-tools\` (Rollup 기반)
181
181
 
182
182
  ## Architecture
@@ -215,7 +215,7 @@ React/Mendix FFI 바인딩은 이 프로젝트에 포함되지 않으며, [glend
215
215
  ## Commands
216
216
 
217
217
  \`\`\`bash
218
- gleam run -m glendix/install # 의존성 설치
218
+ gleam run -m glendix/install # 의존성 설치 + 바인딩 코드 생성 (외부 React 패키지는 사전에 수동 설치 필요)
219
219
  gleam run -m glendix/build # 위젯 프로덕션 빌드 (.mpk 생성)
220
220
  gleam run -m glendix/dev # 개발 서버 (HMR, port 3000)
221
221
  gleam run -m glendix/start # Mendix 테스트 프로젝트와 연동 개발
@@ -245,6 +245,7 @@ React:
245
245
  - \`glendix/react/hook\` — React Hooks (useState, useEffect 등)
246
246
  - \`glendix/react/event\` — 이벤트 타입 + 값 추출
247
247
  - \`glendix/react/html\` — HTML 태그 편의 함수
248
+ - \`glendix/binding\` — 외부 React 컴포넌트 바인딩
248
249
 
249
250
  Mendix:
250
251
  - \`glendix/mendix\` — \`ValueStatus\`, \`ObjectItem\`, Props 접근자
@@ -45,9 +45,11 @@ glendix = { path = "../glendix" }
45
45
  ```
46
46
 
47
47
  ```bash
48
- npm install
48
+ gleam run -m glendix/install
49
49
  ```
50
50
 
51
+ > `glendix/install`은 패키지 매니저를 자동 감지하여 의존성을 설치하고, `bindings.json`이 있으면 외부 React 컴포넌트 바인딩도 자동 생성합니다.
52
+
51
53
  #### 4) 빌드 확인
52
54
 
53
55
  ```bash
@@ -198,11 +200,87 @@ react.none() // React null 반환
198
200
 
199
201
  #### 외부 React 컴포넌트 사용
200
202
 
203
+ `glendix/binding` 모듈로 외부 React 라이브러리를 **`.mjs` 없이** 사용합니다.
204
+
205
+ **1단계: `bindings.json` 작성** (프로젝트 루트)
206
+
207
+ ```json
208
+ {
209
+ "recharts": {
210
+ "components": ["PieChart", "Pie", "Cell", "LineChart", "Line",
211
+ "XAxis", "YAxis", "CartesianGrid", "Tooltip", "Legend",
212
+ "ResponsiveContainer"]
213
+ }
214
+ }
215
+ ```
216
+
217
+ **2단계: 패키지 설치** — `bindings.json`에 등록한 패키지는 위젯 프로젝트의 `node_modules`에 설치되어 있어야 합니다. 생성된 `binding_ffi.mjs`가 해당 패키지를 직접 import하므로, Rollup이 번들링할 때 resolve할 수 있어야 합니다.
218
+
219
+ ```bash
220
+ # 사용 중인 패키지 매니저에 맞게 설치
221
+ npm install recharts
222
+ # 또는
223
+ pnpm add recharts
224
+ # 또는
225
+ yarn add recharts
226
+ # 또는
227
+ bun add recharts
228
+ ```
229
+
230
+ **3단계: `gleam run -m glendix/install`** 실행 (바인딩 자동 생성)
231
+
232
+ **4단계: 순수 Gleam 래퍼 모듈 작성** (편의용, 선택사항)
233
+
201
234
  ```gleam
202
- // 다른 React 컴포넌트를 합성할
203
- react.component(my_component, prop.new() |> prop.string("title", "Hello"), [
204
- // children
205
- ])
235
+ // src/chart/recharts.gleam 순수 Gleam, FFI 없음!
236
+ import glendix/binding
237
+ import glendix/react.{type Component}
238
+
239
+ fn m() { binding.module("recharts") }
240
+
241
+ pub fn pie_chart() -> Component { binding.resolve(m(), "PieChart") }
242
+ pub fn pie() -> Component { binding.resolve(m(), "Pie") }
243
+ pub fn cell() -> Component { binding.resolve(m(), "Cell") }
244
+ pub fn tooltip() -> Component { binding.resolve(m(), "Tooltip") }
245
+ pub fn legend() -> Component { binding.resolve(m(), "Legend") }
246
+ pub fn responsive_container() -> Component {
247
+ binding.resolve(m(), "ResponsiveContainer")
248
+ }
249
+ ```
250
+
251
+ **5단계: 위젯에서 사용**
252
+
253
+ ```gleam
254
+ import chart/recharts
255
+ import glendix/react
256
+ import glendix/react/prop
257
+
258
+ pub fn my_pie_chart(data) -> react.ReactElement {
259
+ react.component(recharts.responsive_container(),
260
+ prop.new() |> prop.int("width", 400) |> prop.int("height", 300),
261
+ [
262
+ react.component(recharts.pie_chart(), prop.new(), [
263
+ react.component(recharts.pie(),
264
+ prop.new()
265
+ |> prop.any("data", data)
266
+ |> prop.string("dataKey", "value"),
267
+ [],
268
+ ),
269
+ react.component(recharts.tooltip(), prop.new(), []),
270
+ react.component(recharts.legend(), prop.new(), []),
271
+ ]),
272
+ ],
273
+ )
274
+ }
275
+ ```
276
+
277
+ 래퍼 모듈 없이 직접 사용하는 것도 가능합니다:
278
+
279
+ ```gleam
280
+ import glendix/binding
281
+
282
+ let rc = binding.module("recharts")
283
+ react.component(binding.resolve(rc, "PieChart"), props, children)
206
284
  ```
207
285
 
208
286
  ### 3.2 Props 빌더
@@ -1305,8 +1383,8 @@ pub fn dashboard(props) -> ReactElement {
1305
1383
  | 문제 | 원인 | 해결 |
1306
1384
  |---|---|---|
1307
1385
  | `gleam build` 실패: glendix를 찾을 수 없음 | `gleam.toml`의 경로가 잘못됨 | `path = "../glendix"` 경로 확인 |
1308
- | `react is not defined` | peer dependency 미설치 | `npm install react@^19.0.0` |
1309
- | `Big is not a constructor` | big.js 미설치 | `npm install big.js@^6.0.0` |
1386
+ | `react is not defined` | peer dependency 미설치 | `gleam run -m glendix/install` |
1387
+ | `Big is not a constructor` | big.js 미설치 | `gleam run -m glendix/install` |
1310
1388
 
1311
1389
  ### 런타임 에러
1312
1390
 
@@ -1315,6 +1393,10 @@ pub fn dashboard(props) -> ReactElement {
1315
1393
  | `Cannot read property of undefined` | 존재하지 않는 prop 접근 | `get_prop` (Option) 대신 `get_prop_required` 사용 시 prop 이름 확인 |
1316
1394
  | `set_value` 호출 시 에러 | read_only 상태에서 값 설정 | `ev.is_editable(attr)` 확인 후 설정 |
1317
1395
  | Hook 순서 에러 | 조건부로 Hook 호출 | Hook은 항상 동일한 순서로 호출해야 함 (React Rules of Hooks) |
1396
+ | `바인딩이 생성되지 않았습니다` | `binding_ffi.mjs`가 스텁 상태 | `gleam run -m glendix/install` 실행 |
1397
+ | `could not be resolved – treating it as an external dependency` | `bindings.json`에 등록한 패키지가 `node_modules`에 없음 | `npm install <패키지명>` 등으로 설치 후 재빌드 |
1398
+ | `바인딩에 등록되지 않은 모듈` | `bindings.json`에 해당 패키지 미등록 | `bindings.json`에 패키지와 컴포넌트 추가 후 재설치 |
1399
+ | `모듈에 없는 컴포넌트` | `bindings.json`의 `components`에 해당 컴포넌트 미등록 | `components` 배열에 추가 후 재설치 |
1318
1400
 
1319
1401
  ### 일반적인 실수
1320
1402
 
@@ -1361,5 +1443,28 @@ list.map(items, fn(item) {
1361
1443
  let month = date.month(my_date) // 1~12 (Gleam 기준, 변환 불필요)
1362
1444
  ```
1363
1445
 
1446
+ **4. 외부 React 컴포넌트용 `.mjs` 파일을 직접 작성하지 마세요:**
1447
+
1448
+ ```gleam
1449
+ // 잘못된 방법 — 수동 FFI 작성
1450
+ // recharts_ffi.mjs를 만들고 @external로 연결하는 것
1451
+
1452
+ // 올바른 방법 — bindings.json + glendix/binding 사용
1453
+ import glendix/binding
1454
+ let rc = binding.module("recharts")
1455
+ let pie = binding.resolve(rc, "PieChart")
1456
+ react.component(pie, props, children)
1457
+ ```
1458
+
1459
+ **5. `binding.resolve()`에서 컴포넌트 이름을 snake_case로 바꾸지 마세요:**
1460
+
1461
+ ```gleam
1462
+ // 잘못된 예
1463
+ binding.resolve(m(), "pie_chart")
1464
+
1465
+ // 올바른 예 — JavaScript 원본 이름(PascalCase) 그대로 사용
1466
+ binding.resolve(m(), "PieChart")
1467
+ ```
1468
+
1364
1469
  ---
1365
1470
 
@@ -8,4 +8,4 @@ runtime = "node"
8
8
 
9
9
  [dependencies]
10
10
  gleam_stdlib = ">= 0.44.0 and < 2.0.0"
11
- glendix = ">= 1.1.1 and < 2.0.0"
11
+ glendix = ">= 1.2.0 and < 2.0.0"
@@ -1,11 +0,0 @@
1
- # This file was generated by Gleam
2
- # You typically do not need to edit this file
3
-
4
- packages = [
5
- { name = "gleam_stdlib", version = "0.70.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86949BF5D1F0E4AC0AB5B06F235D8A5CC11A2DFC33BF22F752156ED61CA7D0FF" },
6
- { name = "glendix", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glendix", source = "hex", outer_checksum = "9E1B78EEABCC0193F028BB271C3E60565C587E5E901FE553509ECF38D981B58A" },
7
- ]
8
-
9
- [requirements]
10
- gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
11
- glendix = { version = ">= 1.0.0 and < 2.0.0" }