Vue-svg-loader: Typescript Cannot find module '@/assets/svg/register.svg?inline'

Created on 14 Aug 2019  路  9Comments  路  Source: visualfanatic/vue-svg-loader

Created svg.d.ts file with the following contents:

declare module '*.svg' {
  const content: any
  export default content
}

Then using in a component this way:

import register from '@/assets/svg/register.svg?inline'

Causes an error: Typescript Cannot find module '@/assets/svg/register.svg?inline'

But if i remove ?inline it stops complaining. How to correctly declare svg module in .d.ts file?

Most helpful comment

Well, using both declaration is the key, as @sergamers previously noted:

declare module '*.svg?inline' {
  const content: any
  export default content
}

declare module '*.svg' {
  const content: any
  export default content
}

But you don't need to add it in tsconfig.json under files, it would be read automatically, you to just name it, like (random name).d.ts

All 9 comments

@webcoderkz did you find a solution for that meanwhile?

@FlorianWerndl i just abandoned this module.

I've same problem.

@webcoderkz @maximelafarie I solve it that:

Create in the root next file custom.d.ts:

declare module "*.svg?inline" {
  const content: any;
  export default content;
}

and add to tsconfig.json:

...
"files": ["custom.d.ts"],
...

Well, using both declaration is the key, as @sergamers previously noted:

declare module '*.svg?inline' {
  const content: any
  export default content
}

declare module '*.svg' {
  const content: any
  export default content
}

But you don't need to add it in tsconfig.json under files, it would be read automatically, you to just name it, like (random name).d.ts

I'm facing the same issue when running npm run test:unit using the jest framework through vue-cli. It doesn't like the ?inline and it also doesn't like things like import 'pickerjs/dist/picker.css';

HI, I am also having an issue whit running jest for ?inline usage.

https://github.com/visualfanatic/vue-svg-loader/blob/master/docs/faq.md#how-to-use-this-loader-with-jest

I have followed this guideline and here is my jest configuration for your information.

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue',
    'ts',
    'tsx'
  ],
  transform: {
    'snippets\/(?!index)': 'jest-raw-loader',
    '^.+\\.vue$': 'vue-jest',
    '^.+\\.jsx?$': 'babel-jest',
    '^.+\\.svg\?inline$': '<rootDir>/test/unit/svgTransform.js',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
    '^.+\\.tsx?$': 'ts-jest'
  },
  transformIgnorePatterns: [
    '/node_modules/'
  ],
  moduleNameMapper: {
    '^vue$': 'vue/dist/vue.common.js',
    '^@/(.*)$': '<rootDir>/src/$1',
    '^test/(.*)$': '<rootDir>/test/$1',
    '^.+.svg\?inline$': '<rootDir>/src/$1',
    '^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  testMatch: [
    '**/test/unit/**/*.test.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
    '**/test/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  testURL: 'http://localhost/',
  verbose: true,
  watchPlugins: [
    'jest-watch-typeahead/filename',
    'jest-watch-typeahead/testname'
  ],
  globals: {
    'ts-jest': {
      babelConfig: true
    }
  },
  setupTestFrameworkScriptFile: '<rootDir>test/unit/setupTests.ts',
  setupFiles: ['jest-date-mock']
}

<rootDir>/test/unit/svgTransform.js , this file is where I have located the following code.

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

module.exports = {
  process (content) {
    console.log('svg transformer', content)
    const { render } = vueJest({
      content,
      attrs: {
        functional: false
      }
    })

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

Here is my shims-svg.d.ts file.

declare module '*.svg?inline' {
  import Vue, { VueConstructor } from 'vue'
  const content: VueConstructor<Vue>
  export default content
}

Also, here is part of my vue.config.js file. I am not using babel-loader so have not added it here.

chainWebpack: config => {
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule
      .oneOf('inline')
      .resourceQuery(/inline/)
      .use('vue-svg-loader')
      .loader('vue-svg-loader')
      .options({
        svgo: {
          plugins: [
            { prefixIds: true },
            { removeViewBox: false }
          ]
        }
      })
      .end()
      .end()
      .oneOf('external')
      .use('file-loader')
      .loader('file-loader')
      .options({
        name: 'assets/[name].[hash:8].[ext]'
      })
  }

I am getting this error.

image

@hipkiss91, did you manage to resolve the issue?

Please advise on this. Thanks.

Just find a solution on this issue.

First, by using jest moduleNameMapper function, remove ?inline
moduleNameMapper: { '^.+/(.*\\.svg)\\?inline$': '<rootDir>/path/svg/$1' },
For my case
````
import SvgBack from '../../assets/svg/back.svg?inline'

(Convert to) --->
import SvgBack from '../../assets/svg/back.svg'
````

Second, transform the svg files into vuejs format
transform: { '^.+\\.svg$': '<rootDir>/svgTransform.js', },

svgTransform.js can find it in the guide
https://github.com/visualfanatic/vue-svg-loader/blob/master/docs/faq.md#how-to-use-this-loader-with-jest

jest.config.js

module.exports = {
  collectCoverage: false,
  collectCoverageFrom: [
    '<rootDir>/components/**/*.vue',
    '<rootDir>/pages/*.vue',
  ],
  // tell Jest to handle `*.vue` files
  moduleFileExtensions: [ 'js', 'json', 'vue' ],
  moduleNameMapper: {
    '^.+/(.*\\.svg)\\?inline$': '<rootDir>/assets/svg/$1',
  },
  modulePaths: [ '<rootDir>' ],
  snapshotSerializers: [ '<rootDir>/node_modules/jest-serializer-vue' ],
  transform: {
    // process `*.vue` files with `vue-jest`
    '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
    // process js with `babel-jest`
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
    // process svg with svgTransform.js
    '^.+\\.svg$': '<rootDir>/tests/tools/svgTransform.js',
  },
  watchman: false,
}

any updates? i still have this issue


svgTransform.js doesn't seem to be necessary any more with [email protected]. just add vue-jest for the .svg transformer.

module.exports = {
  moduleNameMapper: {
    '^(.*\\.svg)\\?inline$': '$1',
  },
  transform: {
    '\\.svg$': 'vue-jest',
    '\\.vue$': 'vue-jest',
  },
}

this transformer works with [email protected]:

const compiler = require('vue-template-compiler')

module.exports = {
  process(content) {
    const { render } = compiler.compileToFunctions(content)
    return `module.exports = { render: ${render} }`
  },
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

valangar picture valangar  路  3Comments

sashakaralchuk picture sashakaralchuk  路  6Comments

santigarcor picture santigarcor  路  8Comments

AasmundEndresen picture AasmundEndresen  路  5Comments

edarioq picture edarioq  路  6Comments