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

fix: script in app.html #13714

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

fix: script in app.html #13714

wants to merge 5 commits into from

Conversation

martabal
Copy link
Member

@martabal martabal commented Oct 24, 2024

The only place where we have js is in app.html and that's causing multiple issues:

  • Linters don't work here
  • Shared variables like colorTheme have to be kept in sync across multiple files.

That PR fixes all these issues it by moving that script to a complete new ts file fouc.ts. That script is also simplified.
During the first page load/the build, the import statement in fouc.ts is directly replaced by the entire content of the imported file to not have to deal with imports. Then the ts is transpiled to js and that js replaces the %app.fouc% placeholder in app.html.

The script in app.html is now:
image

Comment on lines 12 to 14
const themePrepared = theme.replaceAll(/^export\s+/gm, '');
const foucPrepared = fouc.replaceAll(/^import.*$/gm, themePrepared);
const scriptFouc = `<script>${transpileFile(foucPrepared)}</script>`;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you have to strip out imports/exports? Why can this not be loaded as a module?

Copy link
Member Author

Choose a reason for hiding this comment

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

All variables and methods should be placed within the script block. Correct me if I'm wrong, but if you include imports here, the browser will need to fetch those modules before executing the script, which will defeat the purpose.

Copy link
Contributor

Choose a reason for hiding this comment

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

The solution isn't to manually resolve the dependencies by hand though. We should probably have the script be dependency-less and throw an error if there are any imports being used.

Copy link
Member Author

Choose a reason for hiding this comment

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

So no shared modules? It's quiet nice to have theme.ts so we are sure that if one day we change one of the values here, there will be a lint/build failure

Copy link
Contributor

@jrasm91 jrasm91 Oct 25, 2024

Choose a reason for hiding this comment

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

I think there is value in getting linting, type-checking, etc. for this file. But you are getting that at the expense of manually managing module imports here, which I think isn't ideal. What if in the future theme.ts imports something from another file? Unless I'm mistaken that would just break this. What ends up happening is that you basically have to keep the dependency tree for this file in sync with this piece of code here. That's the job of a bundler, which you are in part replicating here. The two options I'd like to see instead would be either:

  1. This script has no dependencies, but other files can import from it. TLDR - move all the stuff that needs to be inlined, into this file and have everything else import from it.
  2. Define a custom entrypoint for vite which pulls everything in automatically into a single file and then inline that.

web/src/lib/utils.ts Outdated Show resolved Hide resolved
web/src/lib/utils/fouc.ts Outdated Show resolved Hide resolved
web/src/hooks.server.ts Outdated Show resolved Hide resolved
}

// should be the same values as the ones in constants.ts
enum Theme {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it not work to export these?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope:

 9:07:52 PM [vite] Error when evaluating SSR module /src/lib/utils/app.ts:
 |- ReferenceError: localStorage is not defined
     at /usr/src/app/src/lib/utils/app.ts:14:21

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we tell svelte that this isn't a SSR module?

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

Successfully merging this pull request may close these issues.

2 participants