ember-elm lets you write Ember components in Elm! It integrates cleanly with your existing Ember application, so you can experiment with Elm without having to migrate to another front-end stack. It also integrates with ember-cli, so you can develop Elm code with live reloading, while having access to the full power of ember-cli's addon ecosystem.
- Use your Elm code in Ember with
elm-component
- Generate Elm modules with
ember g elm-module
- Live reload with ember-cli
- Leverage the power of the ember-cli and Elm ecosystems together in one stack
Before you can install ember-elm, you need to have two things installed:
- Node 6.0.0+ or up. This is because this addon's build code uses ES6.
- Elm. Don't worry, it's relatively pain-free! This will be automated in the future.
$ ember install ember-elm
Alternatively, if you're using Yarn:
$ yarn add ember-elm --dev && ember g ember-elm
To get started, let's get a simple "Hello World" example up and running.
First, generate an Elm module:
$ ember g elm-module hello
This will generate an Elm file in your project, located at
app/elm-modules/Hello.elm
. You will see that a very basic Elm program has
already been written for you:
module Hello exposing (..)
import Html exposing (text)
main =
text "hello world"
Take note of the module Hello exposing (..)
declaration at the top of
Hello.elm
. Like an ES6 file, every Elm file defines its own module. This
particular module will simply output a <div>
containing the text "hello world"
to the screen.
Great! Your project now contains an Elm module. To actually use that module,
include the file <your-app>/elm-modules.js
into a controller/component, so
that you can use your Elm module in a template.
Note:
Behind the scenes, ember-elm finds all Elm files in your app tree, and compiles all of them into a single
elm-modules.js
file at the root of your tree. So you can't import an Elm file directly – you have to importelm-modules.js
, and access properties on the imported object to get the module you want.
For example:
// routes/application.js
import Ember from 'ember'
import Elm from 'my-app/elm-modules'
export default Ember.Route.extend({
setupController(controller, model) {
controller.set('Elm', Elm)
}
})
Once that's done, you should see a simple "hello world" output to the screen:
Output:
Congrats! If you've made it this far, you are now up and running with Elm.
Pass in an Elm module to use it:
If the Elm module requires flags, pass them in and they will be passed to the Elm module:
To communicate with your Elm module, grab the functions that are passed via ports:
import Ember from 'ember'
export default Ember.Controller.extend({
sendToElm(emojis) {},
actions: {
setupPorts(ports) {
this.set('sendToElm', ports.emoji.send)
},
winkyFace() {
this.get('sendToElm')(';)')
}
}
})
ember-elm
requires your elm files w/ main
values to be defined in a separate directory
than the rest of your elm code. By default this is set to /elm-modules/Main/
, which will match everything
in <your app>/elm-module/Main/
. Those files can then be used to import other elm files living outside of /elm-modules/Main/
.
To specify a different location, override mainDirs
in ember-cli-build.js
like:
elm: {
mainDirs: ['/elm-modules/AnotherMain']
}
ember-elm (via node-elm-compiler) will install Elm dependencies to
elm-stuff/
. To avoid committing Elm deps to version control, run:
$ echo elm-stuff/ >> .gitignore
Babel will start stripping whitespace from elm-modules.js
when it exceeds
100KB. This makes it harder to learn how it works. To disable this behavior, set
the Babel compact
option to false in your ember-cli-build.js
:
module.exports = function(defaults) {
const app = new EmberApp(defaults, {
babel: {
compact: false
}
})
}
Jason Tu · Tide Software · GitHub @nucleartide · Twitter @nucleartide · Slack @nucleartide