Giter Club home page Giter Club logo

vite-svg-sprite-wrapper's Introduction

vite-svg-sprite-wrapper

npm package

svg-sprite wrapper for Vite

Install

npm i vite-svg-sprite-wrapper -D

Usage

Add it to your plugins in vite.config.ts

import { defineConfig } from 'vite'
import ViteSvgSpriteWrapper from 'vite-svg-sprite-wrapper';

export default defineConfig({
  plugins: [
    ViteSvgSpriteWrapper({
      /**
       * Input directory
       *
       * @default 'src/assets/images/svg/*.svg'
       */
      icons?: string
      /**
       * Output directory
       *
       * @default 'src/public/images'
       */
      outputDir?: string

      /**
       * sprite-svg {@link https://github.com/svg-sprite/svg-sprite/blob/main/docs/configuration.md#sprite-svg-options|options}
       */
      sprite?: SVGSpriter.Config
      /**
       * Defines if a type should be generated
       * @default false
       */
      generateType?: boolean
      /**
       * Name of the type to be used when generateType is set to true
       * @default 'SvgIcons'
       */
      typeName?: string
      /**
       * File name of the generated type file
       * @default 'svg-icons'
       */
      typeFileName?: string
      /**
       * Name of the output directory for generated type file
       * @default '{@link icons} directory'
       */
      typeOutputDir?: string
    }),
  ],
})

Now, any changes to the .svg files in the icons folder will generate a sprite.svg in the outputDir folder.

So you can use the icons somehow (Example):

<svg class="icon" aria-hidden="true">
  <use xlink:href="/images/sprite.svg#star"></use>
</svg>

Example of React Component:

Config:

ViteSvgSpriteWrapper({
  outputDir: 'public',
  generateType: true,
  typeName: 'IIcon',
  typeFileName: 'Icon',
  typeOutputDir: './src/type',
})

Component:

import type { IIcon } from './src/type/Icon'

import sprite from '/sprite.svg'

interface Props {
  icon: IIcon
}

function Icon({ icon }: Props) {
  return (
    <svg class="icon" aria-hidden="true">
      <use xlinkHref={`${sprite}#${icon}`}></use>
    </svg>
  )
}

export default Icon

MIT License © 2024 Volodymyr Shepel

vite-svg-sprite-wrapper's People

Contributors

13twelve avatar jameswragg avatar vshepel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vite-svg-sprite-wrapper's Issues

Build task writeBundle will happen after the project has been built

First, thanks for making this wrapper.

Not sure if this is an issue with other people, or if this is just a pattern that I have gotten wrong.

We are not saving the sprite sheet in source control because it is a generated asset and would just cause merge conflicts (assume that's reasonably normal behaviour for most people). Our issue is that we are using that sprite file in our react app and to generate typescript types so will cause the build to fail because the file doesn't exist until the writeBundle event has happened after the build.

Is there an config option that I can set, or have some way of running it earlier in the build process?

List the names of the files as a typescript type

Hello,

Thank you for this wrapper, we're using it to reduce the overhead of using SVG icons in our code.

We'd love to have the name of the symbols inside the sprite.svg as a typescript type. We can then use it to accept a name property in an Icon component (with React, Vue, ...).

import sprite from './sprite.svg';

export function Icon({name}) => (
  <svg>
    <use href={`${sprite}#${name}`} />
  </svg>
)

I can create a pull request, I just want to make sure this isn't yet possible before writing code :)

Sprite is not being served

Hi,

everything works fine on build/prod mode, but during the serve-mode the svg-sprite is not accessible.
It gets requested via https://MY_IP:3000/static/app/dist/svg-icons.svg, but is not being served by vite.

My code:

ViteSvgSpriteWrapper({
      icons: './assets/base/icons/**/*.svg',
      outputDir: './public/static/app/dist/',
      sprite: {
          shape: {
              transform: ['svgo'],
          },
          mode: {
              symbol: {
                  dest: '.',
                  sprite: 'svg-icons.svg',
              },
          },
      },
  }),

In build mode it gets listed in the manifest and everything looks great. Any idea why it is not being served?

(also tried other outputDir, etc.)

Sprite SVG option: "mode.symbol.sprite" causes infinite loop during vite build watch

Thanks for creating this plugin, it is really helpful to setup an svg sprite setup for my Shopify theme repo.

In configuring the plugin, I attempted to rename the outputed file to svg-sprites.liquid as that is the extension I need it in.

To do so, I set up the plugin like this:

ViteSvgSpriteWrapper({
  icons: 'src/icons/*.svg',
  outputDir: 'shopify/snippets',
  sprite: {
    mode: {
      symbol: {
        sprite: '../svg-sprites.liquid', // rename
      },
    },
    shape: { ... },
  },
});

After making this update, when I run vite build --watch from the command line, the project builds over and over in an infinite loop even though I'm not changing any of the watched files.

Do you happen to know why this might be happening? Any help is appreciated.

emptyOutDir immediately removes the generated sprite

Hi,

By default build.emptyOutDir is true, but this removes the sprite as soon as it’s generated if the outputdir is within build.outDir:

import { defineConfig } from 'vite';
import ViteSvgSpriteWrapper from 'vite-svg-sprite-wrapper';

export default defineConfig({
  plugins: [
    ViteSvgSpriteWrapper({
      icons: 'src/images/icons/*.svg',
      outputDir: './dist',
    }),
  ],
  build: {
    assetsDir: '',
    emptyOutDir: true,
    copyPublicDir: false,
    manifest: true,
    outDir: './dist',
    rollupOptions: {
      input: [
        'src/js/app.js'
      ]
    },
  },
});

`outputDir` to `dist/`

How can I output the sprite in the dist/ folder ?
The default outputDir is in the source folder which is very strange, I don't want to commit the sprite, only the originals.
So I changed the outputDir to dist/, but it doesn't seem to work.
I suspect this run and create the file, but then Vite overwrite the folder ?

Sprite error Error: ENOENT: no such file or directory

Paths are broken on Windows.

If i have this config:

ViteSvgSpriteWrapper({
  icons: "./src/assets/icons/*.svg",
  outputDir: "./src/assets",
  sprite: {
    mode: {
      symbol: {
        dest: "",
        sprite: "icons.svg",
      },
    },
  },
}),

plugin throws an error:

vite v5.2.11 building for production...
[vite-plugin-svg-sprite] Sprite error Error: ENOENT: no such file or directory, open 'C:\Users\artus\Work\project\C:\Users\artus\Work\project\src\assets\icons.svg'

because as i see in the node_modules source code here:

112: return sprite.path.replace(`${root}/`, ""); // this does not replace anything on Windows

or here:

144: const source = readFileSync(`${root}/${path}`); // this creates completely wrong path on Windows, because of 112 line

there are incorrect slashes which does not work in Windows environment.

Manifest support

I've been looking for a SVG Sprite plugin for ages that does what I need & this is SO close. Thanks for building it!

I noticed that because the plugin doesn't use Rollup's emitFile method, it can’t support filename hashing & won't ever be added to the manifest.json.

I'd love to be able to use the manifest in production to reference the hashed sprite like so:

{
  "sprite.svg": {
    "file": "assets/sprite.2ffa3d27.svg",
    "src": "sprite.2ffa3d27.svg"
  },

The sprite is not rebuilt in development mode

Hello. In build mode, when the server is running, I add new files to the folder with icons or delete them from there, but the sprite is not rebuilt. The sprite is collected only when running "npm run dev" or during the build "npm run build". I am inserting the code with a picture because it is inserted crookedly.

image

image

Doesn't appear to run on build?

The sprite.svg is only generated when an svg changes while the vite server is active: running vite build will not generate the sprite.

Similarly, running vite without making a change to the svgs will also not generate the sprite - only when I add/amend an svg to the defined icons folder.

Is this intended behaviour?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.