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

Use dynamic file names for assets #18632

Closed
wants to merge 1 commit into from

Conversation

silverwind
Copy link
Member

@silverwind silverwind commented Feb 6, 2022

WIP on dynamic asset filenames which turns /js/index.js into /js/index.5ed90373e37c.js. This is done via webpack-assets-manifest which creates a assets-manifest.json file which is used by the backend to map the filenames.

TODOs:

  • Find a solution for development reloads
  • Render the resolved filenames back into the template
  • Make it work for bindata
  • Fix Makefile logic for index.js and index.css
  • Gracefully handle absence of assets-manifest.json for integration tests

I'm unsure what the best option is for development rebuilds as the backends need to be able to reload assets-manifest.json when it changes, both inside bindata and in the file system. One simple option could be to only use dynamic asset names during the prod build. Another option could be a SIGUSR1 (SIGHUP is already in use) sent by webpack to the backend, but I don't think it's a portable option.

Fixes: #18522

@silverwind silverwind added pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! topic/build PR changes how Gitea is built, i.e. regarding Docker or the Makefile pr/wip This PR is not ready for review and removed pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! labels Feb 6, 2022
modules/public/public.go Outdated Show resolved Hide resolved
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Feb 6, 2022
modules/public/public.go Outdated Show resolved Hide resolved
@wxiaoguang
Copy link
Contributor

wxiaoguang commented Feb 6, 2022

Actually the original PR #18348 (/assets/public-{ver}/index.js) was almost done and very simple (+24 −16), and it can handle all cases.

This PR is already much more complex (+190 −28) and still have a lot of TODOs, and it doesn't handle existing JS files without webpack (CodeMirror plugins, PDF.js, etc, the public/vendor/plugins), and it might need hacky methods to handle filenames in templates and during development.

Although I still feel that #18348 is better and more suitable for current Gitea, if this PR can handle all cases correctly without introducing hacky methods, then I would have no objection.

@silverwind
Copy link
Member Author

silverwind commented Feb 6, 2022

This PR is already much more complex

More complex, but the proper solution imho

lot of TODOs

Yes, it's WIP

existing JS files without webpack

I plan to remove all files outside webpack in the future, it's just bad practice and CodeMirror can break anytime with the currently outdated plugins.

might need hacky methods to handle filenames in templates and during development

Not hacky imho, and I think I've found a solution for development by Stat()ing the manifest.

@silverwind
Copy link
Member Author

silverwind commented Feb 6, 2022

It seems the general recommendation for webpack during development is to not emit hash-based assets (files will pile up in the filesystem until watch is restarted, there is clean option but I found it to be buggy).

Current solution still has it in by checking the mtime of the manifest, but I think I will opt to just follow the recommendation and remove it during development.

@stale
Copy link

stale bot commented Apr 17, 2022

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 months. Thank you for your contributions.

@stale stale bot added the issue/stale label Apr 17, 2022
@lunny lunny added the issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented label Apr 17, 2022
@stale stale bot removed the issue/stale label Apr 17, 2022
@silverwind
Copy link
Member Author

Let's keep this open.

@silverwind silverwind marked this pull request as draft August 9, 2022 15:07
@silverwind
Copy link
Member Author

Rebased. Still WIP.

}

manifestModified = fi.ModTime()
manifestMutex.Unlock()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All returns need Unlock

@silverwind
Copy link
Member Author

silverwind commented Aug 16, 2022

Development & Production version should enable cache when the asset is the same and disable cache when the asset is not the same. Since cache could be disabled from web browser. It seems it's unnecessary to diff Development & Production versions.

@lunny: time-based cache doesn't work like that. Browser will not even attempt to re-validate a cached resource until cache duration has expired, even if it had already changed on the server. ETag-based cache could do what you want but it would require re-validation (e.g. If-None-Match header) on every request, which will increase server load.

Once cache busting via filename works (this PR), I agree, we can make prod/dev the same, but it's still convenient to not have the dev server cache at all.

// use clean to keep the file is a valid path with no . or ..
f, err := fs.Open(path.Clean(file))
f, err := fs.Open(file)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: should path.Clean in all cases.

@silverwind
Copy link
Member Author

silverwind commented Aug 16, 2022

On topic here: It might be possible make a "light" version of this PR and introduce contenthash for dynamic chunks only, which is really the main cause of the cache issues. Cache busting via query string from HTML works, but the problem happens because dynamic chunks are always served with the same names. I'll try that.

Edit: #20813

@silverwind
Copy link
Member Author

Let's continue this in #20813. I think the solution here with asset manifest is probably too complicated, but will likely be necessary if we ever want to have consistent contenthash in all filenames.

@silverwind silverwind closed this Aug 17, 2022
@go-gitea go-gitea locked and limited conversation to collaborators May 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/confirmed Issue has been reviewed and confirmed to be present or accepted to be implemented lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. pr/wip This PR is not ready for review topic/build PR changes how Gitea is built, i.e. regarding Docker or the Makefile
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Edit of comments not possible
4 participants