Skip to content
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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue + Vite + SSR: Referencing public assets with the root path (/myimage.jpg) inside the public directory results in a Rollup error #10082

Closed
7 tasks done
truumahn opened this issue Sep 12, 2022 · 10 comments

Comments

@truumahn
Copy link

Describe the bug

Using vite-plugin-ssr with Vue, running build with an asset referenced from the root path (e.g. /myimage.jpg) results in a Rollup error. This doesn't occur during dev.

Also, the issue doesn't occur when used with a generic Vue SPA.

However, @brillout noted that vite-plugin-ssr doesn't do anything about the public directory

Here's a detailed explanation of the scenarios:

Scenario A: VPS with Vue using npm init vite-plugin-ssr@latest

"vite": "^3.0.9",
"vite-plugin-ssr": "^0.4.32",
"@vitejs/plugin-vue": "^3.0.3"

myimage.jpg can be found in public directory, inside the root component in the template:

this breaks:

<img src="/myimage.jpg" />

this works:

<img src="http://localhost:3000/myimage.jpg" />

Scenario B: Vue 3 project using npm init vue@latest

"vite": "^3.0.9",
"@vitejs/plugin-vue": "^3.0.3"

myimage.jpg can be found in public directory, inside the root component in the template:

this works:

<img src="/myimage.jpg" />

this works:

<img src="http://localhost:3000/myimage.jpg" />

Reproduction

https:/truumahn/vps-public-image-repro

System Info

System:
    OS: Linux 5.10 Ubuntu 20.04.2 LTS (Focal Fossa)
    CPU: (12) x64 AMD Ryzen 5 4600H with Radeon Graphics
    Memory: 5.76 GB / 15.31 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 16.16.0 - /mnt/wslg/runtime-dir/fnm_multishells/31022_1662972639084/bin/node
    npm: 8.11.0 - /mnt/wslg/runtime-dir/fnm_multishells/31022_1662972639084/bin/npm
  Browsers:
    Chrome: 96.0.4664.45
  npmPackages:
    @vitejs/plugin-vue: ^3.0.3 => 3.1.0 
    vite: ^3.0.9 => 3.1.0

Used Package Manager

pnpm

Logs

Click to expand!
[vite]: Rollup failed to resolve import "/politecat.jpg" from "renderer/PageShell.vue?vue&type=script&setup=true&lang.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
[vite-plugin-ssr:autoFullBuild] [vite]: Rollup failed to resolve import "/politecat.jpg" from "renderer/PageShell.vue?vue&type=script&setup=true&lang.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
error during build:
Error: [vite]: Rollup failed to resolve import "/politecat.jpg" from "renderer/PageShell.vue?vue&type=script&setup=true&lang.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
    at onRollupWarning (file:///path/to/project/vite-ssr-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-665b0112.js:45824:19)
    at onwarn (file:///path/to/project/vite-ssr-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-665b0112.js:45622:13)
    at Object.onwarn (file:///path/to/project/vite-ssr-project/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:23225:13)
    at ModuleLoader.handleResolveId (file:///path/to/project/vite-ssr-project/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:22352:26)
    at file:///path/to/project/vite-ssr-project/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/es/shared/rollup.js:22313:26
 ELIFECYCLE  Command failed with exit code 1.

Validations

@brillout
Copy link
Contributor

Vite-plugin-ssr doesn't do anything with public/ assets, so it's likely a Vite issue during SSR building.

@sapphi-red
Copy link
Member

It seems it does not reproduce with a simple setup.
https://stackblitz.com/edit/github-marmex?file=src%2FApp.vue

And it happens with vite-plugin-ssr + react too.
https://stackblitz.com/edit/github-6pyqmj?file=renderer%2FPageShell.jsx

@truumahn
Copy link
Author

truumahn commented Sep 12, 2022

And it happens with vite-plugin-ssr + react too.

Only because you imported the images, not used them with the root path as /logo.svg directly at the src attribute of the img element. It successfully builds like this: https://stackblitz.com/edit/github-6pyqmj-wrxz1m?file=renderer/PageShell.jsx

The same doesn't work with Vue though.

@sapphi-red
Copy link
Member

plugin-vue transforms <img src="/logo.svg"> into

<template>
  <img :src="logoSvg" />
</template>

<script setup>
import logoSvg from '/logo.svg'
</script>

So something is not working around resolving /logo.svg.
And since it does not happen with Vite only, I guess something in vite-plugin-ssr is interacting it.

@truumahn
Copy link
Author

truumahn commented Sep 12, 2022

It builds successfully with the following vite.config.ts:

import vue from "@vitejs/plugin-vue";
import ssr from "vite-plugin-ssr/plugin";
import { UserConfig } from "vite";

const config: UserConfig = {
  plugins: [
    vue({
      template: {
        transformAssetUrls: {
          img: [],
        },
      },
    }),
    ssr({ prerender: true }),
  ],
};

export default config;

https://stackblitz.com/edit/vitejs-vite-nsfvwb?file=vite.config.ts

So it is indeed the Vue plugin that causes this. I'm just checking the documentation: https:/vitejs/vite/tree/main/packages/plugin-vue#asset-url-handling

This behaviour was introduced in 3.x.

@brillout
Copy link
Contributor

It seems that @vitejs/plugin-vue tries to resolve src if it doesn't match a public/ asset.

Vite-plugin-ssr 0.4 changed Vite's config publicDir to false for SSR, which explains the problem.

I reverted that change and released a new version [email protected] which should fix the problem.

@truumahn Let me know if you run into any other issues. We can close this in the meantime.

@sapphi-red The proper fix would be to stop separating the client-side and server-side building process into two isolated processes. FYI, this is one of many reasons why I believe the decision the Vite team took here #9496 (comment) was a mistake. Separating both builds is asking for trouble.

@brillout
Copy link
Contributor

The proper fix would be to stop separating the client-side and server-side building process into two isolated processes. FYI, this is one of many reasons why I believe the decision the Vite team took here #9496 (comment) was a mistake. Separating both builds is asking for trouble.

I created a discussion #10097 - Unify client-side and server-side build steps about this.

@sapphi-red
Copy link
Member

It seems that @vitejs/plugin-vue tries to resolve src if it doesn't match a public/ asset.

Yes. This is because of #10082 (comment).

Vite-plugin-ssr 0.4 changed Vite's config publicDir to false for SSR, which explains the problem.

What is the purpose of changing this? Avoiding the public directory to be copied? I think it's correct not to resolve public assets when publicDir: false is set.

@brillout
Copy link
Contributor

Yes, to avoid the public directory being copied twice at dist/client/assets/ and dist/server/assets/. If the user has a couple of gigabytes of images, that's significant.

@truumahn
Copy link
Author

I'm closing this as the original issue has been resolved. The discussion can be continued in #10097

@github-actions github-actions bot locked and limited conversation to collaborators Oct 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants