테마 컴포넌트 내 JavaScript 에셋

STL 미리보기 테마 컴포넌트를 구축하려고 합니다. 이를 위해 훌륭한 자바스크립트 라이브러리 가 있지만, 테마 컴포넌트에서 어떻게 작동하게 할지 확실하지 않습니다.

이 라이브러리는 ES6가 아닌 일반 자바스크립트로 작성되어 있어, 단순히 “javascripts” 디렉토리에 넣고 가져오기(import)할 수 없다는 뜻인 것 같습니다. 맞습니까? 게다가 이 라이브러리는 스크립트 태그를 통해 가져와져야 한다는 가정에 기반한 것 같습니다.

따라서 스크립트 태그를 생성하여 문서 헤드에 추가할 수는 있지만, 라이브러리 JS 파일의 이름을 어떻게 찾습니까? 또한 이 라이브러리는 여러 JS 파일로 구성되어 있으며, 해당 파일들이 동일한 디렉토리에 사용 가능하다고 가정합니다. 나머지 라이브러리를 로드하기 위해 추가적인 스크립트 태그를 생성합니다.

그러면 이 파일들은 javascripts 디렉토리에 두어야 합니까? 아니면 자산(assets)으로 취급해야 합니까? 이와 유사한 작업을 수행하는 가장 가까운 예로 discourse-math 플러그인을 찾을 수 있지만, 가능하면 이를 테마 컴포넌트로 유지하는 것이 좋습니다.

이것은 플러그인에 대해 어떻게 하는지 보여 주는 것 같습니다: How to ship javascript library with plugin?
아직 테마 컴포넌트에 대해서는 아무것도 찾지 못했습니다.

잘 모르겠지만, 당신에게는 좋은 답이 없잖아!

다음으로 살펴볼 것은… 테마 컴포넌트에 다른 파일을 포함하는 것에 관한… 내용이다.

나 생각에는, 대형 테마 컴포넌트들이 살펴볼 만한 곳인 것 같아. 기본적으로, 파일 구조는 테마 컴포넌트와 동일하고, 엠퍼(Ember)가 플러그인처럼 해당 테마 파일을 로드할 거라고 생각해.

그렇게 생각하지 않아요. 각 구성 요소가 자체 가상 디렉터리를 갖는 것 같아요. discourse/theme-10/… 같은 형태로요. 따라서 거기서 파일을 로드하려면 최소한 해당 디렉터리가 무엇인지 알아야 합니다.

에셋 이름은 변수로만 접근 가능한 것 같고, 실제 이름은 길고 복잡한 숫자라서 이 방법도 작동하지 않을 것 같습니다.
지금 당장 컴포넌트로 이를 구현하는 방법이 전혀 없는 것 같습니다. 그래서 당분간 nginx를 통해 JS 파일을 사이드로드하고 그 방식으로 접근할 계획입니다. 안타깝게도 이 컴포넌트는 저에게만 작동할 것 같습니다.

테마 구성 요소의 header.html 파일에 일반 script 태그를 추가할 수 있습니다.

사이드로딩이 작동합니다!
단 한 번만요. :frowning:

다른 토픽으로 이동했다가 STL이 있는 토픽으로 돌아오면 작동하지 않습니다. JavaScript 콘솔에 오류가 표시되지 않는 이유가 무엇인지 모르겠습니다. 어딘가에서 onload 관련 이상 현상에 대해 논의하는 스레드를 본 적이 있는데, 이 스크립트들이 onload를 사용하므로 관련이 있을 수도 있을까요?

맞습니다. 하지만 viewstl 코드는 인라인으로 넣는 것이 아닙니다.
사이드로딩을 위해 common/head_tag.html에 다음과 같은 script 태그를 넣었습니다:

<script src="/xi/viewstl/stl_viewer.min.js"></script>

(/xi/는 nginx에서 제공됩니다)

Discourse는 SPA(단일 페이지 애플리케이션)입니다. 단순히 onLoad에 스크립트를 붙이는 것만으로는 작동하지 않습니다. Discourse의 API 엔드포인트에 연결해야 합니다. Discourse 테마 개발자 가이드를 확인해 보세요.

