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

Vue3 Support #136

Open
milewski opened this issue Aug 18, 2020 · 47 comments
Open

Vue3 Support #136

milewski opened this issue Aug 18, 2020 · 47 comments

Comments

@milewski
Copy link

I think the dependency on template-compiler breaks with vue-3, is there any temporarily workaround?

@damianstasik
Copy link
Owner

@milewski I just released a new beta version with Vue 3 support, please check it out vue-svg-loader@beta. Please follow the updated configuration docs here: https://github.com/visualfanatic/vue-svg-loader/tree/dev#vue-cli.

@sritirunagari
Copy link

@visualfanatic Does the webpack config in the readMe file work for vue-svg-loader@beta ? Because svg doesn't load when I upgraded to beta in my vue-3 app I had set it up using webpack 4

@damianstasik
Copy link
Owner

@sritirunagari could you share your webpack config?

@sritirunagari
Copy link

@visualfanatic Thanks for getting back. Webpack config I used was :
module: {
rules: [
{
test: /.svg$/,
use: [
'vue-loader',
'vue-svg-loader'
],
}
]
}

It's exactly the same config you mentioned in your readMe file. In fact, I have also something else, I had taken a dump of this : vue-next-webpack and added the config, it still didn't pick up svg unfortunately.

Please let me know if i am not clear.

@damianstasik
Copy link
Owner

@sritirunagari could you provide a full configuration file? This snippet looks fine 🤔

@sritirunagari
Copy link

sritirunagari commented Sep 7, 2020

@visualfanatic Here, it is

const path = require('path')
const webpack = require('webpack')
const { VueLoaderPlugin } = require('vue-loader')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = (env = {}) => ({
  mode: env.prod ? 'production' : 'development',
  devtool: env.prod ? 'source-map' : 'eval-cheap-module-source-map',
  entry: path.resolve(__dirname, './src/main.js'),
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/'
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader'
      },
      {
        test: /\.png$/,
        use: {
          loader: 'url-loader',
          options: { limit: 8192 }
        }
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: { hmr: !env.prod }
          },
          'css-loader'
        ]
      },
      {
        test: /\.svg$/,
        use: [
          'vue-loader',
          'vue-svg-loader'
        ],
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    new MiniCssExtractPlugin({
      filename: '[name].css'
    }),
    new webpack.DefinePlugin({
      __VUE_OPTIONS_API__: 'true',
      __VUE_PROD_DEVTOOLS__: 'false'
    })
  ],
  devServer: {
    inline: true,
    hot: true,
    stats: 'minimal',
    contentBase: __dirname,
    overlay: true
  }
})

@damianstasik
Copy link
Owner

@sritirunagari that's weird, are you sure you are using the beta version?

@sritirunagari
Copy link

@visualfanatic , here is the dependencies overview from package.json

{ "private": true, "scripts": { "dev": "webpack-dev-server", "build": "webpack --env.prod" }, "dependencies": { "vue": "^3.0.0-rc.9" }, "devDependencies": { "@vue/compiler-sfc": "^3.0.0-rc.9", "babel-loader": "^8.1.0", "css-loader": "^4.2.2", "file-loader": "^6.0.0", "mini-css-extract-plugin": "^0.11.0", "url-loader": "^4.0.0", "vue-loader": "^16.0.0-beta.5", "vue-svg-loader": "^0.17.0-beta.1", "webpack": "^4.42.1", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3" } }

@damianstasik
Copy link
Owner

@sritirunagari this might be actual bug in the loader, not in your config, I will take a look at it later today.

@sritirunagari
Copy link

sritirunagari commented Sep 7, 2020

@visualfanatic
Infact when I try to run build script, I get the below error

`Module build failed (from ./node_modules/vue-svg-loader/index.js):
Error: Cannot find module 'svgo'
Require stack:

  • ****/vue-next-webpack-preview/node_modules/vue-svg-loader/index.js`

then I had installed svgo dependency, to see if it picks up, but no luck.

@sritirunagari
Copy link

@visualfanatic Sure, thank you, I will wait for your update

@sritirunagari
Copy link

sritirunagari commented Sep 8, 2020

@visualfanatic I have an update. I guess it would have been some mistake in my project settings. I am using a lerna mono-repo and apparently one of the packages didn't compile as expected. I am able to load svgs now.

However, I still see one more issue, the dependency throws error if I build my app without 'svgo' dependency as mentioned in my previous comment. So you might want to add this to your beta version to support webpack.

There is one more problem I came across when setting up jest to transform svgs as per your link ( click here ). Now that, we don't use template-compiler, what would you suggest from where to pull vueJest() from ?

Thanks in advance.

@damianstasik
Copy link
Owner

@sritirunagari Sorry for the delay, I finally found a bit of time to push a new release. I checked it using the vue-next-webpack-preview repo and it works, could you confirm?

@sritirunagari
Copy link

@visualfanatic Sorry, I had missed to reply.

Could you mention which issue have you fixed in your new release ? I have report two minor ones.

  • 'svgo' dependency missing
  • svgTransform.js setup for Vue-3 & Jest

@damianstasik
Copy link
Owner

@sritirunagari I fixed the missing svgo dependency issue. Could you share a simple repro with the Jest issue?

@onyx-blackbird
Copy link

onyx-blackbird commented Oct 16, 2020

I am also trying to use this in Vue3 which since a few weeks is officially released. Do we still need to use the vue-loader-v16 or is there an update.
And I'm trying to use this approach, but this also doesn't seem to work in Vue3, any ideas:
https://stackoverflow.com/a/59149533/3737177

EDIT: I just realized the documented approach also doesn't work for me (the file is there):
Cannot find module '@/assets/svg/trash_can_solid.svg' or its corresponding type declarations.

@prem-prakash
Copy link

@sritirunagari could you share your working configuration? I was not able to get it to work here.

@Tjark-Kuehl
Copy link

Tjark-Kuehl commented Nov 9, 2020

Using Typescript it doesn't work at all.
The svg types are outdated and doesn't work anymore.
You cannot compile with these errors.

Nvmd its fixable with this.

In Vue3 you need to define the Svg definition file like this

declare module '*.svg' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent;
    export default component;
}

@rightaway
Copy link

@visualfanatic Anything we can do to help get a stable version with Vue 3 support out?

@Keavon
Copy link

Keavon commented Mar 23, 2021

declare module '*.svg' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent;
    export default component;
}

Specifically for people running across this, you will want to add this to an index.d.ts file (any file name ending in .d.ts is fine). Then do one of the two following (the second option is better):

Add this to the top of your TypeScript file which is importing the SVGs:

/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="../path/to/your/index.d.ts"/>

Or (better), update your project root's tsconfig.json so the "include" array points to your .d.ts file, for example you can add this piece:

{
	"include": [
		"src/**/*.d.ts",
	],
}

I really hope this library can include these type definitions by default! This wasted about six hours of my life split between a few infuriating hours a month ago and again now upon revisiting it. Very glad I was able to finally solve this though.

@EmanueleCoppola
Copy link

Is there an ETA for the stable release?

@WhyNotHugo
Copy link

I also can't quite get this to work, but I'm getting an error I'm not seeing anyone else having:

 ERROR  Failed to compile with 1 error                                                                                                                                                                                                                                              4:06:30 PM

 error  in ./src/assets/upload.svg

Syntax Error: TypeError: Cannot read property 'parseComponent' of undefined


 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/PhotoManager.vue?vue&type=script&lang=ts 21:0-45 26:18-27
 @ ./src/components/PhotoManager.vue?vue&type=script&lang=ts
 @ ./src/components/PhotoManager.vue
 @ ./src/main.ts
 @ multi ./node_modules/@sentry/webpack-plugin/src/sentry-webpack.module.js ./src/main.ts

 ERROR  Build failed with errors.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Any ideas? This is my new vue.config.js:

module.exports = {
  // ...
  chainWebpack: (config) => {
    config.resolve.alias.set("vue", "@vue/compat");

    config.module
      .rule("vue")
      .use("vue-loader")
      .tap((options) => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 2,
            },
          },
        };
      });

    const svgRule = config.module.rule("svg");

    svgRule.uses.clear();

    svgRule
      .use("vue-loader")
      .loader("vue-loader")
      .end()
      .use("vue-svg-loader")
      .loader("vue-svg-loader");
  },
};

@jskitz
Copy link

jskitz commented Jul 27, 2021

@visualfanatic I have most everything working, except that I can no longer style any SVG files within my component using Vue 3. I don't know what changed between Vue 2 and Vue 3, but here is my very simple component:

<template>
  <div>
    <CameraIcon />
  </div>
</template>
<script>
import CameraIcon from './camera.svg'
export default {
  components: {
    CameraIcon
  }
}
</script>
<style lang='scss' scoped>
svg {
  path {
    transition: all .2s ease-in-out;
    fill: #c3c3c3;
  }
  &:hover {
    path {
      fill: black;
    }
  }
}
</style>

None of the styling works unless I remove scoped. For example, the hover state does not work. But if I remove scoped, then it works but the stylings bleed into other components. I am on version 0.17.0-beta.2. This behavior is different than what I saw in Vue 2.

Also, I am using Vue CLI and have the following config:

  chainWebpack: config => {
    config.resolve.alias.set('vue', '@vue/compat');

    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 3
            }
          }
        }
      });

    const svgRule = config.module.rule('svg');
    svgRule.uses.clear();
    svgRule
      .use('vue-loader')
      .loader('vue-loader')
      .end()
      .use('vue-svg-loader')
      .loader('vue-svg-loader');
  }
};

@Keavon
Copy link

Keavon commented Jul 27, 2021

Just in case it helps anyone figure this out, I was able to get it working in my project, here is the repo: https://github.com/GraphiteEditor/Graphite and here is the vue.config.js: https://github.com/GraphiteEditor/Graphite/blob/master/frontend/vue.config.js

@jskitz
Copy link

jskitz commented Jul 28, 2021

@Keavon I took a look and I also have it working, but my main problem with the latest, is that I have to remove scoped in all of my CSS to use this library now.

