【问题标题】:vue-jest configuration - Is there a way to map aliases that occur in template/script src attributes?vue-jest 配置 - 有没有办法映射模板/脚本 src 属性中出现的别名?
【发布时间】:2021-09-30 16:49:49
【问题描述】:

依赖:“@vue/cli-plugin-unit-jest”:“^4.5.13”,“@vue/test-utils”:“^1.2.1”,“vue-jest”:“^3.0 .7"

我有一个使用在 vue.config.js 中设置的别名(比如“foo”)的应用:

module.exports = {
  chainWebpack: (config) => {
    // Add project name as alias
    config.resolve.alias.set('foo', __dirname);
  },
};

对于 import 语句和 HTML 标记 src...

在 main.js 中:

...
import App from 'foo/src/components/core/App';
...

在 ../src/core/App/index.vue:

<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" />

我知道我可以在 jest.config.js 中使用 moduleNameMapper,类似于:

'^foo(.*)$': '&lt;rootDir&gt;$1',

但是,这不会映射出现在我的 HTML 标记的 src 属性中的别名。有没有办法让 vue-jest 通过配置设置或其他方式解释这些属性路径?

任何建议将不胜感激。

【问题讨论】:

    标签: javascript vue.js vuejs2 jestjs vue-jest


    【解决方案1】:

    SFC 中的 URL 解析

    vue-jest 无法解析 SFC 中顶级块标签的 src URL,因此您必须在 src/components/core/App/index.vue 中使用未别名的相对路径:

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

    &lt;template&gt; 内容中的 URL 解析

    vue-jest 使用@vue/component-compiler-utils 编译模板,但URL 解析需要transformAssetUrls optionvue-jest 3.x 不支持将选项传递给@vue/component-compiler-utils,但现在可以通过templateCompiler.transformAssetUrls config4.0.0-rc.1 中使用。

    即使启用了此 URL 解析,Vue CLI 也会将 jest 配置为 return an empty string for require-ed media, including images。如果您的测试需要在生产中使用正常解析的 URL,您将需要一个模仿 url-loader 的 Jest 转换。 Vue CLI 将加载器配置为return the resolved filename if greater than 4KB; or the base64 data URL otherwise

    启用 URL 解析:

    1. 更新到vue-jest4:

      npm i -D vue-jest@4
      
    2. 为自定义 my-jest-url-loader 创建以下文件,我们稍后将在下面使用:

      // <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 = ')
        }
      }
      
    3. 为避免意外覆盖 Vue CLI 的默认 Jest 预设,请使用合并实用程序(例如 lodash.merge)在 jest.config.js 中插入自定义配置。

    4. Jest global 中添加vue-jest 配置,设置templateCompiler.transformAssetUrls

    5. 修改合并预设的transform 属性以使用我们的my-jest-url-loader 转换图像。这需要从默认的 Jest 预设中移除其他图像变换以避免冲突。

      // 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>/$1',
        },
      })
      
      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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-16
      • 2020-06-23
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多