Vue-svg-loader: How to add it to Jest configuration?

Created on 25 Jul 2018  ·  10Comments  ·  Source: visualfanatic/vue-svg-loader

The MyComponent is importing an SVG file, and then using it in the code. I cannot unit test such component because vue-svg-loader is not configured in my Jest.

import { shallowMount } from "@vue/test-utils";
import MyComponent from "../MyComponent";

describe("MyComponent.vue", () => {
    it("should put new date if is was passed via props", async () => {
        const wrapper = shallowMount(MyComponent, {
            propsData: {
                value: "2018-01-05"
            }
        });

The unit test throws... Cannot render the SVG.

How to add vue-svg-loader to the Jest configuration?

Docs mention

Most helpful comment

There is one major issue when it comes to integrating vue-svg-loader with Jest, and it is async behaviour. Jest's transforms are synchronous, webpack loaders can be both. That means we cannot use SVGO to process the SVG files, which can be bad in some cases. I suggest you and everybody to always pass the SVG files through SVGO before putting them in a project (for example using this great tool), so that the end result does not contain:

  • XML declaration,
  • <script> tags,
  • <style> tags.

If your SVGs are prepared, create a transform file named for example svgTransform.js with:

const vueJest = require('vue-jest/lib/template-compiler');

module.exports = {
  process(content) {
    const { render } = vueJest({
      content,
      attrs: {
        functional: false,
      },
    });

    return `module.exports = { render: ${render} }`;
  },
};

And then modify your jest.config.js to use the transform file above (note that <rootDir> is injected by Jest):

module.exports = {
  transform: {
    '^.+\\.svg$': '<rootDir>/path/to/svgTransform.js',
  },
};

To test if everything works you need to start the tests with the --no-cache flag. Let me know if that works for you.

All 10 comments

There is one major issue when it comes to integrating vue-svg-loader with Jest, and it is async behaviour. Jest's transforms are synchronous, webpack loaders can be both. That means we cannot use SVGO to process the SVG files, which can be bad in some cases. I suggest you and everybody to always pass the SVG files through SVGO before putting them in a project (for example using this great tool), so that the end result does not contain:

  • XML declaration,
  • <script> tags,
  • <style> tags.

If your SVGs are prepared, create a transform file named for example svgTransform.js with:

const vueJest = require('vue-jest/lib/template-compiler');

module.exports = {
  process(content) {
    const { render } = vueJest({
      content,
      attrs: {
        functional: false,
      },
    });

    return `module.exports = { render: ${render} }`;
  },
};

And then modify your jest.config.js to use the transform file above (note that <rootDir> is injected by Jest):

module.exports = {
  transform: {
    '^.+\\.svg$': '<rootDir>/path/to/svgTransform.js',
  },
};

To test if everything works you need to start the tests with the --no-cache flag. Let me know if that works for you.

@koresar have you had a chance to test the solution above?

Hello.

Sorry mate. I had no chance.

We've decided to just rename the file extension from .svg to .vue and wrap
it in the