Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] Improve bundler config #795

Closed
ptandler opened this issue Apr 2, 2022 · 7 comments
Closed

[Enhancement] Improve bundler config #795

ptandler opened this issue Apr 2, 2022 · 7 comments
Labels
enhancement New feature or request

Comments

@ptandler
Copy link

ptandler commented Apr 2, 2022

I started to migrate my homepage from VuePress 1 to 2 and also used this opportunity to give Vite a try.

With VuePress 1 and web pack, I used the vue-svg-loader plugin to allow inline SVG. I'm stuck to port this to VuePress 2 and Vite.

I found vite-svg-loader which looks pretty comparable. But I've got no idea how to use it.

In the documentation I read that one can add custom Vite config via viteOptions:

const svgLoader = require('vite-svg-loader')
// ...
module.exports = {
// ...
  bundlerConfig: {
    viteOptions: {
      plugins: [svgLoader()]
    }
  },
// ...
}

and within a custom Vue component I do:
'm stuck

<template>
    <ComponentLogo/>
</template>
<script>
import logo from "./stack-overflow-logo.svg?inline"

export default {
    name: "name",
    props: {
// ...
    },
    components: {ComponentLogo: logo},
//...
  }
</script>

But I get an error:

Uncaught (in promise) DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('.../global-components/Social/stack-overflow-logo.svg?inline') is not a valid name.
    at createElement

I interpret this that the imported SVG is treated as HTML or JS, but not SVG. Correct?

Coming back from this specific case to my general point: I really would appreciate to get a better explanation, and ideally also some complete and working examples of how to use Vite options and plugins. Thanks! 🙏

@Mister-Hope
Copy link
Member

Mister-Hope commented Apr 3, 2022

// .vuepress/config.ts
import svgLoader from "vite-svg-loader";

export default {
  // ...
  plugins: [
    // ...
    {
      name: "svg-loader",
      onInitialized: (app) => {
        if (app.bundler.endsWith("vite")) {
          app.bundlerConfig.viteOptions.plugins.push(svgLoader());
        } else {
          // do samething with webpack
        }
      },
    },
  ],
};

Try this

@ptandler
Copy link
Author

ptandler commented Apr 6, 2022

Hi @Mister-Hope, thanks for your suggestion. I just needed to tweak it a bit: The first thing I noticed is that it should be app.options.bundler, while app.bundler is undefined. And then, the plugins array can be empty. So I use this now:

// .vuepress/config.ts
import svgLoader from "vite-svg-loader";

export default {
  // ...
  plugins: [
    {
      name: "svg-loader",
      onInitialized: (app) => {
        console.log(JSON.stringify(app.options))
        if (app.options.bundler.endsWith("vite")) {
          app.options || (app.options = {});
          app.options.bundlerConfig || (app.options.bundlerConfig = {});
          app.options.bundlerConfig.viteOptions || (app.options.bundlerConfig.viteOptions = {});
          app.options.bundlerConfig.viteOptions.plugins || (app.options.bundlerConfig.viteOptions.plugins = []);
          app.options.bundlerConfig.viteOptions.plugins.push(svgLoader());
        } else {
          // do same thing with webpack
        }
      },
    },
  ]
};

However, my original issue remains: This should be part of the docs!

And: As the docs say that I can add bundlerConfig.viteOptions to the VuePress config, why do I have to do it this way via the onInitialized hook? Really not straightforward for a thing that I regard as quite common use case.

In fact, I know that I use vite only and not webpack, so do I have to care about checking the configured bundler?

@Mister-Hope
Copy link
Member

Mister-Hope commented Apr 6, 2022

It seems that svgloader needs to be loaded after vueLoader to work, but currently it can only be loaded before vueLoader, I had a discussion with meteorlxy of this yesterday, we will add a new option in feature to solve this, allowing you edit the config after vuepress config is injected.

@Mister-Hope
Copy link
Member

It's not part of documentation thing.

@Mister-Hope Mister-Hope added the enhancement New feature or request label Apr 6, 2022
@Mister-Hope Mister-Hope changed the title [Docs Improvement] Please improve the documentation of Vite, viteOptions, vite plugins [Enhancement] Improve bundler config Apr 6, 2022
@Mister-Hope
Copy link
Member

You may need to wait a little bit for this, see #602 (comment)

@meteorlxy
Copy link
Member

It seems that svgloader needs to be loaded after vueLoader to work, but currently it can only be loaded before vueLoader

Well, I just took a look at vite-svg-loader. Seems that it has enforce: 'pre':

https://github.com/jpkleemans/vite-svg-loader/blob/816f309a7235dad6d26d24aff045218a023f2d29/index.js#L13

@meteorlxy
Copy link
Member

meteorlxy commented Jun 11, 2022

Closing as I've tested with import IconComponent from './foo.svg?component' and it works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants