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')(';)')
}
}
})
Compilation of Elm files in version 0.19.1 requires a main
value for all files
passed to elm-make
.
-- NO MAIN ---------------------------------------------------------------------
When producing a JS file, I require that given files all have `main` values.
That way functions like Elm.CSS.ChatConversationStyle.init() are definitely
defined in the resulting file. I am missing `main` values in:
... cut for brevity ...
To target only files that have main
values, use the ember-elm includePaths
configuration option in ember-cli-build.js
to limit compliation to only
safe directories. The elm compiler will handle including any other module
dependencies.
elm: {
includePaths: ['app/elm-modules/Main']
}
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