Skip to content

Releases: fastify/fastify-vite

@fastify/[email protected]

20 Oct 21:21
Compare
Choose a tag to compare

@fastify/[email protected]

16 Oct 06:07
Compare
Choose a tag to compare

The first (usable) alpha release of @fastify/[email protected] 🎉

This release has much to thank for to the couple dozen brave souls actually using @fastify/vue.

Their feedback, ideas and support have been greater than I could ever hope for. This project has come a long way!

Most features in this release have Developer Experience in mind.

Tip

If you're new to @fastify/vue

Make sure to check out Matteo Collina's excellent write-up.

This is not a metaframework, but it might very well be mistaken as one.

The reason it can't really be considered a metaframework is because it relies purely on Fastify, Vite and @fastify/vite. Everything uses @fastify/vite hooks and the application shell is completely transparent and ejectable.

New $app/ smart import prefix

Previously, @fastify/vue used /: as the prefix for its smart imports (virtual modules). This releases also adopts the $app/ prefix adhering to the convention used by SvelteKit. It's mostly an aesthetic addition, with /: remaining available for those who prefer it.

New $app/hooks virtual module

A new $app/hooks virtual module has been added providing convenience wrappers to useRouteContext():

Screenshot 2024-10-14 at 08 47 06

Automated $app/stores

One of my favorite things about @fastify/vue has always been the context.js file. A single file that can define your application's global state as a simple reactive() object, as well as actions that operate on it. In retrospect this file should have been named store.js — the main reason for it to be named context.js is that its exports are automatically collected and made available via useRouteContext(), and if it has a function as its default export, it is executed exactly once both on the server and on the client for every request, mimicking the functionality of Nuxt plugins.

This releases further improves the automation of global state and actions by introducing automated stores, automatically sliced off the main state object. For every property that is an object, @fastify/vue will make it available as an individual store including any methods defined in actions matching the property name.

Screenshot 2024-10-14 at 07 28 13

This dynamic $app/stores virtual module is compiled exactly once at build time.

See client/context.js and client/pages/using-store.vue from the new vue-kitchensink starter template.

Pregenerated preload tags for every route

@fastify/vue will now generate one individual SSR HTML template for each route module, containing pregenerated preload tags for assets loaded within the route module.

Screenshot 2024-10-16 at 01 44 23

This was inspired on the work of Jarle Friestad in vite-plugin-preload. Thanks Jarle!

Conditional client and server imports

Screenshot 2024-10-14 at 09 44 11

No more client/index.js!

This has been in my wishlist for a long time. The Vite project root is no longer required to have the index.js file (the clientModule), which has joined the list of available virtual modules (or smart imports as @fastify/vue calls them). In the vite build call to build the server bundle, just pass /:index.js as the entry point now.

If you're using your client module file to provide additional properties to the server, you can still keep it in your Vite project folder and it will be used. Take note however that its default definition has been updated to:

import { createRoutes } from '@fastify/vue/server'

export default { 
  routes: createRoutes(import('/:routes.js')),  
  create: import('/:create.js'),
  context: import('/:context.js'),
}

The new /:routes.js smart import is now simply the import.meta.glob() call for collecting route modules:

export default import.meta.glob('/pages/**/*.vue')

If you want to a different source directory for your route modules, just provide your own routes.js file. Note that this also eliminates the routing options that were previously available in @fastify/vue's Vite plugin.

New @fastify/vue/server module

Previously, the core createRoutes() function was defined in the /:routes.js smart import. Due to its significance in the setup, it is no longer encouraged to directly modify this function — unless you're contributing to the project of course! The @fastify/vue/server now contains the createRoutes() function, used directly from the /:index.js smart import as seen above.

New @fastify/vue/client module

Previously, the core useRouteContext() hook was made available via the /:core.js virtual module. Since it contains fundamental pieces of the setup, the /:core.js smart import ceased to exist and has moved to @fastify/vue/client at the library level.

The @fastify/vue/client module also provides createBeforeEachHandler() and hydrateRoutes().

These are used internally by the /:create.js and /:mount.js virtual modules, respectively.

Trying it out

Use the vue-base or vue-kitchensink starters as recommended by the documentation.

Miscellaneous

Many thanks to my employer Feature.fm for supporting my work on this project.

You can also support my work by preordering Happy Little Monoliths — an upcoming book covering the Fasstify-Vite stack.

@fastify/[email protected]

13 Oct 22:07
Compare
Choose a tag to compare

This new major alpha release paves the way for the upcoming @fastify/[email protected] and @fastify/[email protected] releases.

It will also be the first @fastify/vite release to support Vite 6. Currently this release still supports Vite 5, but support for Vite 6 is almost done and will be added to subsequent v8.0.0-alpha releases.

Warning

The final v8.0.0 release will oficially deprecate Vite 5 support.

It will stay on the next tag on npm until Vite 6 is released. After that, Vite 5 support will be removed and @fastify/[email protected] and @fastify/[email protected] will require @fastify/vite v6.0.7 (Fastify v4) or v7.0.1 (Fastfiy v5) to run.

Caution

Do not upgrade to this release if you're using @fastify/[email protected] or @fastify/[email protected] or @fastify/[email protected].

This release is intended to support the upcoming @fastify/[email protected] and @fastify/[email protected] releases.

Breaking changes

This release reverses a feature introduced in v6.0.0, namely the Readable support in createHtmlTemplateFunction(). The performance degradation is just too high (up to 20%), and affects the majority of users, who don't really make use of this feature.

