Premise
So Ben started a discussion about Parcel the other day. I didn't participate in it, mainly because I've never even heard of Parcel before.
I did however open up the project website and it got me really interested for two reasons: First it seemed much simpler than webpack, second it promised to be much faster than webpack. Now my webpack experience is just slightly above what I'd describe as advanced beginner even though I already started a few dozen projects using it and watched many courses using it both on Youtube and Udemy. Most of the time however I just started with copying something that others crafted and adjusted it to my needs. I wouldn't go as far as to say that I had no idea what I was doing, but I certainly didn't master the tool.
I have copied webpack setups of some really knowledgeable people in the past, but I always felt that that the end result is somewhat clumsy and extremely slow, therefore I decided to give Parcel a shot. To make things more interesting, I decided to try to set it up with Elm 0.19 and Furtive
I literally just installed the tool this morning so I will not try to assess its performance in real-life projects but it sure feels much faster so far. What I will say however is that it was a breeze setting it up, even for me, even for such a weird setup. Let me drive you through:
Path #1: Quick and dirty way (<2 mins)
1. Clone my repo
git clone https://github.com/peteraba/elm0.19-furtive-parcel.git
2. Install the missing dependencies
yarn install
Path #2: DIY (~10 mins)
1. Create a new project directory
mkdir path/to/your/project
cd path/to/your/project
2. Initialize your project
yarn init -y
3. Add Furtive
For this project I decided to choose a tiny frontend framework called Furtive to keep things fast. I could have stayed with just including a minimized css from a CDN but I wanted to test Parcel so I decided to add Sass compilation instead:
yarn add node-sass
yarn add furtive
4. Add Elm support
UPDATE (2018-09-20):
This part has become much easier as 0.19 support is now added to parcel-plugin-elm, simply add it with yarn:
yarn add parcel-plugin-elm
Now this part was a bit tricky, because I wanted to use the latest Elm 0.19 and the main Elm plugin for Parcel is outdated. There is a pull request from Ben Hanna for 0.19 but it's not yet merged. Also, I'm not really a yarn expert, so I had to look up how to use his code instead of the official one. Okay, it only took about 2 minutes, but still..
So basically I downloaded Ben's code and extracted it to a directory called outdated
and added it via yarn (yarn add file:./outdated/parcel-plugin-elm). This should remind me to use the main repo once the changes get merged.
5. Initialize your elm project
Parcel still doesn't know about Elm, so we should probably install it locally:
yarn add elm@^0.19.0-bugfix2
Then we can also initialize our Elm project:
yes | ./node_modules/.bin/elm init
Optional: global Elm install
In case you don't have Elm 0.19 installed but want to toy with it, please find the installation instructions in the Official Guide.
6. Create project files
sass/main.scss
$font-family: 'Lato', Helvetica, sans-serif;
$dark-gray: #222;
$text-color: $dark-gray;
$body-bg: #fafafa;
@import "node_modules/furtive/scss/all.scss";
.elm-container {
margin: 5px 0;
button, div {
display: inline-block;
margin: 2px;
}
}
src/Main.elm
:
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import Html.Attributes exposing (class)
main =
Browser.sandbox { init = 0, update = update, view = view }
type Msg = Increment | Decrement
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
view model =
div [class "elm-container txt--center"]
[ button [ onClick Decrement, class "btn btn--blue btn--s" ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment, class "btn btn--green btn--s" ] [ text "+" ]
]
index.html
:
<html>
<head>
<title>Hello, Parcel!</title>
<script src="./index.js"></script>
</head>
<body>
<main></main>
</body>
</html>
index.js
:
import './sass/main.scss'
if (module.hot) {
module.hot.dispose(() => {
window.location.reload();
});
}
import('./src/Main.elm')
.then(({ Elm }) => {
var node = document.querySelector('main');
Elm.Main.init({ node: node });
});
Note: The if part in the middle is a workaround for a Parcel issue, might become obsolete soon.
End result
Okay, now we have everything in place, let's give it a go:
➤ parcel index.html
Server running at http://localhost:1234
Success! Compiled 1 module.
Success! Compiled 1 module.
✨ Built in 2.23s.
^C
➤ parcel index.html
Server running at http://localhost:1234
✨ Built in 724ms.
^C
Less than 3 seconds without cache, less than a second with cache, hot reload works as expected. What is more important however is that I didn't have to edit any configuration files.
Conclusion
I have to say I'm really impressed with Parcel so far. Its getting started guide is quite short, but it still allowed me to achieve what I wanted without getting confused or stuck even once. I think this might just be the beginning of a beautiful friendship...
Top comments (4)
Another 1.5h of my life wasted on parcel. Tried it ~1 year ago, and even the most basic example with bare js+html+css didn't work at all.
Ran the code from the repo, and it crashed immediately, which looked like parcel not recognizing elm files.
Did some minimal research, and somehow managed to bundle & display "hello world". But then, it watches only the first file change, and after that, I must manually restart it to see changes (ctrl+r doesn't work).
I'm so tired of the broken software everywhere...
PS: your guide is fine.
I'm sorry about the trouble you went through. The setup actually worked reasonably well for me developing a decent sized SPA, but I'm also having some major issues running parcel at the moment because of this bug: github.com/parcel-bundler/parcel/i...
Getting an 'Unexpected token' error when parcel/babel tries to parse the elm file on the 2nd line (import Html exposing (Html, button, div, text) ). Any ideas?
Not really. Are you using my repo?