Does anyone have any idea what changed between Vue 2 and Vue 3 that requires me to remove scoped on all of my CSS? This is certainly not just a slap in replacement to what was there. Every module that contains an SVG file that I styled based on different states like hover, I've had to remove scoping. I've also asked this question in the Vue Discord channel, and the suggestion (which I'm doing), is to add a class to every component that includes an SVG file, and remove the scoped so that I can move forward for now. I don't really want to unscope all of my styles to make this work. Anyone else running into this?

@phoenix-ru
Copy link

@Keavon I took a look and I also have it working, but my main problem with the latest, is that I have to remove scoped in all of my CSS to use this library now.

Does anyone have any idea what changed between Vue 2 and Vue 3 that requires me to remove scoped on all of my CSS? This is certainly not just a slap in replacement to what was there. Every module that contains an SVG file that I styled based on different states like hover, I've had to remove scoping. I've also asked this question in the Vue Discord channel, and the suggestion (which I'm doing), is to add a class to every component that includes an SVG file, and remove the scoped so that I can move forward for now. I don't really want to unscope all of my styles to make this work. Anyone else running into this?

That is the way scoped works in general. It will parse all the classes/elements in your SFC and apply scope for them. Since you don't explicitly use SVG in the template, the scoped will ignore it (no matter if it appears later or not).

@giovannidias1
Copy link

i getting the following error after update

in ./Assets/icon/category/administracao.svg?component
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: C:\Users\giova\Documents\Project\Project\Project\Assets\icon\category\administracao.svg: Unexpected token, expected "</>/<=/>=" (1:15)

> 1 | <template><svg xmlns="http://www.w3.org/2000/svg" width="32pt" height="32pt" viewBox="0 0 32 32"><path d="M22.719 2.5l-.375 1.063-.313.906A13.009 13.009 0 0016 3C8.832 3 3 8.832 3 16s5.832 13 13 13 13-5.832 13-13c0-1.695-.344-3.297-.938-4.781l1.125-.406 1.032-.344-.438-1A13.045 13.045 0 0023.72 3zm-7.844 2.563c.043-.004.082.003.125 0V15H5.062c.473-5.242 4.586-9.41 9.813-9.938zm2.125 0c1.55.14 3.016.597 4.313 1.312l-2.25 6.281-.72 2 2-.719 5.845-2.062C26.703 13.148 27 14.539 27 16c0 2.68-.945 5.125-2.531 7.031L17 15.563zm6.781.437a10.797 10.797 0 013.563 3.844l-5.688 2zM5.063 17h10.5l7.468 7.469A10.937 10.937 0 0116 27c-5.75 0-10.434-4.387-10.938-10z"/></svg></template>
    |                ^
    at Object._raise (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:798:17)
    at Object.raiseWithData (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:791:17)
    at Object.raise (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:752:17)
    at Object.unexpected (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:3257:16)
    at Object.expectRelational (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:3176:12)
    at Object.tsParseTypeAssertion (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:8424:10)
    at Object.parseMaybeUnary (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:9556:19)
    at Object.parseExprOps (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10882:23)
    at Object.parseMaybeConditional (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10856:23)
    at Object.parseMaybeAssign (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10814:21)

this ocurrers in all my svg files i'm using webpack

@tsiotska
Copy link

I also can't quite get this to work, but I'm getting an error I'm not seeing anyone else having:

 ERROR  Failed to compile with 1 error                                                                                                                                                                                                                                              4:06:30 PM

 error  in ./src/assets/upload.svg

Syntax Error: TypeError: Cannot read property 'parseComponent' of undefined


 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/PhotoManager.vue?vue&type=script&lang=ts 21:0-45 26:18-27
 @ ./src/components/PhotoManager.vue?vue&type=script&lang=ts
 @ ./src/components/PhotoManager.vue
 @ ./src/main.ts
 @ multi ./node_modules/@sentry/webpack-plugin/src/sentry-webpack.module.js ./src/main.ts

 ERROR  Build failed with errors.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Any ideas? This is my new vue.config.js:

module.exports = {
  // ...
  chainWebpack: (config) => {
    config.resolve.alias.set("vue", "@vue/compat");

    config.module
      .rule("vue")
      .use("vue-loader")
      .tap((options) => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 2,
            },
          },
        };
      });

    const svgRule = config.module.rule("svg");

    svgRule.uses.clear();

    svgRule
      .use("vue-loader")
      .loader("vue-loader")
      .end()
      .use("vue-svg-loader")
      .loader("vue-svg-loader");
  },
};

You've forgotten to use 'vue-loader-v16' instead of 'vue-loader'

@WhyNotHugo
Copy link

Thank for the hint, vue-loader-v16 fixed that particular issue. I did a few more tweaks, and now I'm stuck again seeing:

 ERROR  Failed to compile with 1 error                                                                                               3:51:30 PM

This relative module was not found:

* ../assets/xmas.svg in ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/Modal.vue?vue&type=script&lang=ts
 ERROR  Build failed with errors.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
 node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

RpcIpcMessagePortClosedError: Cannot send the message - the message port has been closed for the process 1615.
    at /app/node_modules/fork-ts-checker-webpack-plugin-v5/lib/rpc/rpc-ipc/RpcIpcMessagePort.js:47:47
    at processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: undefined,
  signal: undefined
}

This is my current vue.config.js:

module.exports = {
  // ...
  chainWebpack: (config) => {
    config.resolve.alias.set("vue", "@vue/compat");

    config.module
      .rule("vue")
      .use("vue-loader")
      .tap((options) => {
        return {
          ...options,
          compilerOptions: {
            compatConfig: {
              MODE: 2,
            },
          },
        };
      });

    const svgRule = config.module.rule("svg");
    svgRule.uses.clear();
    svgRule
      .use("vue-loader-16")
      .loader("vue-loader-16")
      .end()
      .use("vue-svg-loader")
      .loader("vue-svg-loader");
  },
};

