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

Equivalent of Node.js' path.relative #13187

Open
rnwst opened this issue Dec 22, 2024 · 2 comments
Open

Equivalent of Node.js' path.relative #13187

rnwst opened this issue Dec 22, 2024 · 2 comments
Labels
Milestone

Comments

@rnwst
Copy link

rnwst commented Dec 22, 2024

It would be convenient if Hugo's path functions included one that allowed us to make an absolute location relative to another absolute location, in the same way Node.js' path.relative function works. This could be called path.Rel, path.RelFromTo, path.Relative, or something along those lines.

@bep bep removed the NeedsTriage label Dec 23, 2024
@bep bep added this to the Unscheduled milestone Dec 23, 2024
@bep
Copy link
Member

bep commented Dec 23, 2024

absolute location relative to another absolute location

There are very few (2?) absolute locations in Hugo's API, so you need to come up with some "useful examples".

@rnwst
Copy link
Author

rnwst commented Dec 23, 2024

Thank you for considering my proposal! I should've been clearer in my proposal, by absolute location I meant absolute URL path, like those created with RESOURCE.RelPermalink. The return value of the function would be a relative URL path. As an example, path.RelFromTo "/js/a/a.js" "/js/b/b.js" would return "../../b/b.js".

As to a simple example where this could be used. A few bytes could be saved by including relative instead of absolute URL paths for page resources in templates, like so: src="{{ path.RelFromTo .RelRef $pageResource.RelPermalink }}" (since the resulting relative URL path would likely be much shorter than the equivalent absolute URL path). This is just a simple example where, admittedly, not much is gained, but it illustrates the function.

Here is another example, which is my personal use case. Apologies if this is too convoluted. I have a bunch of small module scripts which are all imported into a single module script, residing under assets/js/index-inline.js:

import './a.js';
import './lib/b.js';
import './dir1/dir2/c.js';

In production, I want to inline, bundle, and minify these, to increase page load speed. For development, however, I don't want to bundle and inline the imports, to make debugging easier. This means that for development, I need to pass the imports as externals to js.Build, and at the same time also as shims, to make sure the relative URL paths in the import statements of index-inline.js get replaced with the absolute URL paths of the fingerprinted and published imports.

{{- $inlinePath := "/js/index-inline.js" }}
{{- $inlineIndex := resources.Get $inlinePath }}
{{- $inlineBuildOpts := dict "format" "esm" }}
{{- if hugo.IsProduction }}
  {{- $inlineBuildOpts = merge $inlineBuildOpts (dict "minify" true) }}
{{- else }}
  {{- $modules := resources.Match "js/**.js" }}
  {{- $shims := dict }}
  {{- $externals := slice }}
  {{- range $modules }}
    {{- /* Generate both relative and absolute paths, as we cannot be sure how the modules were imported. */}}
    {{- $relPath := printf "%s/%s" "./" (path.RelFromTo $inlinePath .Name) }}
    {{- $absPath := .Name }}
    {{- $url := (fingerprint .).RelPermalink }}
    {{- $shims = merge $shims (dict $relPath $url
                                    $absPath $url) }}
    {{- $externals = append $externals (slice $url) }}
  {{- end }}
  {{- $inlineBuildOpts = merge $inlineBuildOpts (dict "shims" $shims
                                                      "externals" $externals) }}
{{- end }}
{{- $inlineIndex = $inlineIndex | js.Build $inlineBuildOpts }}
    <script type=module>
      {{ $inlineIndex.Content | safeJS }}
    </script>

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

No branches or pull requests

2 participants