Transpilers
Source → Source
Sass, Less, Stylus, Autoprefixer, Myth, Babel, Jsx, Coffeescript, TypeScript, Markdown, Jade, Haml
- Simple tools.
- Unix 1-to-1 command line.
- Enables abstractions we like
- Give access to powerful new features immediately
- These are awesome. But there is still a problem
- Note that I collapse css, js, html transpilers into one abstract
Build Artifacts
- Build artifacts are transient
- We don't want humans looking at them
- We want machines looking at them
- They are in the way and cluttering up our setups
- Let's set up a development environment as an example
Transpiling: Source directory
app/main.scss → app/main.css
echo "*.css" >> .gitignore
app/vendor/bootstrap.css ❌
- The build artifact is a sibling to the source
- This is simple. URLs make sense
- We should probably ignore build artifacts in our source directory (FRAGMENT)
- But this brings us in trouble with sources that are validly with the same extension (FRAGMENT)
- Conclusion: Transients do not belong in your source directory
- Let's try a different approach
Transpiling: Temp Directory
app/main.scss → artifacts/main.css
echo "artifacts" >> .gitignore
HTTP GET artifacts/main.css ✔ 200
HTTP GET artifacts/index.html ✘ 404
HTTP GET app/index.html ✔ 200
- Here we moved build artifacts to a temp directory
- Version control and clutter problems solved
- But now URLs don't make sense any more. Browsers can't find the build artifact in the web root
- You now have a choice of either pointing URLs at a non-existing path or to change your URL resolving, which might look like this (FRAGMENT)
- Your web server now looks for build artifacts first and falls back to non-built sources
Transpiling: Build trigger
WATCH app/**/*.css
TRIGGER TRANSPILE app/main.scss → artifacts/main.css
TRIGGER LIVERLOAD app/main.css
npm install grunt/gulp/broccoli
- Running the transpiling manually gets tedious, so we set up a file watcher to trigger transpiling on each source file increment (FRAGMENT)
- This takes care of the task of creating the build artifacts we saw before (FRAGMENT)
- And you probably also want livereloading in there as well
- And you probably also need a task runner to orchestrate all of this as the setup grows
- Ok, that's about it. Now we have a transpiler setup, right? Wrong! We forgot about non-browser integrations
Transpiling: Integrations
Task runner
Production bundler
Linter
Test framework
- CSS is only consumed by few tools. Your browser and your build system mainly. Javascript is consumed by many more
- So now you need to find transpiler plugins for all of these tools
- And for each of those integrations you need a plugin for each transpiler, so start multiplying...
- So let's take a step back and evaluate
- Does this look simple to you?
- The word I would use is complex (SLIDE)
Complexity
- Not to worry though, modern tooling has you covered!
- We just take all of this complexity... And scaffold it (FRAGMENT)
- Problem not solved. Problem hidden away
- Easy vs. simple
- But when something eventually goes wrong, this is what a new developer sees
How
does
this
work?
- ... and this is what you find (FRAGMENT x4)
- This setup requires you to know about: version control, web server middleware, file watching, the task runner, transpiler plugins...
- As a minimum!
- The eco system lock-in removes their ability to gradually ease into the complexity
- When I voice this critique I often have experienced developers tell me (SLIDE)
NEED
- "My setup is complex / legacy / customized / special, so we need the complexity"
- (FRAGMENT) NEED... complexity
- I believe this is wrong. What you need is ABILITY. You want to be able to transpile
- But maybe somewhere along the way cause and effect were confused.
- So let's look at what we actually need from a transpiling tool
Fusile
$ npm install fusile -g
$ fusile <sourcedir> <targetdir>
License: MIT
Status: Development ready
Tools provide ability
Reject complexity
Demand simplicity
♥
Transpiling
Recomposed
By Peter Müller / @_munter_