The file path seems correct (and hasn't changed since the working Vue2 setup):

$ ag xmas.svg
src/components/Modal.vue
18:import XMas from "../assets/xmas.svg";

$ fd xmas.svg
src/assets/xmas.svg

I think my src/assets/svgs.d.ts is also relevant, and should be correct (also unchanged since Vue2):

// From https://vue-svg-loader.js.org/faq.html#how-to-use-this-loader-with-typescript
// Required to avoid TS complaining about the SVGs not being proper modules.
declare module "*.svg" {
  import Vue, { VueConstructor } from "vue";

  const content: VueConstructor<Vue>;
  export default content;
}

Any ideas what's up here?

@AasmundEndresen
Copy link

@sritirunagari I fixed the missing svgo dependency issue. Could you share a simple repro with the Jest issue?

This Jest issue seem to still be a problem - the solution described in the docs simply doesnt work. Its very easy to reproduce, as if you try to run a test using a svg as a component in any project it will fail.

@SherinBloemendaal
Copy link

SherinBloemendaal commented Sep 20, 2021

i getting the following error after update

in ./Assets/icon/category/administracao.svg?component
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: C:\Users\giova\Documents\Project\Project\Project\Assets\icon\category\administracao.svg: Unexpected token, expected "</>/<=/>=" (1:15)

> 1 | <template><svg xmlns="http://www.w3.org/2000/svg" width="32pt" height="32pt" viewBox="0 0 32 32"><path d="M22.719 2.5l-.375 1.063-.313.906A13.009 13.009 0 0016 3C8.832 3 3 8.832 3 16s5.832 13 13 13 13-5.832 13-13c0-1.695-.344-3.297-.938-4.781l1.125-.406 1.032-.344-.438-1A13.045 13.045 0 0023.72 3zm-7.844 2.563c.043-.004.082.003.125 0V15H5.062c.473-5.242 4.586-9.41 9.813-9.938zm2.125 0c1.55.14 3.016.597 4.313 1.312l-2.25 6.281-.72 2 2-.719 5.845-2.062C26.703 13.148 27 14.539 27 16c0 2.68-.945 5.125-2.531 7.031L17 15.563zm6.781.437a10.797 10.797 0 013.563 3.844l-5.688 2zM5.063 17h10.5l7.468 7.469A10.937 10.937 0 0116 27c-5.75 0-10.434-4.387-10.938-10z"/></svg></template>
    |                ^
    at Object._raise (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:798:17)
    at Object.raiseWithData (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:791:17)
    at Object.raise (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:752:17)
    at Object.unexpected (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:3257:16)
    at Object.expectRelational (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:3176:12)
    at Object.tsParseTypeAssertion (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:8424:10)
    at Object.parseMaybeUnary (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:9556:19)
    at Object.parseExprOps (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10882:23)
    at Object.parseMaybeConditional (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10856:23)
    at Object.parseMaybeAssign (C:\Users\giova\Documents\Project\Project\Project\node_modules\@babel\core\node_modules\@babel\parser\lib\index.js:10814:21)

this ocurrers in all my svg files i'm using webpack

+1 After npm update everything broke. I did an vue inspect on my config before the update and after the update, no big differences so i don't really know whats causing this.

@ajerez
Copy link

ajerez commented Sep 22, 2021

I'm getting this error, yesterday all was working good:

error in ./src/assets/img/wysiwyg/strike.svg

Module parse failed: Unexpected token (1:0)
File was processed with these loaders:

  • ./node_modules/vue-loader-v16/dist/index.js
  • ./node_modules/vue-svg-loader/index.js
    You may need an additional loader to handle the result of these loaders.

@drewcauchi77
Copy link

drewcauchi77 commented Sep 22, 2021

Same error as @ajerez . Building my project through webpack was working a few days ago but stopped working today due to issues within the SVGs.

Module parse failed: Unexpected token (1:0)
File was processed with these loaders:

  • vue-loader
  • vue-svg-loader

You may need an additional loader to handle the result of these loaders.

@drewcauchi77
Copy link

I have managed to solve the issue quoted by @ajerez and myself above by upgrading vue-loader to version 16.5.0. Below are the versions that I am currently using with Vue 3.1.4 - build was successful.

"vue-loader": "16.5.0"
"vue-svg-loader": "^0.17.0-beta.2"

My webpack build for svg files is as per below (specific to my project):

module.exports = {
    ...
    module: {
        rules: [
            ...,
            {
                test: /\.vue$/, 
                use: 'vue-loader' 
            },
            ...,
           {
                test: /\.svg$/, 
                oneOf: [
                    // test.svg?inline
                    // Used mainly to include an svg as a background in CSS for example
                    { resourceQuery: /inline/, use: 'url-loader' },
                    { use: ["vue-loader", "vue-svg-loader"] },
                ],
            },
            ...,
        ]
    },
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.esm-bundler.js'
        }
    },
    ...,
};

