#Idea: A tool to extract, bundle, and inject #JavaScript and #CSS referenced on a web page at build time.

Imagine an #SSG toolchain whereby you render a page like:

```html
<html>
<my-comp>Some content.</my-comp>
<script src="/my-comp.js" type="module"></script>
<link href="/my-comp.css" rel="stylesheet">

<my-comp-2>Some more content.</my-comp-2>
<script src="/my-comp-2.js" type="module"></script>
<link href="/my-comp-2.css" rel="stylesheet">
</html>
```

Then you could run a tool and transform it to:

```html
<html>
<my-comp>Some content.</my-comp>
<my-comp-2>Some more content.</my-comp-2>

<script src="/all-scripts.js" type="module"></script>
<link href="/all-styles.css" rel="stylesheet">
</html>
```

This way you can render only the scripts/styles you actually need for a specific page and they will be implicitly used as entry points for bundled and optimized resources.

It's render-driven bundling!

#Web

#rules_prerender can actually do this and it's a very powerful feature, but using it in that ecosystem requires buying into a much larger toolchain not everyone will want.

https://github.com/dgp1130/rules_prerender/

I'm imagining a more flexible, standalone tool which could be effectively used in any web toolchain.

GitHub - dgp1130/rules_prerender: A Bazel rule set for prerending HTML pages.

A Bazel rule set for prerending HTML pages. Contribute to dgp1130/rules_prerender development by creating an account on GitHub.

GitHub

The biggest challenge with a standalone tool like this is how it would integrate with a bundler.

In theory, the tool doesn't really care about the bundler at all. It just needs some tool it can reference to convert entry point paths (`/my-comp.js`) to their bundled paths (`/all-scripts.js`):

```typescript
declare function bundle(
entryPoints: Set<string>,
): Map<
/* entryPoint */ string,
/* output */ string
>
```

Unfortunately making this ergonomic with modern #JavaScript bundlers would be quite a pain and likely require bespoke plugins and integrations for each one.

Yet again, the lack of build systems on the web throws a wrench into any kind of reasonably-abstracted build tooling.

@develwithoutacause Just an idea but I think it's a good use for a proxy server maybe. Something that you can put in front of any website and optimize it in various ways. I've done stuff like this with lol_html (a rust crate from cloudflare). I have a development tool called coolstyleserver that uses it to modify webpages for hot reloading of styles when you don't use a bundler, so I know it's possible. It would be a tough sell though maybe.

@erickjm Are you talking about running this optimization at request-time via a proxy server? The primary benefit of this is to bundle and optimize the JavaScript during the build, that kind of tooling is too slow to run at request-time and would overall negatively affect the user experience.

I could maybe see the possibility of doing this during deployment-time or as a dynamic async optimization which happens in the background of the first request but then gets cached for future requests.

I'm personally not a big fan of deployment/service-level transformations like that as it makes it harder to reason about the code you're actually developing, couples you more tightly to the cloud provider offering the feature, and breaks integrity features like CSP. I do see how some devs might prefer that kind of approach though.

@develwithoutacause Yeah at request time, but with caching of course. But I read your post too quickly to be honest. I thought you were just talking about deduplicating some script and link tags mostly.
@erickjm Deduplicating isn't that big an improvement, I'm thinking about bundling and tree shaking the scripts. This way you can render a site, only generate `<script>` tags where you know functionality is needed, and then automatically bundle and load only the exact minimum amount of JS required for each page.