Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add js.Batch #12626

Open
bep opened this issue Jun 27, 2024 · 9 comments · May be fixed by #12641
Open

Add js.Batch #12626

bep opened this issue Jun 27, 2024 · 9 comments · May be fixed by #12641
Assignees
Labels
Milestone

Comments

@bep
Copy link
Member

bep commented Jun 27, 2024

Naming is hard, but the entry point to this new feature is js.Bundle. We already have js.Build, which also allow bundling ... Yea, we should look for a different name.

There are some aspects to this new feature:

  • Multiple main entry points (e.g. home.js, mysection.js).
  • Multiple component and component instances with a user provided callback script (e.g. JSX components from shortcodes).
  • Bundling and code splitting (chunking). This is a big thing if you have many small scripts that shares some common and big dependencies (e.g. React).

Like with js.Build and others, these bundles are built in parallel during render, but for this we need some improved synchronisation mechanisms.

In the examples below, all the methods prefixed Use* acquire a lock and needs to be closed when done. This would probably be too hard to teach the common Hugo user, so I have made it so if you use as the argument to with, it will automatically be closed when with closes.

// Naming convention used in the callback script set below.
// One use case: Render React components (e.g. JSX scripts) added in e.g. shortcodes.
<div "batch1-instance1"></div>


# Get or create a new bundle with the given ID and store it in the given store/scope.
$bundle := js.Bundle "mybundle" hugo.Store # or site.Store, $.Store (page), newScratch

// Will get or create a new entry point script with the given ID.
//  Think about this as logically-independent groups of code, e.g. a main thread and a worker thread, or code for
// the editor page or a settings page.
with $bundle.UseScriptOne ID
	.SetResource
	.SetInstance # Params

// Get or create a new script batcher.
// This allows code to be batched and passed to a user provided call back.
// One use case: Render React components (e.g. JSX scripts) added in e.g. shortcodes.
with $bundle.UseScriptMany ID
	.SetCallback
	with .UseItem ID
		.SetResource
		.AddInstance # Params

$m := $bundle.Build

with index $m "main"
   <src .RelPermalink>

with index $m "batch1"
   <src .RelPermalink>
@bep bep added the Proposal label Jun 27, 2024
@bep bep added this to the v0.129.0 milestone Jun 27, 2024
@bep bep self-assigned this Jun 27, 2024
bep added a commit to bep/hugo that referenced this issue Jun 30, 2024
bep added a commit to bep/hugo that referenced this issue Jul 2, 2024
@bep bep changed the title Add js.Batch Add js.Bundle Jul 4, 2024
bep added a commit to bep/hugo that referenced this issue Jul 5, 2024
bep added a commit to bep/hugo that referenced this issue Jul 5, 2024
@bep bep linked a pull request Jul 5, 2024 that will close this issue
bep added a commit to bep/hugo that referenced this issue Jul 5, 2024
bep added a commit to bep/hugo that referenced this issue Jul 5, 2024
bep added a commit to bep/hugo that referenced this issue Jul 6, 2024
@bep bep modified the milestones: v0.129.0, v0.131.0 Jul 22, 2024
@bep bep modified the milestones: v0.131.0, v0.133.0 Aug 9, 2024
@cmahnke
Copy link

cmahnke commented Aug 21, 2024

Naming it Bundle might imply that this also addresses #8411 ? 😉

@bep
Copy link
Member Author

bep commented Aug 22, 2024

@cmahnke do you have better name?

@cmahnke
Copy link

cmahnke commented Aug 22, 2024

Not really, my point is that Bundle might imply more functionality for the end user: Next to the mentioned CSS handling esbuild plugins might also be useful.

My suggestion would be not to use too common nomenclature from the context (as this may imply functionality) or if that can't be avoided, at least not to use a verb.
How about Librarize? But I suspect this is't a proper English word.

@bep
Copy link
Member Author

bep commented Aug 22, 2024

@cmahnke The scope of this issue is clearly defined; this is something that I want to do. Scoping it to something that I 1. Want to do and 2. Something that has a limited/possible scope means that it might get done. Pulling in every other remotely related thing isn't moving this particular issue forward, even if I can sympathise with your motivation.

@bep
Copy link
Member Author

bep commented Aug 22, 2024

As to naming:

  • js.Build = 1 entry point
  • js.Build = multiple entry points

