ProjectEvergreen / greenwood

Greenwood is your workbench for the web, embracing web standards from the ground up to empower your stack from front to back.
https://www.greenwoodjs.io
MIT License
97 stars 9 forks source link

Isomorphic Asset Bundling #1163

Open thescientist13 opened 12 months ago

thescientist13 commented 12 months ago

Type of Change

Feature / Documentation

Summary

In #1151 as part of fixing bundling of custom imports using a combination of new URL + import.meta.url, a feature was enabled that support "bundling" of non-Javascript assets, like images. For example, doing something like this could * work

const logo = new URL('./logo.svg', import.meta.url);

class HeaderComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `
      <header>
        <h1>Welcome to My Site!</h1>
        <img src="${logo.pathname}" alt="Company logo"/>
      </header>
    `;
  }
}

customElements.define('x-header', HeaderComponent);

This will now produce a filename that includes hashing in the name automatically, e.g. logo-abb2e884.svg. 🎉

This is also awesome because now these assets can be anywhere, not just the /assets/ directory! 💯

However, in the browser import.meta.url will effectively equal the pathname of new URL(import.meta.url), which means if the URL in the browser is something like www.mywebsite.com/about, the path in the above example would resolve to www.mywebsite.com/about/logo-abb2e884.svg, which breaks. 😢 (notice the /about/ in the path segment)

Screenshot 2023-10-07 at 8 09 45 PM


It is interesting to note that in development this doesn't seem to be an issue, looking at the output of import.meta.url and logo respectively. Screenshot 2023-10-07 at 8 01 14 PM

Details

A quick and dirty hack currently is to do something like this but that's a little clunky, which is to programmatically remove the pathname from the browser URL bar.

<img src="${logo.pathname.replace(window.location.pathname, '/')}" alt="Greenwood logo"/>

Screenshot 2023-10-07 at 8 13 03 PM

It would be nice to find a way or pattern that can ensure this is a consistent experience not only for the browser, but for SSR as well! Thinking that as part of #955 and related to observations documented in #691 , it would be cool to get "absolute" references to static assets when generating this same code on the server too in the case of prerendering or SSR pages, so should test those out as well.

This also needs to take into account when a base path is set, too.

We should allow follow the convention set for API routes in https://github.com/ProjectEvergreen/greenwood/pull/1186/commits/59136f3d25753a641ec2e8a9d86ae8a989eca15e#diff-57634df7e2b1ba3ea0031d8adc1e73230ca3c93bbecfdea7b44d00c7e100ec8b to also do "bundle mapping" for SSR page URL chunks. (additionally, started a discussion for URL bundles in general at https://github.com/ProjectEvergreen/greenwood/discussions/1204


Additionally, for docs and implementations, we should probably make sure to align with #1005 and #517