In addition, the default definition of createHtmlTemplateFunction() now returns a Promise:

- const indexHtmlTemplate = config.createHtmlTemplateFunction(source)
+ const indexHtmlTemplate = await config.createHtmlTemplateFunction(source)

Revamped HTML template compiler

This releases includes a completely rewritten HTML template compiler:

As mentioned before, it also drops support for Readable streams, requiring you to handle streaming manually, which has become extremely straightforward via Readable.from().

Miscellaneous

Tests are now running in CI and are much faster.

Fastify v5 and Node v22 are now used in development and all examples have been updated to use them.

Biome has been replaced with Oxc for speed1.

  1. Biome is still amazingly fast but Oxc manages to be faster by further skipping a few steps in formatting, which still seems like an acceptable compromise given how fast it is and the fact we don't lose any truly important diagnostics.

@fastify/[email protected]

04 Mar 07:33
Compare
Choose a tag to compare

This release includes an experimental implementation of server actions.

Read all about it here: https://hire.jonasgalvez.com.br/2024/mar/04/server-actions-in-fastify/

@fastify/[email protected]

26 Feb 02:24
Compare
Choose a tag to compare

This contains a patch for a bug some users reported where not all CSS imports would be loaded client-side.

Also peerDependencies has been removed from package.json.

@fastify/[email protected]

19 Feb 08:03
Compare
Choose a tag to compare

This is the sixth major release of @fastify/vite.

It has important changes that required the introduction of a couple of breaking changes, thus the new major release.

Both @fastify/[email protected] and @fastify/[email protected] still require @fastify/vite@5 to run.

Updated versions of these packages will be released soon.

New features

  • Type definitions have been comprehensively expanded, hat off to @Gehbt.

  • The default reply.html() function, returned by createHtmlTemplateFunction(), now always returns a Readable. And any parameter passed to it can also be a Readable. In addition, placeholders now also support the dot notation, and receive app (the Fastify plugin scope), req, reply, client and route as part of their default context in the default createRouteHandler() definition . For the following index.html:

    <head><!-- req.head --></head>

    The following reply.html() call should work:

     import { Readable } from 'node:stream'
    
     async function * head () {
        yield '<title>Streaming title</title>'
     }
    
     req.head = Redable.from(head())
     reply.html({ req })
  • If no createRenderFunction function is provided, createRouteHandler() will now by default call the route module's default export, as follows:

    createRouteHandler({ client, route }, scope, config) {
      // ...
      return async (req, reply) => {
        const page = await route.default({ app: scope, req, reply })
        return reply.html({
          app: scope,
          req,
          reply,
          route,
          client,
          element: page,
        })
      }
  • The plugin's config object now has two injected readonly properties:

    • hasRenderFunction indicates whether or createRenderFunction was provided.
    • ssrManifest contains the parsed JSON from the ssr-manifest.json file (production only).

Breaking changes

  • The default call signature of reply.render() in createRouteHandler() changed as follows:

    - const page = await reply.render(scope, req, reply)
    - return reply.html(page)
    + const page = await reply.render({
    +   app: scope,
    +   req,
    +   reply,
    +   route,
    +   client, 
    +  })
  • The default call signature of createRouteHandler() and createErrorHandler() have changed as follows:

    - createRouteHandler (client, scope, config) {
    + createRouteHandler({ client, route }, scope, config) {
    - createErrorHandler (client, scope, config) {
    + createErrorHandler({ client, route }, scope, config) {

In both cases, route is a reference to the route module, and client is a reference to the client module.

Fixes

Many thanks to the contributors!

Miscellaneous

Node v20+ is now used in development.

Vitest has been replaced with Node's native test runner.

ESLint has been replaced with Biome for speed1.

  1. Biome is lacking a formatting option that makes it not fully StandardJS-compliant, but it's an acceptable compromise since it was possible to remove several ESLint plugins from the dependencies and still have superior performance.

@fastify/[email protected]

19 Feb 23:49
Compare
Choose a tag to compare

This release contains a small addition allowingdecorateReply and decorateRequest to be exported from route modules, for purposes of preinitialisation of properties added to either object (and avoiding changing the V8 shape of them in runtime).

export const decorateRequest = ['data']

export function preHandler (req, _, done) {
  req.data = {}
  done()
}

export default () => (
  <>
    <h1>Page</h1>
  </>
)

Note that all of Fastify's route-level hooks can be already exported from route modules, as demonstrated above. This feature is provided by default in @fastify/vite, namely, in its default definition for the createRoute() hook.

@fastify/[email protected]

19 Feb 08:14
Compare
Choose a tag to compare

This is the first release for an experimental HTMX renderer for @fastify/vite, with JSX support provided via @kitajs/html.

This is currently the fastest SSR option for @fastify/vite.

Documentation and benchmarks will be added soon. For now here's a rundown of its features:

  • All route modules server-side rendered only.
    • But if they import *.css, *.svg and *.client.js files, these are also loaded on the client.
    • Head tags with prefetch tags are precomputed at boot time, leveraging Vite's ssr-manifest.json.
  • Route modules automatically loaded from /views folder, need to export path.
  • Route layout modules automatically loaded from /layouts folder.
  • Fragment route modules automatically loaded from /fragments folder.
    • Fragments are just endpoints that return raw HTML, without the <html> and <body> shells.
  • Tailwind and CSS Nesting enabled out of the box.

Play with the example in starters/htmx-kitchensink to learn more.

Screen Shot 2024-02-19 at 05 14 01