Both should support the same setting/CSS handling/plugins.

I think that should be possible to document and clear enough.

As to plugins; I created a feedback thread relevant to this after v0.132.0 (added support for QuickJS via Wasi/WASM). where I have gotten close to zero relevant feedback, so I'm guessing that's not a priority among the common Hugo user.

@bep bep modified the milestones: v0.133.0, Unscheduled Aug 29, 2024
@doompadee
Copy link

@bep You misspelled the second term?

As to naming:

  • js.Build = 1 entry point
  • js.Buildjs.Bundle = multiple entry points

Personally, I would have expected that js.Build could be extended with some new configuration capabilities, but it seems that the ergonomics are vastly different which makes a separate command reasonable (maybe long term js.Build could be phased out?). Besides, any effort here is more than welcome and clear documentation should certainly be enough to make this much wanted functionality accessible to users.

I would be keen to learn more about this new building mechanism soon and hope your experiments fare well. I'd love to be able to easily bundle Alpine.js data objects individually.

bep added a commit to bep/hugo that referenced this issue Sep 12, 2024
@bep
Copy link
Member Author

bep commented Sep 12, 2024

@doompadee well, whatever we call it, the APIs are wastly different, so trying to force them into one function would create lots of extra work, and also I suspect would be mucho confusing for the end user. All of the esbuild related options should, of course, be shared/the same.

{{ $bundle := (js.Bundle "mybundle" .Store) }}

Looking at that extract of the integration test now, we could possibly also call it js.Builder -- which I guess it also is, and that would drop the "bundle" word, which I guess js.Build is also doing.

So:

{{ $jsBuilder := (js.Builder "mybundle" site.Store) }}
// ... add stuff in this (home.html) and in single.html etc. templates.
// Then build and include the script(s).
{{ with (templates.Defer (dict "data" (dict "js" $jsBuilder)) }}
   {{ with .Build.Scripts }}
      {{ with index . "alpinejs1" }}
             <script src="{{ .RelPermalink }}">
      {{ end }}
   {{ end }}
{{ end }}

@bep bep changed the title Add js.Bundle Add js.Builder Sep 12, 2024
@doompadee
Copy link

All of the esbuild related options should, of course, be shared/the same.

That's why I was thinking at some point in the (distant) future, the older js.Build might get removed in favor of the newer, more powerful solution.

js.Builder is probably a good choice as well. The only downside might be that both names are nearly identical , but then both do nearly the same, so still fitting.

Having thought about the naming, why not use the name of the underlying tool? We already have js.Babel. Why not js.Esbuild as well? Could be advantageous if users recognize the names and you might want/need to add other tools in the future.

@bep
Copy link
Member Author

bep commented Sep 12, 2024

That's why I was thinking at some point in the (distant) future

Well, as we spent the entire "2024 Hugo developer budget" already, the distant future may very well be when this particular issue gets resolved.

bep added a commit to bep/hugo that referenced this issue Sep 18, 2024
bep added a commit to bep/hugo that referenced this issue Sep 24, 2024
bep added a commit to bep/hugo that referenced this issue Sep 28, 2024
@bep bep modified the milestones: v0.135.0, v0.136.0 Sep 28, 2024
bep added a commit to bep/hugo that referenced this issue Oct 12, 2024
bep added a commit to bep/hugo that referenced this issue Oct 13, 2024
bep added a commit to bep/hugo that referenced this issue Oct 13, 2024
bep added a commit to bep/hugo that referenced this issue Oct 18, 2024
bep added a commit to bep/hugo that referenced this issue Oct 19, 2024
bep added a commit to bep/hugo that referenced this issue Oct 21, 2024
bep added a commit to bep/hugo that referenced this issue Oct 22, 2024
bep added a commit to bep/hugo that referenced this issue Oct 22, 2024
bep added a commit to bep/hugo that referenced this issue Oct 22, 2024
@bep bep modified the milestones: v0.136.0, v0.137.0, v0.138.0 Oct 23, 2024
bep added a commit to bep/hugo that referenced this issue Oct 24, 2024
bep added a commit to bep/hugo that referenced this issue Oct 27, 2024
@bep bep modified the milestones: v0.137.0, v0.138.0 Oct 30, 2024
bep added a commit to bep/hugo that referenced this issue Nov 6, 2024
@bep bep modified the milestones: v0.138.0, v0.139.0 Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants