vshepel / vite-svg-sprite-wrapper

Creating one sprite file on the fly
27 stars 5 forks source link

Sprite is not being served #13

Open janein opened 4 months ago

janein commented 4 months ago

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.)

vshepel commented 4 months ago

@janein Hi

How do you set the path to the sprite? Like this?

<svg class="icon" aria-hidden="true">
  <use xlink:href="/static/app/dist/svg-icons.svg#star"></use>
</svg>
janein commented 4 months ago

@vshepel yes it's getting requested with this path via my local IP. Just like every other asset.

FYI: I work with a symfony setup, so the path gets generated by the vite-bundle: https://github.com/lhapaipai/vite-bundle

vshepel commented 4 months ago

@janein Send me the full vite configuration. Because on my local example everything works correctly, most likely the problem is in "vite-bundle" or maybe wrong path

janein commented 4 months ago

Of course! I removed the parts which are too custom, to keep it clear for you:

export default defineConfig(async ({ mode }) => {
    process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
    const certificatesBasePath = os.homedir() + '/.vite-plugin-mkcert/';
    const bsCerts = {
        key: path.resolve(certificatesBasePath + 'dev.pem'),
        cert: path.resolve(certificatesBasePath + 'cert.pem'),
    };

    return {
        root: './',
        publicDir: './public/',

        plugins: [
            mkcert(),
            tsconfigPaths(),
            symfonyPlugin({
                refresh: process.env?.VITE_TEMPLATE_RELOADING === 'true' ? ['templates/**/*.twig'] : false,
            }),
            VitePWA({
                  manifest,
                  injectRegister: null,
                  workbox: {
                      navigateFallback: null,
                  },
            }),
            ViteSvgSpriteWrapper({
                /**
                 * Input directory
                 *
                 * @default 'src/assets/images/svg/*.svg'
                 */
                icons: './assets/base/icons/**/*.svg',
                outputDir: './assets/base/images/',
            }),
            VitePluginBrowserSync({
                dev: {
                    bs: {
                        proxy: APP_URL,
                        https: bsCerts,
                        cors: true,
                        port,
                        ui: false,
                    },
                },
            }),
            viteStaticCopy({ /* copies static images (other directory than svg-icons!) */ }),
            splitVendorChunkPlugin(),
        ],
        base: `/static/app/dist/`,
        build: {
            // output dir for production build
            outDir: `./public/static/app/dist`,
            emptyOutDir: true,

            // disable inlining of assets
            assetsInlineLimit: 0,

            // emit manifest so PHP can find the hashed files
            manifest: true,
            ssrEmitAssets: true,

            // our entry
            rollupOptions: {
                input: {
                    app: './assets/main.ts',
                },
            },

            // set to "false" to create a single css file
            cssCodeSplit: false,
        },
        server: {
            // use local ip to make it accessible via network
            origin: `https://${ip.address()}:3000`,
            // required to load scripts from custom host
            cors: true,
            strictPort: true,
            port,
            hmr: true,
            watch: {
                ignored: ['!assets/**', '!templates/**', '**/vendor/**', '**/public/**', '**/var/**'],
            },
        },
        resolve: {
            alias: {
                // my custom aliases
            },
        },
    };
});

And this is my twig-file for the svg-icons:

{# namespace and name are being used to build the id of the icon #}
<span class="svg-icon">
    <svg>
        <use xlink:href="{{ asset('svg-icons.svg', 'app') }}#{{ namespace }}--{{ name }}"></use>
    </svg>
</span>

But as you said, I guess there is a good chance, the issue lies within the vite-bundle for symfony...

janein commented 3 weeks ago

@vshepel I looked at it again and as far as i can see the file is not being serverd by ViteDevServer correctly. If i request it directly in a new tab, it loads just fine, but as an inline request from the html, it gets blocked by CORS. As it is not server by the devserver, my settings to allow CORS are not working. Any idea how to fix this?