laynezh / vite-plugin-lib-assets

A Vite Plugin extracts resource files referenced in library mode instead of embedded them as base64.
MIT License
100 stars 9 forks source link

Asset URL changes when lib rebuilds in watch mode #92

Open kanonieer opened 2 months ago

kanonieer commented 2 months ago

Hi, TLDR I have issue that the url to assets get changed in output js files on rebuild in watch mode

Little project setup background:

/library
 /myComponent
  - myComponent.tsx
  - image.svg
/frontend-app

in /library I have a component that imports an svg for background image like

import image from './image.svg`

The image.svg is correctly bundled into dist/assets/image.svg and is correctly linked in myComponent.js bundled file as

import image from '../../assets/image.svg`

The issue I have occurs in dev mode in which I have the library built via vite build --watch - when I update code of library it gets rebuild and the link to asset get updated to

import image from `./assets/image.svg`

which no longer correctly links to asset folder (assets still exist under previous url)

here is how my vite.config looks like

export default defineConfig({
  plugins: [
    libInjectCss(),
    dts({
      insertTypesEntry: true,
    }),
    viteTsconfigPaths(),
    libAssets({
      name: '[name].[ext]',
    }),
  ],
  esbuild: {
    minifyIdentifiers: false,
  },
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.tsx'),
    },
    rollupOptions: {
      preserveEntrySignatures: 'strict',
      external: pkg.peers,
      input: Object.fromEntries(
        glob.sync('src/**/*.{ts,tsx}').map((file) => [
          // The name of the entry point
          // src/nested/foo.ts becomes nested/foo
          relative('src', file.slice(0, file.length - extname(file).length)),
          // The absolute path to the entry file
          // src/nested/foo.ts becomes /project/src/nested/foo.ts
          fileURLToPath(new URL(file, import.meta.url)),
        ]),
      ),
      output: [
        {
          format: 'es',
          // Put chunk files at <output>/chunks
          chunkFileNames: 'chunks/[name].[hash].js',
          // Put chunk styles at <output>/assets
          assetFileNames: 'assets/[name][extname]',
          entryFileNames: '[name].js',
        },
      ],
    },
  },
});

The issue seems to be similar to the one described there https://github.com/laynezh/vite-plugin-lib-assets/issues/89

PS. I was logging asset within outputPath function and I noticed it's only called during first build and not when the lib rebuilds - could it be the issue?

Thanks in advance for any help or advice :pray:

coder-layne commented 1 month ago

@kanonieer Under watch mode, due to the build cache, unchanged files are not re-processed by the plugin, and the assets within them aren't recognized. As a result, it's expected that the outputPath function won't be called on some assets during rebuilds. To emit complete assets during rebuilds, this plugin caches all emitted assets and re-emits them during the writeBundle phase. However, when emitting these cached assets, the import paths in importers are not processed, leading to this bug.

coder-layne commented 1 month ago

@kanonieer I just released v0.5.25 under the next tag, you can try it to see if it solves your problem.

rbatistajs commented 1 month ago

@coder-layne in version v0.5.25 after changing any file the assets folder is deleted.

In version v0.5.24 I have an error after changing any file and the folder is also deleted.

image

kanonieer commented 1 month ago

@kanonieer I just released v0.5.25 under the next tag, you can try it to see if it solves your problem.

@coder-layne The fix you made resolved the issue I had - many thanks for the help :heart: :bowing_man:

coder-layne commented 1 month ago

@rbatistajs Thanks for your feedback, and can you provide a minimal reproducible version?