resources.FromString breaks resource caching/reloading

I’ve been noticing that something about my setup cause Hugo to get a little confused and load old versions of resources until I restart the server. The most noticeable symptom is that if I make a code change in a Typescript file, then change it back it will continue loading the previous version. At any point if I go back to a version of the file that was previously used it will continue loading the most recent version before the change.

It feels like the resource system is caching versions and when a new version is requested that matches a cached version it returns the current version instead of the matching cached version. But that’s just a wild guess.

It’s a bit tricky to get consistent enough behavior for a clear repro, but I think this will work.

I’m running my server with hugo server -e development.

I have this partial template. It’s reduced from my actual partial which is using FromString because it’s renaming a resource file. FromString seems to be the thing causing the issue.

{{ $resource := resources.Get . | js.Build }}
{{ $resource = $resource.Content | resources.FromString . }}
{{ return $resource.RelPermalink }}

I’m using the partial template with

{{- with partial "resource" "res/main.ts" }}
	<script src="{{ . }}"></script>
{{- end }}

In my Typescript file I’m commenting and uncommenting the same line of code and watching to see if the generated file in public changes. Typically what I see is that the generated file never updates when toggling the comment.

If I add --disableFastRender it works correctly and each time I toggle the comment the file is updated. (Note: this option isn’t desirable because it stops the page in the browser from live reloading when making code changes. I’m not sure it’s working correctly.)

If I actually change the resource name the generated file is updated correctly once then stops being updated (until I make a change to the code that is new and isn’t “cached”)

{{ $resource := resources.Get . | js.Build }}
{{ $name := replaceRE `\.ts\z` ".js" . }}
{{ $resource = $resource.Content | resources.FromString $name }}
{{ return $resource.RelPermalink }}

I know I’m coloring a bit outside the lines here.

--ignoreCache and --noHTTPCache don’t appear to have an impact.

It’s also worth noting that changing the partial template while the server is running doesn’t change the behavior. I have to restart the server. For example, if I’m using resources.FromString and reloading is not working and I remove FromString reloading remains broken until a server restart.

I’ve read this a few times, and I don’t understand why you are using the resources.FromString function.

Unless I’m missing something, it seems like you could just specify the targetPath in the options map passed to the js.Build function.

I don’t think I knew about targetPath. I’ll give that a shot real fast. If it works that at least gives me a way to avoid the issue.

Sorry if it’s hard to follow. It’s tricky to communicate the issue clearly. Happy to provide additional detail if needed.

Oh, I remember why I’m not using targetPath now. Because I use this resource renaming for multiple asset types, not just Typescript/Javascript.

Have you looked at resources.Copy?

I don’t recall a specific reason for using FromString over Copy. There was a potential issue with it a while back, but I’m not running into it locally.

I’ve swapped to Copy and it looks like it behaves correctly. As a bonus it’s a lot faster - 16ms → 8ms to rebuild.

1 Like