Elm과 Electron으로 데스크톱 앱을 만들어 보았습니다.
소개
Elm과 Electron을 사용하여 Twitter 해시 태그 인 #elm을 스트리밍하는 앱을 만들어 보았습니다. 완성된 것은 GitHub - calmery/elm-advent-calendar-2017 에서 볼 수 있습니다.
구현
커밋마다 정리해 갑니다.
Hello World
GitHub - calmery/elm-advent-calendar-2017 at 6490533e51c1fb4afea9e03aa9562e4762f52207
Elm이 undefined되었습니다.
조속히라고 할까. Electron에서 Elm을 참조하면 undefined가되었습니다.
Elm.Main.fullscreen() // Uncaught ReferenceError: Elm is not defined
실제로 생성 된 코드를 보면 module.exports가 우선되는 것 같습니다.
if (typeof module === "object")
{
module['exports'] = Elm;
return;
}
var globalElm = this['Elm'];
if (typeof globalElm === "undefined")
{
this['Elm'] = Elm;
return;
}
그래서 module.exports에서 직접 참조하도록했습니다.
const Elm = module.exports
// require を使って読み込むこともできる
const Elm = require( './app.js' )
이 문제는 webpack을 사용하면 걱정할 필요가 없습니다.
webpack 추가
GitHub - calmery/elm-advent-calendar-2017 at 55e80b6a4e1e11bb8713177fcbbaabc13d90732d
webpack 그 1 · Elm Tutorial 의 설명이 참고가 되었습니다.
트위터에서 얻은 트윗을 프로세스 간 통신 및 포트로 보내기
GitHub - calmery/elm-advent-calendar-2017 at 45fff5fea0170ef369d8554a4dbcbe0f020abe81
Electron은 메인 프로세스와 렌더러 프로세스가 분리되어 있습니다. 그러므로, 그 사이에서 교환을 실시하기 위해서 프로세스간 통신을 실시할 필요가 있습니다. 여기는 ipcMain | Electron를 보면 좋을까 생각합니다.
// src/entry.js
// In main process.
stream.on( 'data', event => {
const tweet = event.text
window.webContents.send( 'newTweet', tweet )
} )
// src/public/entry.js
// In renderer process.
ipcRenderer.on( 'newTweet', ( _, tweet ) => {
// do something ...
} )
일단 트윗 본문만 렌더러 프로세스에 전달하도록 했습니다. 여기에서 받은 데이터를 Elm에 Port를 사용하여 전달합니다. 여기는 JavaScript · An Introduction to Elm 의 Step 2: Talk to JavaScript 라든지 Elm의 Port에서 JS를 사용한다. - Qiita 가 참고가 됩니다.
// src/public/entry.js
ipcRenderer.on( 'newTweet', ( _, tweet ) => {
app.ports.newTweet.send( tweet )
} )
-- src/public/elm/Main.elm
port newTweet : (String -> msg) -> Sub msg
type Msg
= NewTweet String
subscriptions : Model -> Sub Msg
subscriptions model =
newTweet NewTweet
JSON 디코딩
GitHub - calmery/elm-advent-calendar-2017 at 39ab6b701fcfbbf29a46ec706286c2f4c76a5f1f
트윗의 본문만으로는 부족하기 때문에 유저의 정보등도 함께 건네주게 했습니다.
// src/entry.js
stream.on( 'data', event => {
const tweet = {
text: event.text,
created_at: event.created_at,
user: {
profile_image_url: event.user.profile_image_url,
name: event.user.name,
screen_name: event.user.screen_name,
}
}
window.webContents.send( 'newTweet', JSON.stringify( tweet ) )
} )
Elm에서 JSON을 디코딩합니다. JSON · An Introduction to Elm 이나 [Elm] Decoder a에서 여러가지 이해해 버리자 - Qiita 가 참고가 됩니다.
-- src/public/elm/Main.elm
type alias Tweet =
{ user : User
, text : String
, created_at : String
}
decodeTweet : String -> Result String Tweet
decodeTweet response =
decodeString tweetDecoder response
tweetDecoder : Decoder Tweet
tweetDecoder =
map3 Tweet
(field "user" userDecoder)
(field "text" string)
(field "created_at" string)
알림
GitHub - calmery/elm-advent-calendar-2017 at 5ee82825bd10cd5c3b0705f21b0804ba33455ca3
Elm에서 Port를 통해 Notification - Web API 인터페이스 | MDN을 호출하여 트윗을 받으면 알림을 표시합니다.
-- src/public/elm/Main.elm
port notification : String -> Cmd msg
...
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
...
Ok tweet ->
( List.append [ tweet ] <| List.take 100 model, notification tweet.text )
// src/public/entry.js
app.ports.notification.subscribe( message => {
new Notification( message )
} )
외형을 정돈하다
GitHub - calmery/elm-advent-calendar-2017 at c72da54e9bfb6d0aff18446d4313bfd31af246c5
Elm 에도 elm-styled라든지 style-elements라든지 있는 것 같습니다만, 이번은 보통으로 CSS를 사용했습니다.
요약
망설이는 곳도 몇 개 있었지만, 생각하고 있었던 것보다 순조롭게 생겼을까라고 생각합니다. Elm은 아직 모르는 것이 많기 때문에 여러가지 만들면서 시험해 나가면 좋겠다고 생각합니다.
Reference
이 문제에 관하여(Elm과 Electron으로 데스크톱 앱을 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/calmery/items/b80ee5a9c3aa0b268d02텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)