Hope this helps!

@jskitz
Copy link

jskitz commented Sep 23, 2021

I tried to upgrade vue-loader to the latest, which is version 16.8.1. I get this error with the latest version of vue-loader:

Module parse failed: Unexpected token (1:0)
File was processed with these loaders:
 * ./node_modules/vue-loader/dist/index.js
 * ./node_modules/vue-svg-loader/index.js
You may need an additional loader to handle the result of these loaders.

I know that it works correctly with version 16.5.0 so I wanted to see in what version it breaks. It turns out, that if you upgrade vue-loader to version 16.6.0, it will break when trying to compile SVG files. For now, I'm going to stay on version 16.5.0, but just wanted to mention this here. If you upgrade vue-loader, you may run into this problem. I'm going to continue trying to figure out what the problem is and will post a solution if I find it.

@supryantowp
Copy link

I tried to upgrade vue-loader to the latest, which is version 16.8.1. I get this error with the latest version of vue-loader:

Module parse failed: Unexpected token (1:0)
File was processed with these loaders:
 * ./node_modules/vue-loader/dist/index.js
 * ./node_modules/vue-svg-loader/index.js
You may need an additional loader to handle the result of these loaders.

I know that it works correctly with version 16.5.0 so I wanted to see in what version it breaks. It turns out, that if you upgrade vue-loader to version 16.6.0, it will break when trying to compile SVG files. For now, I'm going to stay on version 16.5.0, but just wanted to mention this here. If you upgrade vue-loader, you may run into this problem. I'm going to continue trying to figure out what the problem is and will post a solution if I find it.

have you found a solution?

@Nikkolast88
Copy link

what happened ?

in ./src/assets/404.svg?component

Module parse failed: Unexpected token (1:0)
File was processed with these loaders:

  • ./node_modules/@vue/cli-service/node_modules/vue-loader-v16/dist/index.js
  • ./node_modules/vue-svg-loader/index.js
    You may need an additional loader to handle the result of these loaders.

vue.config.js
chainWebpack: (config) => {
const svgRule = config.module.rule('svg');

svgRule.uses.clear();
config.resolve.alias.set('@', path.resolve('./src'));
config.resolve.alias.set('vue-i18n', 'vue-i18n/dist/vue-i18n.cjs.js');

svgRule
  .oneOf('component')
  .resourceQuery(/component/)
  .use('vue-loader')
  .loader('vue-loader-v16')
  .end()
  .use('vue-svg-loader')
  .loader('vue-svg-loader')
  .end()
  .end()
  .oneOf('external')
  .use('file-loader')
  .loader('file-loader')
  .options({
    name: 'assets/[name].[hash:8].[ext]',
  });

};

@thimonwentink
Copy link

@sritirunagari I fixed the missing svgo dependency issue. Could you share a simple repro with the Jest issue?

This Jest issue seem to still be a problem - the solution described in the docs simply doesnt work. Its very easy to reproduce, as if you try to run a test using a svg as a component in any project it will fail.

Is there a solution yet?

@bradleySuira
Copy link

bradleySuira commented Oct 29, 2021

Tested this and works https://www.npmjs.com/package/vue-cli-plugin-svg-vue3

  • "vue": "^3.2.1"
  • "vue-cli-plugin-svg": "~0.2.1"

*** Some issues with chrome to render with img tag src so at the end I'm using the inline option.

