首页 > 解决方案 > 不使用单个文件组件时强制重新生成 vue 3 中的代码

问题描述

我正在使用带有 jest 的 vue 3 进行单元测试。我的组件在 .vue 文件中,js 和 css 在单独的文件中,并通过 src= 包含在 .vue 中:

<template>
  <div>my library</div>
</template>

<script src="./library.js"></script>
<style src="./library.css"></style>

这在大多数情况下效果很好,例如npm run serve在我保存对这些文件的更改时重新加载和刷新所有内容。

但是,当我运行npm run test:unit测试时,测试是针对我的 library.js 的陈旧(缓存?)版本运行的。我的 package.json 包含在scripts:中"test:unit": "vue-cli-service test:unit",。我怀疑它被缓存了,因为如果我向 .vue 文件添加注释,它会针对 .js 的正确版本运行,但如果我删除注释(因此文件与以前的版本匹配),那么它会针对 stale 运行。再次.js。

可能有趣的是,vue-cli-service test:unit --watch当我更改 .js 文件时,运行确实会重新运行测试,但它会针对旧版本而不是触发重新运行的新版本运行。

我似乎唯一的解决方法是在 .vue 文件中附加一个虚拟注释,这很烦人。或者转到我觉得烦人的 SFC,因为不同部分的编辑器支持不如单独文件那样好。

如何让 npm / vue-cli-service 绕过这种明显的缓存?或者有没有办法清除缓存?

下面的脚本将重现该问题。请注意,在底部的输出中,测试运行了 3 次:

  1. 在第一次运行时,输出应包括“hello created 1”。
  2. 然后编辑 .js 文件以更改该字符串,以便在第二次运行时输出应为“hello created 2”。但是,当我运行此脚本时,它在两次测试运行中都提供了“hello created 1”。
  3. 然后编辑 .vue 文件以更改虚拟注释。在第三次运行时,输出如预期的那样是“hello created 2”。
#!/bin/bash

if [[ -f package.json ]]
then
    echo "'cd ..' and rerun this script"
    echo "you need to be in the parent directory to the project directory"
    exit 1
fi

if [[ ! -d utfail ]]
then
   vue create -p __default_vue_3__ utfail
   cd utfail

   # specific versions are based on what I was using originally
   npm install vue@3.0.3
   npm install -D @vue/test-utils@2.0.0-beta.11
   npm install -D @vue/compiler-sfc@3.0.3
   npm install -D vue-jest@5.0.0-alpha.7
   npm install -D @vue/cli-plugin-unit-jest@4.5.9
   npm install -D typescript@3.9.7
else
    cd utfail
fi
       

# hack: replace the default lint script with test:unit
sed -i -e 's/^.*"lint":.*$/    "test:unit": "vue-cli-service test:unit"/' package.json

cat <<EOF > jest.config.js
module.exports = {
    moduleFileExtensions: ["js", "json", "vue"],
    preset: '@vue/cli-plugin-unit-jest',
    transform: {
        '^.+\\.js$': "babel-jest",
        '^.+\\.vue$': 'vue-jest'
    },
    "automock": false,
    "setupFiles": [
    "./setupJest.js"
    ]
}
EOF

cat <<EOF > src/components/HelloWorld.vue
<!-- dummy comment 1 -->
<template>
  <div class="hello">blah</div>
</template>

<script src="./helloworld.js"></script>

<style></style>
EOF

cat <<EOF > src/components/helloworld.js
export default {
  name: 'HelloWorld',
  created() {
    console.log("hello created 1")
  }
}
EOF

cat <<EOF > setupJest.js
// require('jest-fetch-mock').enableMocks()
EOF

mkdir -p __tests__
cat <<EOF > __tests__/app.spec.js
import { mount } from '@vue/test-utils'
import App from './../src/App.vue'
import HelloWorld from './../src/components/HelloWorld.vue'

describe('HelloWorld', () => {
    beforeEach(() => {
    })

    it('exists', () => {
        const wrapper = mount(HelloWorld)
    expect(wrapper.exists()).toBe(true)
    })
})
EOF

printf '\n*\n*\n*\n*** about to run tests (round 1)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit

sed -i -e '/hello created/s/1/2/' src/components/helloworld.js

printf '\n*\n*\n*\n*** about to run tests (round 2)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit

sed -i -e '/dummy comment/s/1/2/' src/components/HelloWorld.vue

printf '\n*\n*\n*\n*** about to run tests (round 3)\n*\n*\n*\n'
grep 'hello created' src/components/helloworld.js
npm run test:unit

标签: javascriptunit-testingvue.jsjestjs

解决方案


配置 Jest 以禁用测试缓存:

// jest.config.js
module.exports = {
  cache: false,
}

或者将--no-cache标志添加到test:unitnpm 脚本中:

// package.json
{
  "scripts": {
    "test:unit": "vue-cli-service test:unit --no-cache"
  }
}

或者从项目的根目录使用这个命令清除缓存:

npx jest --clearCache

推荐阅读