좋아요, 그럼 이제 낡은 스크립트 태그 기반 로딩을 다른 방식으로 대체해 볼게요.

이 페이지를 여러 번 읽었지만 여전히 작동하지 않습니다.
import 문으로 three.js를 로드하려고 하고 있는데, 무엇을 해도 모듈을 찾을 수 없다는 오류가 발생합니다. 이상한 점은 다른 파일들은 정상적으로 import할 수 있다는 것입니다. 또한 오류 메시지는 전혀 도움이 되지 않습니다.

어쨌든, 다음과 같은 오류가 발생합니다. 누군가 도움을 줄 수 있을까요:

작동하지 않는 import는 다음과 같습니다:

그리고 제가 받는 오류는 다음과 같습니다:

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 An error occurred in the "STL previews" theme/component: Error: Could not find module `discourse/theme-17/three/build/three.module` imported from `discourse/theme-17/stlviewer/StlViewer`
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74612)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74616)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
(anonymous) @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333
u @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74325
initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74304
i.initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:7723
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49335
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67724
e.walk @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67638
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67568
e.topsort @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67576
_runInitializer @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49361
runInitializers @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49333
_bootSync @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47768
domReady @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47668
n._run @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67275
n._join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67251
n.join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:66968
f @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53760
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53864
l @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3776
c @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3844
setTimeout (async)
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3882
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
fire @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3648
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
ready @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4120
z @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4130

'.'은 마법 같은 모듈 구분자인가요?

점(.)이 뭔가 특별한 의미를 가지는 것 같습니다. three.module.js를 three_module.js로 이름 변경하면 완전히 다른 문제가 발생합니다. 이제 테마를 로드할 수 없거든요. (500 오류)

완전한 URL을 사용하여 CDN에서 three.js를 직접 가져오는 것도 시도해 봤는데, 이 역시 작동하지 않는 것 같습니다…

여기서처럼 D3 라이브러리를 require하는 것처럼, JavaScript 에셋의 Just In Time 로딩만 필요하시다면 Loadscript를 사용하여 이 패턴을 적용할 수 있습니다:

그리고 위쪽에는:

Loadscript는 Promise를 반환하므로, 결과에 대해 .then을 수행해야 합니다. (확신은 못 하지만, 결과가 암묵적으로 캐시되어 두 번째부터는 더 빠르게 실행된다고 가정합니다.)

보시는 바와 같이, 이를 연쇄적으로 연결하여 여러 스크립트를 순서대로 로드할 수 있습니다.

이 코드는 Ember 컴포넌트 내부에서 실행되며 didInsertElement 훅에서 트리거됩니다. Ember 컴포넌트에 대해 더 자세히 알고 싶다면 여기에서 확인하세요: Templates are HTML - Components - Ember Guides

또한 스크립트 자체는 javacsripts/assets 디렉터리에 저장되어 있다는 점도 참고하세요.

이것은 @j.jaffeux의 코드를 기반으로 작성했으며, 그는 완전히 다른 스크립트를 로드하는 데 이를 사용했습니다 (Joffrey, 감사합니다! :+1: )

Discourse 예시입니다:

팁: 비슷한 작업을 수행하는 공식 및 Pavilion TC와 플러그인들을 항상 살펴보고 그들이 어떻게 구현하는지 확인해 보세요 :slight_smile:

흥미롭네요. 조언해 주셔서 감사합니다.
loadScript를 사용해 보겠습니다. 제 문제를 해결할 수 있을지 확인해 보려고요.

더 간단한 접근 방식을 시도해 보기로 했다.
단순히 iframe을 만들어 HTML 페이지를 로드하고, 그 페이지에서 미리보기가 작동하도록 모든 복잡한 스크립트 작업을 수행하게 한다. 현재는 재사용 가능한 형태로 되어 있지 않지만, 이를 플러그인으로 만드는 것은 비교적 간단할 것이다.