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

[IDEA] Testing Hugo Modules (as a PoC) #165

Closed
mnordhaus opened this issue Jan 19, 2025 · 27 comments
Closed

[IDEA] Testing Hugo Modules (as a PoC) #165

mnordhaus opened this issue Jan 19, 2025 · 27 comments
Assignees
Labels
enhancement New feature or request

Comments

@mnordhaus
Copy link
Collaborator

mnordhaus commented Jan 19, 2025

Hugo Modules (https://gohugo.io/hugo-modules/) allow to manage project dependencies in a lightweight way. Such that the Theme can be loaded as a dependency instead of checking it out and copying it into a themes folder. Furthermore Hugo Modules allow to divide the theme itself into Components.
For example the Bootstrap code could go into a separate module or extensions to the theme could be provided in manageable way.

Through a thoroughly thought through concept Hugo Modules would provide better maintainability through the divide and conquer principle. Also integrating the theme as a Hugo Module solves licensing issues. Especially when the content should be provided under a different license then MIT (e.g. Creative Commons)

As a first step I suggest to provide a small showcase or proof of concept. Using the theme as a Module and also externalize the Bootstrap dependencies into a separate Module

Alternatively Git-Submodules are providing similar capabilities. Also using build tool and a package manager like Webpack or npm is an option. But Hugo Modules are built in and work without any other dependencies.

However the PoC should also show that utilizing Hugo Modules would not block other alternatives.

Questions the PoC should answer:

  1. How is it possible to use the Theme as a Hugo Module
  2. Extract the Bootstrap dependencies as a Module
  3. Show that it is still possible to use Git-Submodules or similar ways to manage dependencies

After that this ticket should be a foundation on how to go forward with Hugo Modules

@zetxek If you like you may assign this ticket to me.

@mnordhaus mnordhaus added the enhancement New feature or request label Jan 19, 2025
@mnordhaus
Copy link
Collaborator Author

For reference see: #158

@mnordhaus
Copy link
Collaborator Author

This is the way the Hugo Project itself integrates Bootstrap: https://github.com/gohugoio/hugo-mod-bootstrap-scss/tree/main it includes a sample site.

@mnordhaus
Copy link
Collaborator Author

@zetxek
Copy link
Owner

zetxek commented Jan 19, 2025

How is it possible to use the Theme as a Hugo Module

We can use the demo repo (https://github.com/zetxek/adritian-demo) as a testing ground for the PoC, once there's some changes.

This could very much be a new branch/tag, either V1.5, or 2.0- that way we can test the integration before releasing.

@dcorto
Copy link
Collaborator

dcorto commented Jan 19, 2025

How is it possible to use the Theme as a Hugo Module

We can use the demo repo (https://github.com/zetxek/adritian-demo) as a testing ground for the PoC, once there's some changes.

This could very much be a new branch/tag, either V1.5, or 2.0- that way we can test the integration before releasing.

The v2.x relese tag will be a great idea, because i think this changes will require a little work :P

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

@dcorto @mnordhaus I've gone ahead and created a new branch (https://github.com/zetxek/adritian-free-hugo-theme/tree/2.x-hugo-modules), and invited you as collaborators - so we can build it in the same branch (instead of having to make a big PR once the change is done, we can iterate in smaller PRs in this repo directly :-))

@dcorto
Copy link
Collaborator

dcorto commented Jan 20, 2025

@zetxek 🔝

@mnordhaus
Copy link
Collaborator Author

Thank you @zetxek I assume tho that we need a fork to test this feature in general. But for the detail work a branch is the best way IMHO too.

@mnordhaus
Copy link
Collaborator Author

I have forked the demo-repository already and hope to find some time to make the first break through this week.

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

Why would we need a fork? 🤔 - if all the changes can be made from a separate branch (if I get the idea right).

For now, I've done a couple of things (as very basic starters).

In this repo:

  1. created the branch in the theme repo (https://github.com/zetxek/adritian-free-hugo-theme/tree/2.x-hugo-modules)
  2. committed a very basic attempt to turn the theme into a module (no further changes, such as extracting bootstrap)
  3. created a new tag (https://github.com/zetxek/adritian-free-hugo-theme/releases/tag/v2.0.0-alpha.1) that can be used to import the module

In the demo repo (https://github.com/zetxek/adritian-demo)

  1. created a new branch (https://github.com/zetxek/adritian-demo/tree/demo-2.x-hugo-module)
  2. committed a basic change from git submodule to hugo moduleI intend to setup a first version of adritian-demo that imports the theme (from this repo) by using the alpha tag

My idea is to setup a demo that imports the theme as module - and then take it from there (ie: if there are errors, handling them, etc)

@mnordhaus
Copy link
Collaborator Author

mnordhaus commented Jan 20, 2025

I doubt that we can use releases with a branch: https://gohugo.io/hugo-modules/use-modules/#get-a-specific-version

require ( github.com/<username>/<repo-name>/<path> version )

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

I also think we can't also use branches - but tags should be ok :)

https://discourse.gohugo.io/t/how-to-add-a-theme-using-modules-for-beginners/20665/4

(that's why I created the tag too, I don't think the branch would suffice)

The idea with the tag is to have a future release tag (v2.0.0-alpha.1, that will roll as we progress, like v2.0.0-alpha.2, etc)

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

Oh - it seems that branches would also be ok; just not in the hugo.toml config file:

https://discourse.gohugo.io/t/specify-branch-with-modules/23977/4

Yes, but you cannot specify the branch in config.toml, you need to do it either
in go.mod
or when “getting” hugo mod get -u github.com/some/repo@someref
I can add to that that it’s really any Git reference (commit, branch, tag), not just branches.

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

For the proof of concept, I've tried via a tag and that didn't work. Via commit hash it did (but it picked the wrong version/tag 🤔 - it got the unpublished version as v1.4.27 - as a newer version of the current one, v1.4.26 https://github.com/zetxek/adritian-free-hugo-theme/releases/tag/v1.4.26)

➜  new-site hugo mod get -u github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1

go: github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1: invalid version: module contains a go.mod file, so module path must match major version ("github.com/zetxek/adritian-free-hugo-theme/v2")
Error: failed to get ["-u" "github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1"]: failed to execute 'go [get -u github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1]': failed to execute binary "go" with args [get -u github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1]: go: github.com/zetxek/adritian-free-hugo-theme@v2.0.0-alpha.1: invalid version: module contains a go.mod file, so module path must match major version ("github.com/zetxek/adritian-free-hugo-theme/v2")
 *errors.errorString
➜  new-site
➜  new-site hugo mod get -u github.com/zetxek/adritian-free-hugo-theme@25d7837
go: downloading github.com/zetxek/adritian-free-hugo-theme v1.4.27-0.20250120122236-25d7837ed4e8
go: added github.com/zetxek/adritian-free-hugo-theme v1.4.27-0.20250120122236-25d7837ed4e8

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

As first step, I've been able to render something localy - although in the vercel preview it fails:

zetxek/adritian-demo#144

Now I got to a "theme" error :)

➜  adritian-demo git:(demo-2.x-hugo-module) ✗ hugo --gc
WARN  Failed to read module config for "github.com/zetxek/adritian-free-hugo-theme" in "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120122236-25d7837ed4e8/theme.toml": "_stream.toml:1:1": unmarshal failed: toml: key min_version is already defined
Start building sites …
hugo v0.140.0+extended+withdeploy darwin/arm64 BuildDate=2024-12-17T14:20:55Z VendorInfo=brew

ERROR TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120122236-25d7837ed4e8/assets/scss/bootstrap/_mixins.scss:6:1": File to import not found or unreadable: vendor/rfs.
Total in 230 ms
Error: error building site: TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120122236-25d7837ed4e8/assets/scss/bootstrap/_mixins.scss:6:1": File to import not found or unreadable: vendor/rfs.

It seems to come from

So maybe the next step is to actually import bootstrap as a module too?

@zetxek
Copy link
Owner

zetxek commented Jan 20, 2025

Something that can be useful @mnordhaus @dcorto.
For local development, it seems that using

➜  adritian-free-hugo-theme git:(2.x-hugo-modules) ✗ hugo server --source exampleSite --themesDir ../..
WARN  Failed to read module config for "adritian-free-hugo-theme" in "/Users/adrianmorenopena/Projects/adritian-free-hugo-theme/theme.toml": "_stream.toml:1:1": unmarshal failed: toml: key min_version is already defined
Watching for changes in /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/{archetypes,assets,data,exampleSite,i18n,layouts,package.json,static}
Watching for config changes in /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/exampleSite/hugo.toml
Start building sites …
hugo v0.141.0+extended+withdeploy darwin/arm64 BuildDate=2025-01-16T13:11:18Z VendorInfo=brew

ERROR TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Projects/adritian-free-hugo-theme/assets/scss/adritian.scss:1:1": File to import not found or unreadable: bootstrap/bootstrap.
Built in 79 ms
Error: error building site: TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Projects/adritian-free-hugo-theme/assets/scss/adritian.scss:1:1": File to import not found or unreadable: bootstrap/bootstrap.

gives the same "experience" as if the theme was imported - as it gives me me the same error as the demoSite:

➜  adritian-demo git:(demo-2.x-hugo-module) ✗ hugo serve
WARN  Failed to read module config for "github.com/zetxek/adritian-free-hugo-theme" in "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120151805-6c3d6284df03/theme.toml": "_stream.toml:1:1": unmarshal failed: toml: key min_version is already defined
Watching for changes in /Users/adrianmorenopena/Projects/adritian-demo/{archetypes,assets,content,layouts,package.json,postcss.config.js,static}
Watching for config changes in /Users/adrianmorenopena/Projects/adritian-demo/hugo.toml, /Users/adrianmorenopena/Projects/adritian-demo/go.mod
Start building sites …
hugo v0.141.0+extended+withdeploy darwin/arm64 BuildDate=2025-01-16T13:11:18Z VendorInfo=brew

ERROR TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120151805-6c3d6284df03/assets/scss/adritian.scss:1:1": File to import not found or unreadable: bootstrap/bootstrap.
Built in 86 ms
Error: error building site: TOCSS: failed to transform "/scss/adritian.scss" (text/x-scss): "/Users/adrianmorenopena/Library/Caches/hugo_cache/modules/filecache/modules/pkg/mod/github.com/zetxek/adritian-free-hugo-theme@v1.4.27-0.20250120151805-6c3d6284df03/assets/scss/adritian.scss:1:1": File to import not found or unreadable: bootstrap/bootstrap.

It seems that the fix/change needed now is about being able to import bootstrap in the scss.
I tried with https://github.com/gohugoio/hugo-mod-bootstrap-scss?tab=readme-ov-file#scss - but it's not working yet.

@dcorto
Copy link
Collaborator

dcorto commented Jan 21, 2025

WARN Failed to read module config for "adritian-free-hugo-theme" in "/Users/adrianmorenopena/Projects/adritian-free-hugo-theme/theme.toml": "_stream.toml:1:1": unmarshal failed: toml: key min_version is already defined

@zetxek that error is because in the file there is twice the "min_version" key defined :) Lines 10 and 21 of the file.

Image

And i don't have idea about the scss error at this moment :(

I'm looking along the day if i found something ;)

@zetxek
Copy link
Owner

zetxek commented Jan 21, 2025

WARN Failed to read module config for "adritian-free-hugo-theme" in "/Users/adrianmorenopena/Projects/adritian-free-hugo-theme/theme.toml": "_stream.toml:1:1": unmarshal failed: toml: key min_version is already defined

@zetxek that error is because in the file there is twice the "min_version" key defined :) Lines 10 and 21 of the file.

True! Fixed in a1b40fd, one error down! 👨‍🦯

And i don't have idea about the scss error at this moment :(

I'm looking along the day if i found something ;)

I think that it's related with how the assets are mounted.
What I've done is that I've added a reference to the hugo module of bootstrap: https://github.com/gohugoio/hugo-mod-bootstrap-scss

What this module does is that it exposes the (non-hugo-module) bootstrap repo, as mounted in https://github.com/gohugoio/hugo-mod-bootstrap-scss/blob/main/go.mod#L7

Given that - the import should be bootstrap/bootstrap as in the exampleSite of the hugo module:

https://github.com/gohugoio/hugo-mod-bootstrap-scss/blob/main/exampleSite/assets/scss/styles.scss
will import indirectly
https://github.com/twbs/bootstrap/blob/main/scss/bootstrap.scss

Now, the import I'm trying to make is not working, neither with bootstrap/bootstrap, bootstrap, bootstrap.scss`... so I'm thinking that it's a problem with asset mounting.

🤿 At least that's my last thought, let's see if with some diving I can do now I can figure something! (metaphor inspired for sure by my holiday status 😆)

@zetxek
Copy link
Owner

zetxek commented Jan 21, 2025

It doesn't look like progress...

Image

But I think it's a bit of it.
With 0fa954c, these are the logs:

➜  adritian-free-hugo-theme git:(2.x-hugo-modules) ✗ hugo server --source exampleSite --themesDir ../..
Watching for changes in /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/{assets,exampleSite,package.json}
Watching for config changes in /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/exampleSite/hugo.toml, /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/config.toml, /Users/adrianmorenopena/Projects/adritian-free-hugo-theme/exampleSite/go.mod
Start building sites …
hugo v0.141.0+extended+withdeploy darwin/arm64 BuildDate=2025-01-16T13:11:18Z VendorInfo=brew

WARN  found no layout file for "html" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "page": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

                   | EN | ES | FR
-------------------+----+----+-----
  Pages            | 12 |  6 |  5
  Paginator pages  |  0 |  0 |  0
  Non-page files   |  0 |  0 |  0
  Static files     |  1 |  1 |  1
  Processed images |  0 |  0 |  0
  Aliases          |  1 |  0 |  0
  Cleaned          |  0 |  0 |  0

Built in 27 ms
Environment: "development"
Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Basically: the theme renders now. But the sass file is not processed - therefore, there's no styling at all.
This pointed me a bit in the direction gohugoio/hugo-mod-bootstrap-scss#18 (which is asset-mounting related).

@dcorto
Copy link
Collaborator

dcorto commented Jan 21, 2025

Huge step forward! 👏

@zetxek
Copy link
Owner

zetxek commented Jan 22, 2025

Eureka! 🍎

Image

I have looked at the config of one of the themes recommended by @mnordhaus:
https://github.com/Hugolify/hugolify-theme/blob/main/hugo.yaml

And in dff5732 made a change that:

  1. solves the errors we had:
WARN  found no layout file for "html" for kind "section": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "page": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "home": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "taxonomy": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN  found no layout file for "html" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
  1. Renders the site properly!

Note that the codebase of bootstrap is fully deleted from the theme - so it's completely modularized.

@dcorto
Copy link
Collaborator

dcorto commented Jan 22, 2025

Bravo @zetxek and @mnordhaus 👏

@mnordhaus
Copy link
Collaborator Author

Wow! If tickets assigned to me would solve itself like that on my job ... huge thanks for pushing this forward so quickly. I had a lot on my desk the last few days and got sick on top of it. I promise to read through all the post and I have seen the Pull Request already and give my thoughts to tomorrow.

@mnordhaus
Copy link
Collaborator Author

So I am also all in for keeping Bootstrap within the theme for now for two reasons. First rather do one step at a time and second but more importantly I feel that there is also room for improvement on how Bootstrap is integrated in general. I'll dive into that separately.

I agree also on using modules for extensions like search etc. (I like to add a search to my site eventually).

Modules seem to have some advantages over git-submodules tho:

  1. You simply just need Hugo nothing else (no dependencies to git)
  2. You can deeply specify where you want to copy certain files.
module:
  imports:
   - path: github.com/twbs/icons
     mounts:
     - source: icons
       target: assets/icon
  1. It is maybe easier to configure then submodules
  2. It might be faster in terms of build times.
  3. It looks to me that Modules are already the defacto standard.

In general I think we need to view this issue from three angles

  1. User Experience (UX)

A user is here a technical minded but likes to have an easy start. However Modules could allow adding things like Decap CMS or Sveltia CMS in the future.

  1. Developer Experience (DX)

Keep the theme Maintainable and easy to understand. Splitt the theme into to many (dependent) Modules might make the code unreadable or -> over engineered. While having a large Monolit is also a problem. The Them should not have a too big of a footprint and also it should be possible to develop add ons separately from a core.

  1. Performance or Operators Experience (OX)

Once a website gets larger build time is a concern not only because it will cost money eventually - especially when you like to deploy often. I am not sure which has here advantages.

I suggest to release the current status and use this issue to learn a bit more about modules. I like to start with my website and use this theme finally and will report here about what I learned.

Thank you again for all the efforts!

@mnordhaus
Copy link
Collaborator Author

mnordhaus commented Jan 25, 2025

This is the way how the Bootstrap dudes work within there Blog (also Hugo as the documentation too):

https://github.com/twbs/blog/blob/main/package.json

https://github.com/twbs/blog/tree/main/src/assets/scss

@zetxek
Copy link
Owner

zetxek commented Jan 25, 2025

As mentioned in #166 (comment) - let's explore bootstrap integration improvements, aside of the 2.0.0 release itself (that has added support for hugo modules).

Shall we consider this PoC (hugo modules) fixed by #166, and divide further improvements in other issues?

(btw for the submodule integration I've made a clone of https://github.com/zetxek/adritian-demo, https://github.com/zetxek/adritian-git-submodule-demo), just to automate checks and make sure that external integration via git is not broken (as the focus will be in the hugo module now).

@mnordhaus
Copy link
Collaborator Author

From my point of view this ticket is completed and I agree we should discuss the other issues in separate ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants