gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
76.16k stars 7.54k forks source link

Further ideas on how WASI/Wasm modules could be used in Hugo #12737

Open bep opened 3 months ago

bep commented 3 months ago

Placeholder.

aarol commented 2 months ago

I'm very happy that Wasm/WASI support has landed in Hugo. Nice work!

I've been using Hugo to build my website for a while and I've noticed that the syntax highlighting provided by Chroma hasn't been as nice as what other highlighters like Syntect or Shiki can produce. I wonder if there could be a way to have another syntax highlighter that uses Syntect/Shiki via Wasm?

One thing to note is that Syntect especially has a long warmup time when loading stylesheets (around 100-200ms last time I tried) but is very fast once initialized. It would be good to have a way for programs to serve more than one request.

As for extending the Wasm support in Hugo, I think the natural choice would be to have some kind of a plugin/extension system. I think Zed has the most advanced WASM plugin system of all, since it uses the WIT format to define an interface for extensions and exposes the API as a Rust crate.

imfing commented 1 month ago

I think the natural choice would be to have some kind of a plugin/extension system

I was thinking of something similar to use wasm as a "plugin" or "function" that can be hooked into the templating system.

A starting point could be supporting using a custom wasm file for string-to-string transformations, which we could easily hook into things like safeHTML or unmarshal.

Often the times I found it tedious to implement things such as splitting a page into different chunks or parsing a Jupyter file which could be more straightforward in a higher-level languages like JavaScript or Go.

potential design for the primitive:

wasm.Transform PATH INPUT [OPTIONS]
transformWasm []byte := content.ReadFile(path)

type TransformInput struct {
    Input   string      `json:"input"`
    Options interface{} `json:"options"`
}

As a module author or end user, I could just define things in JavaScript, similar to the greet.js

const transform = function (input, options) {
  // custom data transformation, e.g.
  return input.toUpperCase()
};

This script could be compiled to uppercase.wasm and included with the module or website. Then, using it in a partial would be straightforward:

{{ $output := wasm.Transform "/partials/wasm/uppercase.wasm" $input "" }}

This could potentially address requests for "custom functions"

bep commented 1 month ago

@imfing thanks for the input. In my head, any use of wasm in Hugo needs to be relatively coarse grained -- there is a relatively big start up (and memory) cost so you need to think of each wasm file as "a server". So uppercase.wasm may not be the best fit.

Thinking out loud here of some examples that I would find useful:

If we then allow people to include their wasm files/configurations as part of Hugo's module mount setup.