Last week, I didn't have much to write about, so I tried to learn about Brunch and documented my journey. I'll link this journey at the end of this post. User YJDoc2 suggested to also have a look at Snowpack. I heard a bit about Snowpack before (mainly a tweet or two telling how awesome it was), but haven't used it myself. Time to change exactly that!
Let's have a look
Ok, so the website says that Snowpack is the "faster frontend build tool":
Brunch managed to start between 70 and 100ms. I suspect Snowpack to be in that ball park as well, I mean, this thing has to execute something, right? Brunch already had its problems when Tailwind was added to the build and suddenly we were talking about 70 and 100hms (err, hecto-milli-seconds, basically seconds divided by ten... I should've just written 7-10s. Or deciseconds? ds? Whatever.). But that was mostly PostCSS. I actually suspect the same thing to happen here: A lot of tools (like TypeScript, JSX, CSS, etc.) supposedly work out of the box, but PostCSS needs a plugin. TypeScript is also supported at "build only" and extra type checking would need an extra plugin. Fair enough, I don't expect my build tool to handle everything from the start. But that TypeScript stuff does sound interesting.
(The attentive reader might've caught that I was referencing the docs. I'm not gonna do the same mistake again and just get going without knowing how!)
Boilerplating
Same setup as last time: Tailwind + Alpine. Maybe I should change that to a more complex setup to really see where the tool starts to work against me and find possible pit falls, but those two things should do the trick for now.
I'm actually starting to wonder if there's an Alpine-like framework written in TypeScript. Alpine is written in plain ol' JS, so with the stack above I can't really test the TS capabilities of the build tool without having to write custom stuff. Just thinking aloud here... But maybe I'll just write a show/hide component in TS to use with Alpine and see if that plays out nice.
Anyways, I'm eager to try Snowpack now. npm init
and lot's of hitting enter it is. I'm really curious about the supposed speed of this tool. So instead of installing a lot of things, I just install Snowpack itself, add the "start" and "build" commands to package.json and add an index.html containing a Hello World:
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
And now I type npm run start
and slooowly hit the enter button...
Woah
Seriously, woah. That dev server is basically instant. Gimme a sec, that caught me off guard...
It did log something to the CLI, that much I can tell, but I wasn't even able to read a single word before my browser jumped right in my face, eager to greet the planet like an over-motivated hamster on its first day at its dream job.
I want to know what snowpack wanted to tell me before the browser interrupted it, though, so let's have a look:
> snowpack dev
[snowpack] Hint: run "snowpack init" to create a project config file. Using defaults...
[snowpack] Welcome to Snowpack! Because this is your first time running
this project, Snowpack needs to prepare your dependencies. This is a one-time step
and the results will be cached for the lifetime of your project. Please wait...
[snowpack] No dependencies detected. Ready!
[snowpack] Server started in 8ms.
[snowpack] Local: http://localhost:8080
[snowpack] Network: http://192.168.1.50:8080
Well, hello Snowpack. The browser was faster.
Wait - 8ms? Are you kidding me? How does it do that? It does feel right, though. (As if I could tell the difference between 8 and 80ms...)
Snowpack apparently used its built-in defaults here. I don't think adding a basic config file would slow it down much. I'm amazed that it just works as a plain server, too. Usually I use serve
to quickly look at some built stuff, but this thing feels way faster. I think I'll get rid of serve on my system and just use Snowpack instead.
Back to business. Snowpack tells me to create a project config file with snowpack init
, so I'm doing just that and do a re-run to see if that has any impact.
Nope, no impact. That thing stays super fast.
Let's get back to boilerplating
The Snowpack documentation has a guide on how to set up PostCSS. I'll follow just that and alter the package.json, add a postcss.config.js and an index.css.
Snowpack config:
// Snowpack Configuration File
// See all supported options: https://www.snowpack.dev/reference/configuration
/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
mount: {},
plugins: [
"@snowpack/plugin-postcss"
],
packageOptions: {},
devOptions: {},
buildOptions: {},
}
The package.json:
{
"name": "snowpack-tryout",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "snowpack dev",
"build": "snowpack build"
},
"author": "",
"license": "",
"devDependencies": {
"@snowpack/plugin-postcss": "^1.2.2",
"autoprefixer": "^10.2.5",
"snowpack": "^3.1.2"
},
"dependencies": {
"tailwindcss": "^2.0.4"
}
}
Postcss config:
// postcss.config.js
// Taken from: https://tailwindcss.com/docs/installation#using-tailwind-with-postcss
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
}
And index.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
Nothing out of the ordinary, right? Right. Let's try this again:
As you can see, the server still starts in around 10ms, which is awesome, but the entire Tailwind thing needs its 10s. Instead of waiting for the browser window to open, I wait for stuff to load instead. Fair enough, it has to execute the entire Tailwind stuff somewhen. But the hot reloading is blazing fast:
Not too bad at all! Now I wanna get some TypeScript and Alpine in there.
TypeScript + Alpine
I install Alpine by executing npm i alpinejs
and create a simple index.ts:
import 'alpinejs'
(Yup, that's all so far)
And I adjust index.html a little:
<!-- ... -->
<h1
class="text-4xl text-red-600"
x-data="{ text: 'Hello, World' }"
x-text="text"
></h1>
<script type="module" src="index.js"></script>
<!-- ... -->
No server restart, no nothing, it just works™. Hot reloading is fast as always, so the entire thing apparently didn't slow down Snowpack at all. I'm still amazed.
Next up, a little Alpine component:
interface TabNav {
init: () => void
show: (selector: string) => void
}
export default (): TabNav => ({
init (): void {
console.log(this.$el)
},
show (selector: string): void {
this.$el
.querySelectorAll(`.content:not(${selector})`)
.forEach((el: HTMLElement) => {
el.classList.add('hidden')
})
this.$el.querySelector(selector).classList.remove('hidden')
}
})
This I can import in my index.ts:
import 'alpinejs'
import tabNav from './tabNav'
// @ts-ignore
window.tabNav = tabNav
And then it can be used with some DOM:
<!-- ... -->
<div x-data="tabNav()" x-init="init">
<ul class="flex">
<li class="p-4 cursor-pointer" @click="show('#a')">Show A</li>
<li class="p-4 cursor-pointer" @click="show('#b')">Show B</li>
<li class="p-4 cursor-pointer" @click="show('#c')">Show C</li>
</ul>
<div id="a" class="content">
Content A
</div>
<div id="b" class="content hidden">
Content B
</div>
<div id="c" class="content hidden">
Content C
</div>
</div>
<!-- ... -->
Instant. It really actually positively just works. Amazing. I'm convinced.
Summary
I haven't tried the native Svelte integration yet, but if it works like the rest of it, this will probably blow my mind even more. The TypeScript support works with no additional config or even an extra package. If your IDE does the extra type checking Snowpack mentions, you don't even need that.
Zero-config, blasting off at what feels like near light-speed, TypeScript out of the box. I mean, what's not to love?
About Brunch
Here's the article I mentioned above:
🕵️Something new every now and then: Trying Brunch🍴
Pascal Thormeier ・ Mar 20 '21
I hope you enjoyed reading this article as much as I enjoyed writing it! If so, leave a ❤️ or a 🦄! I write tech articles in my free time and like to drink coffee every once in a while.
If you want to support my efforts, buy me a coffee ☕ or follow me on Twitter 🐦! You can also support me directly via Paypal!
I want to thank Martina who supported me two weeks ago!
Top comments (10)
Heh, recently our webpack (and tailwind) build was getting slow, so we did some research and turned out swapping, configuring is also making a huge difference without boiling the ocean.
Take a look at some of my recent posts to see details (tldr: esbuid-loader, tailwindcss jit, ignoring node_modules in css processing)
I hope one day we wont need build step altogether... :)
Competition usually sparks innovation, so I hope that webpack and the like take some notes of each others progress and improve ever more. I too hope that we don't need those tools in the long run, native TypeScript support by browsers would be an amazing start! :D
And cutting off support for old browsers so that developers can actually focus on using modern tech insted of searching for polyfills and workarounds :)
Oh, how I long for that day! :D Luckily the situation is getting better, slow but steady progress.
Discovered it a while back randomly and fell in love with it. It is so blazing fast.
We made a simple template for creating web packages with it:
pixiumdigital / typescript-package-boilerplate
webpack package with typescript support
Typescript Webpackage Boilerplate
In this boilerplate we have a simple look at a very basic typescript package exported for the web.
We leverage the use of webpack to expose our package to the browser.
Installation
install the dev packages with yarn:
Developement
This will start webpack to compile the library on changes. This will also start snowpack which will update the index.html in test once the library from webpack has been compiled
Build
Publish Package
First login to the npm cli if not already done
You will need to remove the following line in your
package.json
To publish a patch
To publish a minor
To publish a major
Here is the explanatory article:
🔨 Build a web package with typescript! 🔥
Médéric Burlet ・ Nov 27 '20 ・ 3 min read
That's looks very useful! Noted for future projects, thank you so much for sharing :)
I worked with snowpack on a project once. It was a really great experience. I don’t have any new projects to use with it at the moment, but I definitely see myself using it again in the future.
Absolutely agreed, although I usually work with Vue a lot and since Vite seems to operate in about the same execution time ballpark, I don't know when I'll be able to actually use it outside of some playground... But: the tool is nevertheless amazing!
Love the name! ❄️
Snowpack is great, it also supports many transpiled languages such as ReScript. I've used it on a project of mine and worked seamlessly. Webpack's Hell is now far behind us. :D