Vue 3 has been with us for more than two years now. Until now it was missing one crucial component – Server Side Rendering. Fortunately, this week we finally got Nuxt 3. What took the developers so long? Does this release bring some innovative features? You will read about all this in today’s Frontend Weekly.
1. Nuxt 3
I think if you were to show Frontend Weeklys from the past few months to some Artificial Intelligence, it would conclude that this is a newsletter about Server Side Rendering. I can’t help the fact that the whole world has gone crazy about this lately. This week we are once again adding fuel to the fire because after more than two years of development, Nuxt 3 has been released. This means that Vue 3 can finally be rendered on the server! Why did we have to wait so long for Nuxt 3? Does Nuxt surpass Next.js despite a smaller budget? I will try to answer these questions in today’s review.
It’s no secret that Nuxt initially took inspiration from Next.js. As you may have guessed, this means that routing in Nuxt is based on a directory structure. In the latest version of the framework, not much changes. Path matching works the same as it used to. So at our disposal, we have the pages
directory, where we place our pages, components
, where we place shared components, and layouts
where we place “wrappers” for our pages (yes, Nuxt 2 supported layouts
long before Next.js).
If you try to read Nuxt 3 documentation, you will notice the complete lack of JavaScript imports. As it turns out, this is neither an intentional simplification nor an oversight from documentation authors. Nuxt 3 uses the unjs/unimport
library, which is responsible for automatically generating imports. If a name resolution conflict occurs, an error will be thrown. You can get rid of it by manually defining the import.
<script setup>
/* ref() and computed() are auto-imported */
const count = ref(1)
const double = computed(() => count.value * 2)
</script>
Another new feature is native support for “Super Markdown”. What do I mean by that? In Nuxt 3 you can use your Vue components inside Markdown files. What is important, we can parameterize these components, and even pass rendered Markdown snippets to them. Functionalities like this may not turn the world upside down, but they will certainly be appreciated by all blog and documentation authors.
// pages/[...slug].vue
<template>
<main>
<ContentDoc />
</main>
</template>
// content/index.md
# Nuxt Content Hello World
[About](/about)
::app-button{variant="filled"}
Hello **World**!
::
Looking through the directory structure of Nuxt 3 (by the way, the documentation is really good and clear) I come across one more novelty – the server
directory. In there, you can define your REST API. As with the pages
directory, the location of the file defines the endpoint path. What is interesting, Nuxt will automatically generate the appropriate types for you. When you call your endpoint with useFetch
function it will be type-safe by default.
// server/routes/hello.ts
export default defineEventHandler(() => 'Hello World!');
// pages/index.vue
<script setup>
const response = useFetch('/hello'); // response will automatically have string type
</script>
The last big feature is alternative rendering modes. By default, the framework renders pages on the server side. With some configuration we can change this behavior. Among the available options are basic ones like static page generation (SPG) or client-side rendering (CSR), but also more advanced options such as incremental server rendering (ISR) and incremental sever generation (ISG).
OK, all the new features look interesting, but what took the developers so long as two years? Why didn’t they follow a more incremental strategy that would have enabled server-side rendering of Vue without all those “whiz-bangs”? At the time of Vue 3 release, the team behind Nuxt made a very important architectural decision – to spend invaluable time making Nuxt compatible with Vue 3, or to seize the opportunity to rebuild the entire framework. The choice fell on the second option as it enabled implementation of many features that would be hard to achieve otherwise. The result of the rewrite is called Nitro.
Nitro is a JavaScript server that can be run on any environment. This means that it can run in both Node.js and Deno, but also in all sorts of cloud environments with a special focus on Edge Functions. By implication, this means that Nuxt 3 can be run as close to the client as possible. In fact, all the functionalities you have read about above would not have been achievable without Nitro.
Was the strategy employed the right one? Vue 3 lost a lot from the lack of a good Server Side Rendering library for the first two years of its life. On the other hand, Vue 3 was full of breaking changes. Who knows whether creating Nuxt 2 compatible with Vue 3 would have been possible at all, and if so, whether it would not have taken a comparable amount of time.
Sources
https://nuxt.com/v3
https://www.youtube.com/watch?v=cSjlefuZlaI
https://www.youtube.com/watch?v=noq-ZHTD2Cg
https://nuxt.com/docs/guide/concepts/
https://nitro.unjs.io/
https://www.vuemastery.com/blog/new-nuxt-3-feature-incremental-static-generation/
2. Nx gets $8.5m
Nrwl, the company behind Nx, was founded by two developers from the Angular team. Initially, it operated like a typical consulting company helping large corporations build Angular applications. Over time, the company started working on a tool to make working with Angular mono-repo easier. Company founders had just the right experience for the job. At Google, they had a chance to work with large monorepos.
Nx worked so well that two developers decided to leave the consulting business and focus on Nx development. Over the years, Nx stopped being a tool dedicated to Angular and became a tool developed with JavaScript in mind. Developers gradually came to love Nx and it is now the most popular tool in its category.
An interesting episode in the recent history of Nx is the takeover of Lerna – for years the most popular monorepo management tool. Unfortunately, Lerna have been abandoned by its maintainer about two years ago. In the short term, the company intended to focus on fixing critical bugs and vulnerabilities. The long-term plan was to introduce functionality that would enable seamless integration between Lerna and Nx. As time has shown, the promises have been realized. A few weeks ago we saw the first major version of Lerna. All the big features, such as caching or dependency configuration were built on top of Nx.
At this point, we can summarize the state of JavaScript monorepo tools. In the hands of the well-funded Nrwl ($8.5 million) are the two most popular tools in the form of Nx
and lerna
. In the hands of the even better-funded Vercel ($315 million) is the Turborepo
tool. For the time being, it is still a little short of the competition, but it is still rapidly developing. It’s hard to predict which way the balance will turn in the future.
Sources
https://techcrunch.com/2022/11/17/with-8-6m-in-seed-funding-nx-wants-to-take-monorepos-mainstream/
3. Arrow.js – days since new JS framework: 0
The times when new frameworks and libraries sprang up like mushrooms after the rain are thankfully behind us. Still, from time to time some framework or library will spark interest in our dull and settled community. Such thing happened last week, when everyone started talking about Arrow.js.
The new framework (or library?) is distinguished from everything we have now primarily by its simplicity and its bet on native JavaScript functionality. Just take a look at the snippet below:
import { reactive, html } from '@arrow-js/core'
const data = reactive({
clicks: 0
});
html`
<button @click="${() => data.clicks++}">
Fired ${() => data.clicks} arrows
</button>
`
The reactive
method, using Proxies, creates an object in which changes can be observed using the .$on() method. Tagged Templates were used for rendering. The magic html
prefix (it’s actually a quite simple function) subscribes to all the changes in reactive
and automatically updates innerHTML
.
As shocking as it may seem, that’s all Arrow.js offers. Will it win with React, Vue, Angular or at least Svelte? The chances of that are rather low, if not zero. Nevertheless, it seems to be an interesting tool. If you have a spare 15 minutes, I recommend diving into the documentation. Even if you are not interested in yet another framework, it’s still good to understand how a full-fledged framework can work with less than a thousand lines of code.
Sources
4. It’s time to cast your vote in State of JS 2022
We are slowly approaching that time of the year when our reports will be mainly devoted to all kinds of summaries and statistics. But before that happens, we all need to fill out a bunch of surveys that will provide data for these reports. I wouldn’t ask you to fill out a random survey if you couldn’t take something from it for yourself. As with State of CSS, State of JS is the best place to catch up on libraries and native functionalities that has passed off your radar over the past few years. At the end of the entire survey, you’ll get a percentage score and a list of links to quickly fill in the gaps.