@davolcu
Copy link

davolcu commented Feb 23, 2022

Is there any progress in moving this from beta to rc?

@Keavon
Copy link

Keavon commented Feb 23, 2022

This might not be the best advice for everyone but it was helpful to me and possibly will for others: if you don't care about minifying your SVG code, you don't need to use vue-svg-loader at all. You can write your own replacement for this entire library in four lines:

module.exports = function VueSvgLoader(svg) {
	this.cacheable();
	return `<template>${svg}</template>`;
};

(I put this in vue-svg-loader.js at the Vue project root, a sibling of vue.config.js)

Then just import it in your vue.config.js:

// Change the loaders used by the Vue compilation process
config.module
	// Replace Vue's existing base loader by first clearing it
	// https://cli.vuejs.org/guide/webpack.html#replacing-loaders-of-a-rule
	.rule("svg")
	.uses.clear()
	.end()
	// Add vue-loader as a loader for Vue single-file components
	// https://www.npmjs.com/package/vue-loader
	.use("vue-loader")
	.loader("vue-loader")
	.end()
	// Add vue-svg-loader as a loader for importing .svg files into Vue single-file components
	// Located in ./vue-svg-loader.js
	.use("./vue-svg-loader")
	.loader("./vue-svg-loader")
	.end();

This also saves like 80 megabytes worth of junk in node_modules from transitive dependencies (like the SVG minifier).

@719media
Copy link

@Keavon Are you using vue cli v5?

@Keavon
Copy link

Keavon commented Feb 26, 2022

@Keavon Are you using vue cli v5?

My attempt to upgrade has not been successful yet.

@dylan904
Copy link

dylan904 commented Oct 4, 2022

Please follow the updated configuration docs here: https://github.com/visualfanatic/vue-svg-loader/tree/dev#vue-cli.

So this updated fix is for Vue 3. In the updated configuration docs, it shows for Nuxt 1 & 2, but not 3. Would you be able to add supported config for Nuxt 3 as well?

@Max-0n
Copy link

Max-0n commented Mar 29, 2023

Oh guys.... I spent a lot of hours to find work solution 😅
Sharing that for you ❤️

const FILE_RE = /\.(vue|js|ts|svg)$/

// Use vue-cli's default rule for svg in non .vue .js .ts files
config.module.rule('svg').issuer(file => !FILE_RE.test(file));

// Use our loader to handle svg imported by other files
config.module
  .rule('svg-component')
  .test(/\.svg$/)
  // .issuer(file => FILE_RE.test(file))
  .use('vue-loader')
  .loader('vue-loader')
  .end()
  .use("vue-svg-loader")
  .loader("vue-svg-loader");

@kvas-damian
Copy link

In my case - VueCli builds library (--target lib), webpack was exporting svgs as regular asset imports:

/***/ 7505:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
module.exports = __webpack_require__.p + "img/sliders-search.978ca729.svg";

/***/ }),

solved that by removing type and generator from store attribute on svg rule:

		// remove properties which breaks vue-svg-loader output
		svgRule.store.delete('generator');
		svgRule.store.delete('type');

full chanWebpack() in vue.config.js:

module.exports = {
	chainWebpack: (config) => {
		const svgRule = config.module.rule('svg');

		svgRule.uses.clear();

		// remove properties which breaks vue-svg-loader output
		svgRule.store.delete('generator');
		svgRule.store.delete('type');

		svgRule
			.use('vue-loader')
			.loader('vue-loader')
			.end()
			.use('vue-svg-loader')
			.loader('vue-svg-loader');
	},
};

@VladiStep
Copy link

Using Typescript it doesn't work at all. The svg types are outdated and doesn't work anymore. You cannot compile with these errors.

Nvmd its fixable with this.

In Vue3 you need to define the Svg definition file like this

declare module '*.svg' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent;
    export default component;
}

You can make it recognize the element as <svg> like this:

declare module '*.svg' {
  import type { SVGAttributes, DefineComponent } from 'vue';

  const content: DefineComponent<SVGAttributes>;
  export default content;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests