Use import.meta.url by default? #1623
Replies: 3 comments
-
I can see how this might work for ESM files, but what happens when bundlers consume the library and segment its assets from the original file's location? I don't believe we can rely on There's a bit of logic in the base path logic to try to detect it based on the presences of a I'd love to improve this, but I want to make sure whatever we change continues to work at least as good as what we have now. |
Beta Was this translation helpful? Give feedback.
-
this is not a concern when somebody explicitly uses a CDN to load the provided ESM ... bundlers can break anything they want, but if you publish as CDN then this is also not your, as library author, concern? In any case, checking that
you can always check at least most common CDNs and help CDN users to start without issue ... after all, this is the entry point in your documentation: "run this project from a CDN and be done with it". If the documentation getting started was something like "you need a bundler to use this project correctly out of the box" this request wouldn't have existed in the first place ... I hope my reasoning makes sense. |
Beta Was this translation helpful? Give feedback.
-
P.S. this is (not tested) how I'd try to solve this: let basePath = '';
/** Sets the library's base path to the specified directory. */
export function setBasePath(path: string) {
basePath = path;
}
/**
* Gets the library's base path.
*
* The base path is used to load assets such as icons and images, so it needs to be set for components to work properly.
* By default, this script will look for a script ending in shoelace.js or shoelace-autoloader.js and set the base path
* to the directory that contains that file. To override this behavior, you can add the data-shoelace attribute to any
* script on the page (it probably makes the most sense to attach it to the Shoelace script, but it could also be on a
* bundle). The value can be a local folder or it can point to a CORS-enabled endpoint such as a CDN.
*
* <script src="bundle.js" data-shoelace="/custom/base/path"></script>
*
* Alternatively, you can set the base path manually using the exported setBasePath() function.
*
* @param subpath - An optional path to append to the base path.
*/
export function getBasePath(subpath = '') {
if (!basePath) {
const configScript = document.querySelector('script[data-shoelace]');
if (configScript) {
// Use the data-shoelace attribute
setBasePath(configScript.dataset.shoelace);
} else {
let path = import.meta.url;
if (['cdn.jsdelivr.net'].includes(new URL(path).host)) {
// Use the CDN as base (NOT SURE THIS IS ENOUGH NEGATIVE SLICE)
setBasePath(path.split('/').slice(0, -1).join('/'));
} else {
path = '';
for (const s of document.querySelectorAll('script')) {
if (
/shoelace(\.min)?\.js($|\?)/.test(s.src) ||
/shoelace-autoloader(\.min)?\.js($|\?)/.test(s.src)
) {
path = s.getAttribute('src')!;
break;
}
}
setBasePath(path.split('/').slice(0, -1).join('/'));
}
}
}
// Return the base path without a trailing slash. If one exists, append the subpath separated by a slash.
return basePath.replace(/\/$/, '') + (subpath ? `/${subpath.replace(/^\//, '')}` : ``);
} |
Beta Was this translation helpful? Give feedback.
-
What issue are you having?
We had issues with the assets to then realize it was surely well documented but totally unexpected, from a modern ESM point of view ... basically we need to use the following code:
which is not the end of the world but ESM files have an
import.meta.url
that especially for these use cases make the usage of explicitsetBasePath
hard to justify and more error-prone.Describe the solution you'd like
Internally, the library should use
setBasePath
viaimport.meta.url
when imported as ESM, still allowing an explicit override to avoid breaking backward compatibility, but providing the right CDN base path out of the box.Describe alternatives you've considered
Fork the project and re-export all the things via
import.meta.url
as default base path for the ESM export but that seems, looks, and feels, extreme, so maybe this feature request will instead be accepted.Thanks for considering this!
Beta Was this translation helpful? Give feedback.
All reactions