Describe the bug
__vitePreload includes assumptions about where assets are being served from. In a normal Vite project those assumptions hold true, but in more bespoke situations they may not.
Additionally, in the case where CSS dependencies fail to load (whether due to a network failure, or because of the situation described above) the promise returned from __vitePreload will never resolve.
Reproduction
https://github.com/Rich-Harris/vite-preload-repro
Given sources like this...
// src/index.js
import('./foo.js').then((foo) => {
foo.hello();
});
// src/foo.js
import './foo.css';
export function hello() {
document.body.innerHTML = `<h1>Hello!</h1>`;
}
// src/foo.css
h1 {
color: red;
}
...and a config like this...
const config = {
build: {
cssCodeSplit: true,
lib: {
entry: resolve('src/index.js'),
name: 'app', // this doesn't seem to do anything?
formats: ['es']
},
outDir: 'dist',
minify: false,
rollupOptions: {
output: {
entryFileNames: '[name]-[hash].js',
chunkFileNames: '[name]-[hash].js',
assetFileNames: '[name]-[hash][extname]'
}
}
}
};
...the resulting dist/index-ed8ec7ff.js file contains this line:
__vitePreload(() => import("./foo-5368ca0f.js"), true ? ["/foo-5368ca0f.js","/foo-0a0d0fb0.css"] : void 0).then((foo) => {
In the case where assets are served from somewhere other than / (for example, on an external CDN), the /foo-5368ca0f.js and /foo-0a0d0fb0.css paths are meaningless. If they were relative paths instead, the implementation of __vitePreload could add the following...
return Promise.all(deps.map((dep) => {
+ dep = new URL(dep, import.meta.url).href;
if (dep in seen)
return;
...and the resulting files would be more portable.
Meanwhile, to prevent the promise from hanging:
if (isCss) {
- return new Promise((res) => {
- link.addEventListener("load", res);
+ return new Promise((res, rej) => {
+ link.addEventListener("load", res);
+ link.addEventListener("error", rej);
});
}
System Info
vite version: 2.0.0-beta.69
- Operating System: Mac OS
- Node version: 12.18.3
- Package manager (npm/yarn/pnpm) and version: npm 6.14.6
Describe the bug
__vitePreloadincludes assumptions about where assets are being served from. In a normal Vite project those assumptions hold true, but in more bespoke situations they may not.Additionally, in the case where CSS dependencies fail to load (whether due to a network failure, or because of the situation described above) the promise returned from
__vitePreloadwill never resolve.Reproduction
https://github.com/Rich-Harris/vite-preload-repro
Given sources like this...
...and a config like this...
...the resulting dist/index-ed8ec7ff.js file contains this line:
In the case where assets are served from somewhere other than
/(for example, on an external CDN), the/foo-5368ca0f.jsand/foo-0a0d0fb0.csspaths are meaningless. If they were relative paths instead, the implementation of__vitePreloadcould add the following...return Promise.all(deps.map((dep) => { + dep = new URL(dep, import.meta.url).href; if (dep in seen) return;...and the resulting files would be more portable.
Meanwhile, to prevent the promise from hanging:
if (isCss) { - return new Promise((res) => { - link.addEventListener("load", res); + return new Promise((res, rej) => { + link.addEventListener("load", res); + link.addEventListener("error", rej); }); }System Info
viteversion: 2.0.0-beta.69