vite icon indicating copy to clipboard operation
vite copied to clipboard

vite 5.1.3 will lost js & css in html if `build.rollupOptions.input` is relative path

Open wxpwxpwxp opened this issue 2 years ago • 7 comments

Describe the bug

vite 5.1.3 will lost js & css in html after build multiple html input it works in vite4 snapshot

Reproduction

https://github.com/wxpwxpwxp/multi_page_vite_demo/tree/master

Steps to reproduce

cd vite5 pnpm i pnpm run build

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
    Memory: 7.86 GB / 15.80 GB
  Binaries:
    Node: 20.11.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD
    pnpm: 8.15.1 - ~\AppData\Roaming\npm\pnpm.CMD
  Browsers:
    Edge: Chromium (121.0.2277.128)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @vitejs/plugin-vue: ^5.0.4 => 5.0.4 
    vite: ^5.1.3 => 5.1.3

Used Package Manager

pnpm

Logs

No response

Validations

wxpwxpwxp avatar Feb 21 '24 02:02 wxpwxpwxp

I am experiencing the same thing but I don't think the problem is multi builds per se. The issue happens when you add the rollupOptions even on single entry builds:

    rollupOptions: {
      input: globSync(['index.html', 'admin/**/*.html', 'community/**/*.html']),
    },

When I built with:

    rollupOptions: {
      input: {
            test: "index.html"
        },
    },

It still failed to include the JS and CSS.

Edit: I tried with Vite 4.5.2 and everything worked as expected. There must be an issue with Vite 5 and Rollup.

dresch86 avatar Feb 21 '24 04:02 dresch86

This seems to only happen on Windows.

A workaround is to call path.resolve:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'node:path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      input: {
        index: path.resolve('index.html'),
        test: path.resolve('test.html')
      }
    }
  }
})

sapphi-red avatar Feb 21 '24 11:02 sapphi-red

related: #15153

sapphi-red avatar Feb 21 '24 11:02 sapphi-red

I am also experiencing the same phenomenon. When built, the files exist in dist but are not referenced in html.

On the other hand, if you use Vite version 4.5.2, you can see that the reference is inserted normally.

import multiInput from "rollup-plugin-multi-input";

export default {
    root: 'pages',
    publicDir: '../public',
    build: {
        target: 'esnext',
        outDir: '../dist',
        rollupOptions: {
            input: [
                'pages/**/*.html'
            ],
            plugins: [multiInput.default()],
        },
    },
    server: {
        port: 8080,
    }
}

katanazero86 avatar Feb 21 '24 14:02 katanazero86

This seems to only happen on Windows.

A workaround is to call path.resolve:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'node:path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      input: {
        index: path.resolve('index.html'),
        test: path.resolve('test.html')
      }
    }
  }
})

The workaround becomes an issue if one is using glob to get the paths. For multipage applications, you're going to have to resolve multiple files which could become unmaintainable depending on the number.

EDIT: This should work for now...

  build: {
    emptyOutDir: true,
    outDir: '../resources/public',
    rollupOptions: {
      input: globSync(['index.html', 'dir1/**/*.html', 'dir2/**/*.html']).map(f => path.resolve(f)),
    },
  },

dresch86 avatar Feb 21 '24 15:02 dresch86

I just bumped into this, it's really painful bug - it didn't trigger on CI (which is Linux), so I noticed it a long time after it was introduced in the codebase and took me few hours to figure out.

Is this a bug in Rollup or Vite?

If can't be easily fixed, I'd at least add note to docs (Vite or Rollup?), because it's easy to bump into it accidentaly.

panstromek avatar Apr 11 '24 09:04 panstromek

I got faced with this bug since Vite 5.1, too. It's not present in 5.0.12, but still exists in 5.2.8. I've traced it down to a bug in Vite which is related to path handling and manifests itself only under Windows filesystems. I've traced it down to https://github.com/vitejs/vite/blob/102c2fd5ad32a607f2b14dd728e8a802b7ddce34/packages/vite/src/node/plugins/html.ts#L816 where the chunk.facadeModuleId is something like C:\Users\rse\xxx\index.html (the Windows path separation characters are in place) and the id is C:/Users/rse/xxx/index.html (where POSIX path separation characters are in place). As a result, the chunk is not found and hence the tags not emitted during the HTML generation. The workaround by using path.resolve() on the build.rollupOptions.input works, but it would be better if the comparison inside Vite is fixed. I propose to change chunk.facadeModuleId === id with chunk.facadeModuleId === normalizePath(id) to fix this nasty bug. For a little bit better performance, use const normalizedId = normalizePath(id) at the start of the loop and then twice us normalizeId in the loop (there is already a call to normalizePath(id) there).

rse avatar Apr 13 '24 22:04 rse

Closing as #16421 is merged.

sapphi-red avatar May 06 '24 04:05 sapphi-red