Home  >  Q&A  >  body text

Is there a way to use aliases in Vue templates and scripts to map vue-jest configuration?

<p>Dependencies: "@vue/cli-plugin-unit-jest": "^4.5.13", "@vue/test-utils": "^1.2.1", "vue -jest": "^3.0.7"</p> <p>I have an application that sets an alias (say "foo") in vue.config.js:</p> <pre class="brush:php;toolbar:false;">module.exports = { chainWebpack: (config) => { //Set the project name as an alias config.resolve.alias.set('foo', __dirname); }, };</pre> <p>For import statements and src attributes of HTML tags...</p> <p>In main.js:</p> <pre class="brush:php;toolbar:false;">... import App from 'foo/src/components/core/App'; ...</pre> <p>In ../src/core/App/index.vue:</p> <pre class="lang-html prettyprint-override"><code><script src="foo/src/components/core/App/script.js" /> <style module src="foo/src/components/core/App/style.css" /> <template src="foo/src/components/core/App/template.html" /> </code></pre> <p>I know I can use moduleNameMapper in jest.config.js, something like:</p> <p><code>'^foo(.*)$': '<rootDir>$1',</code></p> <p>However, this does not map aliases that appear in the src attribute of an HTML tag. Is there a way to have vue-jest interpret these property paths through configuration settings or other means? </p> <p>Any advice is greatly appreciated. </p>
P粉476547076P粉476547076419 days ago419

reply all(1)I'll reply

  • P粉256487077

    P粉2564870772023-08-27 00:35:45

    URL parsing in SFC

    vue-jest The src URL for the top-level block tag in SFC cannot be resolved, so you need to do it in src/components/core/App/index.vue Use unaliased relative paths in:

    <script src="./script.js" />
    <style module src="./style.css" />
    <template src="./template.html" />
    

    URL parsing in template content

    vue-jestUse @vue/component-compiler-utils to compile the template, but URL parsing requires transformAssetUrlsoption. vue-jest 3.x does not support passing options to @vue/component-compiler-utils, but it does # in #4.0.0-rc.1 ##templateCompiler.transformAssetUrlsConfigurationImplementation. Even with URL parsing enabled, the Vue CLI configuration

    jest

    to return an empty string for require's media, including images . If your tests need to work in production with normally parsed URLs, you will need a Jest converter that mimics url-loader. The Vue CLI configuration loader returns the parsed filename with if larger than 4KB; otherwise returns the base64 data URL .

    To enable URL parsing:

      Upgrade to
    1. vue-jest

      4:

      npm i -D vue-jest@4
      

    2. Create the following files for the custom
    3. my-jest-url-loader

      that will be used later below:

      // <rootDir>/tests/my-jest-url-loader.js
      const urlLoader = require('url-loader')
      
      module.exports = {
        process(src, filename) {
          const urlLoaderOptions = {
            esModule: false,
            limit: 4096,
            fallback: {
              loader: 'file-loader',
              options: {
                esModule: false,
                emitFile: false,
                name: filename,
              },
            },
          }
          const results = urlLoader.call({
            query: urlLoaderOptions,
            resourcePath: filename,
          }, src)
      
          // strip leading Webpack prefix from file path if it exists
          return results.replace(/^module.exports = __webpack_public_path__ \+ /, 'module.exports = ')
        }
      }
      

    4. To avoid accidentally overwriting the Vue CLI's default Jest presets, use a merge tool (e.g.
    5. lodash.merge) in jest.config.jsInsert custom configuration.

    6. Add a
    7. vue-jest

      configuration in Jest global and set templateCompiler.transformAssetUrls.

    8. Modify the
    9. transform

      property of the merge preset to use our my-jest-url-loader converter to process the image. This requires removing other image converters from the default Jest preset to avoid conflicts.

      // jest.config.js
      const vueJestPreset = require('@vue/cli-plugin-unit-jest/presets/default/jest-preset')
      const merge = require('lodash.merge') 3️⃣
      
      const newJestPreset = merge(vueJestPreset, {
        globals: { 4️⃣
          'vue-jest': {
            templateCompiler: {
              transformAssetUrls: {
                video: ['src', 'poster'],
                source: 'src',
                img: 'src',
                image: ['xlink:href', 'href'],
                use: ['xlink:href', 'href']
              }
            }
          }
        },
        moduleNameMapper: {
          '^foo/(.*)$': '<rootDir>/',
        },
      })
      
      function useUrlLoaderForImages(preset) { 5️⃣
        const imageTypes = ['jpg', 'jpeg', 'png', 'svg', 'gif', 'webp']
        const imageTypesRegex = new RegExp(`(${imageTypes.join('|')})\|?`, 'ig')
      
        // remove the image types from the transforms
        Object.entries(preset.transform).filter(([key]) => {
          const regex = new RegExp(key)
          return imageTypes.some(ext => regex.test(`filename.${ext}`))
        }).forEach(([key, value]) => {
          delete preset.transform[key]
          const newKey = key.replace(imageTypesRegex, '')
          preset.transform[newKey] = value
        })
      
        preset.transform = {
          ...preset.transform,
          [`.+\.(${imageTypes.join('|')})$`]: '<rootDir>/tests/my-jest-url-loader',
        }
      }
      
      useUrlLoaderForImages(newJestPreset)
      
      module.exports = newJestPreset
      

    GitHub Demo

    reply
    0
  • Cancelreply