# Discourse 테마 컴포넌트가 이제 Wasm을 지원합니다 🎉

**URL:** https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574
**Category:** Announcements
**Tags:** new-feature
**Created:** [4월 7, 2022, 6:05오전 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574 "2022-04-07T06:05:38Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [4월 7, 2022, 6:05오전 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/1 "2022-04-07T06:05:38Z")

</div>

[WebAssembly](https://webassembly.org/) (Wasm)는 모든 최신 브라우저에 탑재되어 개발자가 휴대 가능한 바이너리 프로그램을 배포할 수 있게 해주는 기술입니다.

즉, 개발자는 거의 모든 프로그래밍 언어를 사용해 웹을 대상으로 애플리케이션을 개발할 수 있습니다.

Discourse의 맥락에서 이는 과거에 플러그인 개발자에게만 제공되었던 상당히 풍부한 확장 기능 세트를 배포할 수 있는 문을 열어줍니다.

예를 들면 다음과 같습니다:

- 이미지 워터마킹 / 리사이징 / 크롭
- graphviz 또는 svgbob을 사용한 그래프 생성
- 프로그래밍 샌드박스 (예: Ruby 런타임을 내장한 게시물)
- 그리고 훨씬 더 많은 것들

과거에는 Discourse의 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 때문에 로컬 업로드와 CDN이 모두 없는 설치 환경이 아닌 한 Wasm에 대한 접근이 차단되었습니다.

클라이언트 측에 새로운 인터페이스가 추가되어, 로컬 도메인을 통해 무조건적으로 접근 가능한 테마 내 JavaScript 에셋을 배포할 수 있도록 지원하게 되었습니다.

이를 통해 테마 개발자가 Wasm을 깔끔하게 호스팅할 수 있으며, 그 흐름은 다음과 같습니다:

컴포넌트 → 로컬 웹 워커 → CDN에 호스팅된 Wasm

[Discourse svgbob](https://meta.discourse.org/t/discourse-svgbob/223573) 은 새로운 패턴의 끝에서 끝까지(end-to-end)의 예시이며, 두 가지 핵심 변경 사항은 다음과 같습니다:

1. 모든 `.js` 에셋은 로컬 서버에서도 CDN과 함께 사용 가능하게 됩니다:

```plaintext
{
...
  "assets": {
    "worker": "assets/will-be-avilable-on-local.js"
  }
}

```

1. 로컬 에셋의 URL은 `settings.theme_uploads_local`을 통해 접근 가능합니다.

따라서 위의 예시에서:

```plaintext
settings.theme_uploads_local.worker; // 로컬 에셋
settings.theme_uploads.worker; // CDN 에셋

```

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [4월 16, 2022, 11:16오전 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/8 "2022-04-16T11:16:14Z")

</div>

wasm과 직접적인 관련은 없지만, 이 코드에 대해 다른 흥미로운 점을 발견했습니다. 이 기능은 새로운 것인가요?

예제에서 `loadScript`가 더 이상 필요하지 않은 것 같습니다. (import가 중복된 것 아닌가요?):

> <https://github.com/SamSaffron/discourse-svgbob/blob/6d7818035fb1eab755ba4facb4b837e738aa0b51/javascripts/discourse/api-initializers/discourse-svgbob.js#L1>

대신, 워커가 존재하지 않는다고 판단되면 워커 스크립트가 JIT로 로드되는 것인가요?

> <https://github.com/SamSaffron/discourse-svgbob/blob/6d7818035fb1eab755ba4facb4b837e738aa0b51/javascripts/discourse/api-initializers/discourse-svgbob.js#L71>

에셋 참조에서 생성된 URL을 사용하고 있습니다.

훌륭한 패턴이며 매우 유용합니다!

다만, 워커에 대해 질문이 있습니다.

세 번째 당사자(third party) 워커 스크립트를 사용했는데, 해당 스크립트에 워커의 전역 범위에 추가 스크립트를 포함하기 위한 [importScripts()](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts) 문이 포함되어 있다면, 테마 컴포넌트 내에서 import를 위해 해당 스크립트를 어떻게 포함해야 할까요?

아마도 제가 묻고 싶은 것은: Discourse 테마 컴포넌트 내에서 URL로부터 스크립트를 어떻게 요구(require)하는지에 대한 것일 수 있습니다.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 16, 2022, 2:28오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/9 "2022-04-16T14:28:29Z")

</div>

이 시나리오에서 저는 메인 JS 스크립트에서 가져오려는 URL을 포함하여 `postMessage`를 사용했습니다. 이는 워커의 메시지 핸들러에서 수신되며, 수신된 URL을 `importScript`할 수 있습니다.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [4월 16, 2022, 2:30오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/10 "2022-04-16T14:30:15Z")

</div>

라파엘, 감사합니다! 참고할 오픈소스 예시가 있나요?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 16, 2022, 2:34오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/11 "2022-04-16T14:34:51Z")

</div>

저는 코어에서 동일한 패턴을 사용했습니다

> <https://github.com/discourse/discourse/blob/c81d4597a779ae730571b8eaa3bd61c6acb51b0c/app/assets/javascripts/discourse/app/services/media-optimization-worker.js#L112>

> <https://github.com/discourse/discourse/blob/c81d4597a779ae730571b8eaa3bd61c6acb51b0c/public/javascripts/media-optimization-worker.js#L166>

---

<div class="post-metadata">

### Author: ![Heinenen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/heinenen/32/372537_2.png) [@Heinenen](https://meta.discourse.org/u/Heinenen)
#### Post date: [3월 20, 2024, 5:28오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/12 "2024-03-20T17:28:10Z")

</div>

[theme creator](https://discourse.theme-creator.io)를 사용하여 wasm을 사용하도록 설계된 새로운 테마 컴포넌트를 만들고 있습니다. 시작점으로 [svgbob](https://github.com/discourse/discourse-svgbob)을 테마 컴포넌트로 업로드해 보았지만, wasm 파일이 포함되어 있어 업로드가 허용되지 않았습니다.

이것이 테마 크리에이터의 의도된 제한 사항인가요? 아니면 svgbob을 그대로 설치할 수 없는 건가요?

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [3월 20, 2024, 9:50오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/13 "2024-03-20T21:50:50Z")

</div>

테마 제작자의 파일 유형 제한이 문제인 것 같고, 이를 해제해야 할 것 같습니다.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [3월 20, 2024, 9:59오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/15 "2024-03-20T21:59:02Z")

</div>

themecreator를 기본 ‘theme authorized extensions’ 설정으로 리셋했는데, 여기에는 WASM도 포함되어 있습니다. 이제 작동해야 할 것 같아요 @Heinenen.

(왜 기본값이 아닌 다른 설정으로 되어 있었는지 모르겠네요… 아마 과거에 일반적인 확장 프로그램 중 하나가 빠져 있었나 봐요 🤷‍♂️)

---

<div class="post-metadata">

### Author: ![Heinenen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/heinenen/32/372537_2.png) [@Heinenen](https://meta.discourse.org/u/Heinenen)
#### Post date: [3월 20, 2024, 10:16오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/16 "2024-03-20T22:16:07Z")

</div>

네, 정말 멋지네요. 이제 제대로 작동하는 것을 확인했습니다. 감사합니다!

---

<div class="post-metadata">

### Author: ![Heinenen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/heinenen/32/372537_2.png) [@Heinenen](https://meta.discourse.org/u/Heinenen)
#### Post date: [3월 20, 2024, 10:24오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/17 "2024-03-20T22:24:58Z")

</div>

음, 아직 완벽하게 작동하지 않는 것 같으니 조금 돌아가야 할 것 같습니다.  
svgbob를 다시 업로드해 보았는데, 이번에는 성공했습니다.

이제 [MDN](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API)에서 가져온 [wasm 파일](https://raw.githubusercontent.com/mdn/webassembly-examples/master/js-api-examples/simple.wasm)을 직접 업로드해 보았더니 다음과 같은 오류가 발생합니다:  
`An error occurred: You supplied invalid parameters to the request: string contains null byte`

제 개발 컨테이너에서는 문제가 되지 않으며, 같은 파일을 문제없이 업로드할 수 있습니다.

---

<div class="post-metadata">

### Author: ![hellekin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hellekin/32/51636_2.png) [@hellekin](https://meta.discourse.org/u/hellekin)
#### Post date: [3월 21, 2024, 7:05오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/18 "2024-03-21T19:05:22Z")

</div>

> [@david](#):
>
> 기본 설정이 아닌 값으로 되어 있던 이유가 궁금하네요…

웹사이트에서 바이너리를 실행하는 것은 보안 위험을 초래할 수 있으므로 신중하게 선택해야 하지 않나요? 그것이 기본값으로 설정되지 않은 이유가 될 수도 있습니다. @Roman, 어떻게 생각하시나요?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [3월 21, 2024, 7:09오후 UTC](https://meta.discourse.org/t/discourse-theme-components-now-support-wasm/223574/19 "2024-03-21T19:09:25Z")

</div>

> [@hellekin](#):
>
> default가 아니었던 이유

기본적으로 테마에서 허용됩니다. discourse.theme-creator.io의 사이트 설정이 변경되었을 뿐입니다. (그것은 누구나 테마를 업로드하고 공유할 수 있는 플러그인이 있는 일반 Discourse 사이트입니다).

> [@hellekin](#):
>
> 웹사이트의 바이너리가 보안 노출

WASM은 여전히 브라우저에 의해 샌드박싱되므로, 보안 노출은 `.js` 파일과 동일합니다.
