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

Enable Webpack ESM output and move assets to /assets/ without subdirectories #25940

Closed
wants to merge 28 commits into from

Conversation

silverwind
Copy link
Member

@silverwind silverwind commented Jul 17, 2023

Enable Webpack to output ESM aka. modules. This is still flagged experimental, but in my testing, it works pretty well. With ESM, all the JS now runs in strict mode which has potential to bring up new JS errors. Also I consolidated the entrypoint scripts to single files because this is required anyways for a future migration to Vite. jQuery.are-you-sure is moved to a vendor file because it is not compatible with strict mode.

I noticed Webpack had some issues with lazy-loading the PNG from monaco, and I concluded that it's not worth to maintain the js,css,fonts etc subdirectories, so I moved the assets to a single subdirectory static which is also what vite does and it eliminates this class of webpack errors.

This works quite well in my testing, but I'm putting WIP because I think there i a strict mode violation in bootstrap.js which is only triggered on error, so I'll investigate that later.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jul 17, 2023
@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jul 17, 2023
@silverwind
Copy link
Member Author

This has an interaction with #25907, so that one should merge first after which I will move the output directory to /assets/static.

@silverwind silverwind marked this pull request as draft July 17, 2023 23:15
web_src/js/bootstrap.js Outdated Show resolved Hide resolved
@silverwind
Copy link
Member Author

Needs updates now that #25907 is in.

* main:
  Refactor "Content" for file uploading (go-gitea#25851)
  Fix SSPI auth panic (go-gitea#25955)
  Make pending commit status yellow again (go-gitea#25935)
  Move public asset files to the proper directory (go-gitea#25907)
  Disallow dangerous url schemes (go-gitea#25960)
  Avoid creating directories when loading config (go-gitea#25944)
  [skip ci] Updated translations via Crowdin
@silverwind silverwind marked this pull request as ready for review July 18, 2023 21:45
@silverwind
Copy link
Member Author

This is ready. I could not reproduce the strict mode violation that I previously saw with vite, so maybe it was something vite-specific.

Makefile Outdated Show resolved Hide resolved
@silverwind silverwind changed the title Enable Webpack ESM output and move to /static/ asset directory Enable Webpack ESM output and move assets to /assets/ without subdirectories Jul 20, 2023
@silverwind
Copy link
Member Author

silverwind commented Jul 20, 2023

The strict mode-related error currently shows up on /devtest/gitea-ui:

image

@wxiaoguang if you have any suggestions to fix it and improve this hacky error handler, please go ahead. We really shouldn't need to fake an Array like that. My first idea is to use a Proxy, but I'm sure there are even simpler solutions.

@silverwind silverwind marked this pull request as draft July 20, 2023 22:05
@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jul 21, 2023

Some code like initGlobalErrorHandler is executed more than once. (not tested yet, just a guess)

@silverwind silverwind marked this pull request as draft July 29, 2023 13:41
@silverwind
Copy link
Member Author

WIP again because of #25940 (comment). Maybe we can't actually do ESM for the webcomponents because of that flicker.

@silverwind
Copy link
Member Author

178538c appears to work to avoid the flicker. I do realize it's not ideal to load a module script as non-module, but it should work as long as we don't do import() inside the webcomponents chunk, which would be bad anyways because it again would be a source of flicker.

@silverwind
Copy link
Member Author

Found a way to extract the devtest css again, so nothing from devtest should load in prod build again.

@silverwind silverwind marked this pull request as ready for review July 29, 2023 14:04
@silverwind
Copy link
Member Author

As per this, combining type=module with async may be worth a try to get the webcomponents script to execute in a render-blocking way, I need to try.

@silverwind silverwind marked this pull request as draft August 11, 2023 08:47
@silverwind
Copy link
Member Author

There is another consideration with type=module scripts from MDN:

Unlike classic scripts, module scripts require the use of the CORS protocol for cross-origin fetching

This would introduce additional issues for people who host assets on another domain. While I discourage this as it's unnecessary since HTTP2, it's a breaking change to them.

I have a feeling this change of script type is not worth it, at least not yet.

@silverwind silverwind added the pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! label Aug 11, 2023
@wxiaoguang
Copy link
Contributor

This would introduce additional issues for people who host assets on another domain. While I discourage this as it's unnecessary since HTTP2, it's a breaking change to them.

I have a feeling this change of script type is not worth it, at least not yet.

Then I guess it breaks STATIC_URL_PREFIX and Set `[server] STATIC_URL_PREFIX = http://cdn.example.com/gitea` in your configuration., and Gitea won't work with CDN?

@silverwind
Copy link
Member Author

silverwind commented Aug 11, 2023

It could only work if said CDN would emit CORS headers, e.g. Access-Control-Allow-Origin. Still, I would never recommend serving assets on a different domain when HTTP2+ is in use, but I know there might be existing users that still do this.

If offloading the gitea web server from asset requests is the goal, the /assets/ subdirectory can be handled by the reverse proxy, and everything remains same-origin and browser security is happy. This is how I always deal with CORS, just don't do it, handle it at reverse proxy level instead.

@silverwind
Copy link
Member Author

silverwind commented Aug 25, 2023

If this does not land, we should use esbuild banner feature to run all JS in strict mode: evanw/esbuild#422 (comment)

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Aug 25, 2023

I haven't tested or fully understood the CDN problem. If it breaks CDN behavior, it would be a problem for many instances which depend on CDN ...... sorry I can't comment at the moment.

(ps: CDN is not just for a "different domain", it also for network speed, cost, server bandwidth, etc)

@silverwind
Copy link
Member Author

silverwind commented Aug 25, 2023

I think long-term, we eventually have to move to ESM script output to remove this unnecessary translation to CommonJS that webpack does. The question is just "when", not "if" imho.

Maybe we should wait til the ESM feature stabilizes in webpack, but I imagine it won't be until webpack 6, if that ever comes.

wxiaoguang pushed a commit that referenced this pull request Aug 31, 2023
Extract from #25940.

`assetUrlPrefix` is guaranteed to not contain trailing slashes, making
this function unneeded.
lafriks pushed a commit that referenced this pull request Sep 6, 2023
Extract from #25940 and because
#26743 does seem to need more
work.

This will be required if we are to run our JS in [strict
mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode).

Previously, the two variables `$fields` and `$dirtyForms` polluted
`window`:

<img width="1145" alt="image"
src="https://github.com/go-gitea/gitea/assets/115237/e0270a0e-b881-4ed7-9cc4-e9ab25c0a2bc">
@silverwind
Copy link
Member Author

Not going to continue here for now. Maybe another try later.

@silverwind silverwind closed this Sep 7, 2023
@go-gitea go-gitea locked as resolved and limited conversation to collaborators Dec 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. pr/breaking Merging this PR means builds will break. Needs a description what exactly breaks, and how to fix it! size/L Denotes a PR that changes 100-499 lines, ignoring generated files. type/refactoring Existing code has been cleaned up. There should be no new functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants