-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
馃挕 RFC: Ability to transpile/bundle <script> tags inside of Astro components #370
Comments
Are we talking module script tags? |
I would take it for with module and non-module scripts. Module scripts being deferred means they should be treated separately. I don't know if this transpilation/bundle should be done my default on all script tags or only if a "flag" is set on the script tag.
Yes dedup would be nicer, also if the same script tag is used across multiple pages it should generate a chunk. But if a bundler is involved in the process they are not bad at this. |
What is there to bundle about non-module scripts? I assume you don't mean something like: <script>
function someInline() { // code here }
</script>
<h1>Hello world</h1>
<script>
var another = '....'
</script> You don't mean combining scripts, right? The problem there is that ordering might very well matter. Especially things like embeds often rely on scripts being placed after other elements. If you don't mean inline scripts then some clarity on what would be bundled would be helpful for me. As far as controlling the number of times a script is inserted, it scares me a little if Astro takes on too much knowledge about HTML structure and makes any sort of assumptions. What would be better, I think, is to give the developer the power to make the decision. For example we have the ---
const shouldInsertScript = Astro.component.instanceCount === 1
---
<div>...</div>
{shouldInsertScript ? (
<script>
/* my script that should be inserted once */
</script>
) : null} |
I think the current state is a real foot-gun for components. for example, if you have a component with a script tag that gets rendered in some list (ex: 25 times on the page) that's 25 repeating scripts on the page. It'll be mostly invisible to the user when this happens. So at best it's just a page weight / render speed concern (and a violation of easy-to-do-the-right-thing and fast-by-default). At worst, things break. I also agree that this isn't something we should go really deep on. For ex, I'd be -1 on creating a lot of custom config/primitives to control how the script loads, how many times, where on the page, etc. What about聽having Astro collect all scripts used to render the page, by default, and then moving them to a single place on the final rendered page? We already do this with CSS / Obviously we should have some fallback to opt-out and manually control this yourself (on the off chance you want ~25 scripts on the page :). Something like |
This actually could be solved by another idea that we'd been talking about:
|
Makes sense to me. And it's perfect first step anyway. |
One thing I think we're glossing over a little here is, what is the exact use case for having a script in a component in the first place? I can See a couple:
In both of the above cases, while it's possible to insert that components multiple times, you would just never do so. So there must be a case where you do want a component to be repeated but not all of its contents. What is the scenario? |
Deduplication is not my primary use case. Here is what I was thinking:
It's close to what you have magnificently done with CSS :D |
After seeing the new Next.js Script component, what it can do, and the positive developer response to it, I'm now in favor of solving this that way.
|
I like the idea to dedupe I use the fact that it runs once for some very sus "components" w/ my Hugo shortcodes: |
Very (literally - very!!) interested to see how this develops. Yet my main are of interest would be to see astro components being rendered in server-side environment, i.e. in express.js app. Could we take server-side component rendering into account? Or is it something Astro would not be interested to pursue? The core need is to be able to bundle multiple js snippets with Astro SFCs, also preferably setting some meta information for each of them. JS output composition would be handled in express.js codebase itself - be it inlining those scripts in request, or composing them in single file, or a mix of the multiple approaches. Components paradigm in server-side (i.e. express, koa ) frameworks is arguably a huge area of web development that has been ignored for too long by webdev tooling. I'd be so glad to see Astro to filling this gap. Currently I use two options(none of them very satisfying). First approach: Second approach: I honestly hope third approach will be just like the first one, just using Astro components instead, and besides I'd also be very glad to financially(at least to some extent) fund R&D of such feature development, if that only would make a difference. |
@toinbis Thanks for commenting but what you are referring to seems a bit different from what this issue is trying to solve. Would you mind creating another issue so it can be discussed separately? |
A low-level solution to this problem with be making sure that ---
const scriptsAdded = new WeakMap();
let includeScript = !scriptsAdded.has(Astro.request);
if(includeScript) {
scriptsAdded.add(Astro.request);
}
---
{includeScript && <script>console.log('this is only added once');</script>} However, this won't work due to the fact that this WeakMap will be created per-render :( This would be nice however because it's not specific to scripts, you could use it to conditionally add any type of content. |
I wonder if that would work for @tony-sull's svg use case? #706 |
I have a use case that I think could be interesting. I am making a However, I'd also like this component to be generic, and for example, accept a query selector for the opener button that it should attach the listener onto. For now, it seems that there's no way to provide a prop to the client script, which is a bummer. But if there were a way, then I for sure wouldn't want the scripts de-duplicated. Oh, and I'd want to keep using I think I can rejigger things so that I have a global script in |
I feel like it should work to auto-deduplicate scripts to their first addition into the page, because of these properties of them: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules |
Brought up by @georges-gomes:
We're staying away from Babel at the moment, but I agree that something like this would make sense.
Related: If a script tag exists in a component that appears multiple times on a page, what happens? Does it get deduped? Should it? We could answer this question at the same time.
The text was updated successfully, but these errors were encountered: