vite: library mode can't extract static assets

Describe the bug

while in library mode, exec yarn build, the static assets is inline into css file, but what i want is to remain assets alone.

Reproduction

  1. yarn create @vitejs/app vite-demo --template react
  2. replace img with div in App.tsx, and remove src attribute
<div className="App-logo" />
  1. add background-image: url(facivon.svg) for .App-logo classname in App.css
.App-logo {
	height: 40vmin;
	pointer-events: none;
	background-image: url(t.jpeg);
}
  1. edit vite.config.json
import { defineConfig } from 'vite';
import path from 'path';
import reactRefresh from '@vitejs/plugin-react-refresh';

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [reactRefresh()],
	build: {
		assetsInlineLimit: 0,
		lib: {
			entry: path.resolve(__dirname, './src/main.tsx'),
			name: 'demo',
		},
	},
});

  1. exec yarn build

  2. output

dist
├── style.css
├── vite-demo.es.js
└── vite-demo.umd.js

what i expect is that there is a favicon.svg file in dist directory

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 58
  • Comments: 27 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Any updates?

Can we have an option that enables emitting assets separately in lib mode?

I wrote a plugin to extract static assets in library mode: vite-plugin-lib-assets

usage:

import libAssetsPlugin from '@laynezh/vite-plugin-lib-assets'

export default defineConfig({
  plugins: [
    libAssetsPlugin({
      limit: 1024 * 8,
      extensions: ['.jpg', '.png', '.otf', '.ttf', '.woff'],
    }),
  ],
})

Any updates on this?

I think the suggestion from the Vite team would be to use a public directory.

Say you have the file /public/cool-font.woff that was included in your Vue component library:

<template><span class="cool-text"><slot></slot></span></template>

<script lang="ts" setup>
// ... 
</script>

<style lang="scss">

@font-face {
    font-family: 'CoolFont';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/cool-font.woff') format('woff');
}

.cool-text {
    font-family: 'CoolFont';
}

</style>

Configured like this, the file will not be inline, but there’s one other catch. The public directory needs to be published with the package. So the package.json would be updated:

{
  "name": "cool-package",
  "exports": {
    ".": "./dist/lib.js",
+   "./cool-font.woff": "/public/cool-font.woff"
  },
  "files": [
    "/dist",
+   "/public"
  ]
}

Now whatever environment the cool-package is included in can handle packing/vite/rollup of the static assets however it needs too.

I would really like this as well. Curious, why is this not supported in “lib” mode? Must be a reason.

I have a solution: move assets to another package

// @libname/core
import ttf from '@libname/icons/fonts/iconfont.ttf'
// @libname/core vite.config.ts
// ......
    build: {
       // ...
      rollupOptions: {
        external: [/\@libname\/icons/],
      },
    },

This problem has been bothering me for a long time. Is there any update?

I would really like this as well. Curious, why is this not supported in “lib” mode? Must be a reason.

Anyone? Why is there a difference from standard, when using lib mode?

This might not be related to this, but what about web workers? I’m unable to use web workers in library mode as well. It builds fine, but doesn’t bundle the worker with it.

Please, allow this for ‘es’ libs. Thanks 😃 . Bundle with svg files inlined , why?

This would also be cool for json files.

I was using library mode so I could get iife and umd builds, but I still wanted the static assets to be separate from the bundle.

I ended up digging into the rollupOptions instead, my vite.config.js is similar to this:

export default {
  build: {
    assetsInlineLimit: 0,
    cssCodeSplit: false,
    rollupOptions: {
      input: 'src/index.ts',
      output: {
        dir: 'dist/',
        format: 'iife',
        name: 'exportsFromEntryPoint',
      },
      preserveEntrySignatures: 'strict',
    },
  },
};

I wrote a plugin to extract static assets in library mode: vite-plugin-lib-assets

usage:

import libAssetsPlugin from '@laynezh/vite-plugin-lib-assets'

export default defineConfig({
  plugins: [
    libAssetsPlugin({
      limit: 1024 * 8,
      extensions: ['.jpg', '.png', '.otf', '.ttf', '.woff'],
    }),
  ],
})

Nice! Static resources will not be converted to BASE64, but converted to require relative path reference, the problem is perfectly solved.

It should be noted that when using the package by @laynezh/vite-plugin-lib-assets, your app needs to support the related loaders or plugins about the used static resources.