Jest + Vue - SyntaxError: Unexpected token <

Posted

技术标签:

【中文标题】Jest + Vue - SyntaxError: Unexpected token <【英文标题】: 【发布时间】:2019-04-24 05:12:39 【问题描述】:

我正在尝试使用 ts-Jest/Jest 和 Chai 将测试添加到我用 TypeScript 编写的 Electron + Vue2 应用程序中。但是,当我尝试运行我编写的简单测试以尝试确保 Jest 正常工作时,我现在遇到了 Jest 的问题,似乎不喜欢我正在导入我正在测试的组件的模板这一事实可以在错误中看到。当我尝试搜索与此相关的内容时,我运气不佳,其中很多都指向“意外的令牌导入”,这是我已经解决的问题。

如果有人对我如何让测试不因导入 html 而感到惊慌有任何见解或知识,那将是惊人的,因为我被难住了,而且文档似乎没有任何帮助。

错误:

$ npm run test

> app@1.0.0 test C:\Users\daniel\Desktop\app\app
> jest --detectOpenHandles

FAIL src/app/features/app-window/app-window.component.spec.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain javascript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\Users\daniel\Desktop\app\app\src\app\features\app-application-content\app-application-content.component.html:1
    ("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)<webview-component v-if="src"
                                                                                             ^

    SyntaxError: Unexpected token <

      2 | import Component from 'vue-class-component'
      3 | import  Prop, Watch  from 'vue-property-decorator'
    > 4 | import Template from './app-application-content.component.html'
        | ^
      5 |
      6 | import * as qs from 'qs'
      7 | import  INameValue  from '../../../contracts/Core'

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/app/features/app-application-content/app-application-content.component.ts:4:1)
      at Object.<anonymous> (src/app/features/app-content/app-content.component.ts:9:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        12.924s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! app@1.0.0 test: `jest --detectOpenHandles`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the app@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\daniel\AppData\Roaming\npm-cache\_logs\2018-11-21T14_25_23_427Z-debug.log

jest.config.js

module.exports = 
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node'],
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: 
    'ts-jest': 
      tsConfig: './src/app/tsconfig.json'
    ,
    NODE_ENV: 'test'
  

tsconfig.json


  "compilerOptions": 
    "allowJs": true,
    "outDir": "./built/",
    "sourceMap": true,
    "strict": true,
    "moduleResolution": "node",
    "target": "ES2017",
    "experimentalDecorators": true,
    "noImplicitAny": false,
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "lib": ["es2017", "dom"],
    "include": [
      "**/*",
      "../types/**/*",
      "../../node_modules/bootstrap-vue/**/*",
      "../../node_modules/electron/**/*"
    ]
  

app-window.component.spec.ts

import  expect  from 'chai'
import 'jest'
import  appWindowComponent  from './app-window.component'

const appWindowComponent = new appWindowComponent()

describe('Test: Set Title Function', () => 
  it('should set the variable title to the passed variable', () => 
    const title = 'this is a test'
    appWindowComponent.setTitle(title)
    expect(appWindowComponent.title).to.equal(title)
  )
)

【问题讨论】:

【参考方案1】:

这里有一个更新的解决方案:

您需要安装 vue-jest (https://github.com/vuejs/vue-jest) 与

npm install -D @vue/vue3-jest

这里是可用的版本及其对应的 vue 和 jest 版本

Vue version Jest Version Package
Vue 2 Jest <= 26 vue-jest@4
Vue 3 Jest <= 26 vue-jest@5
Vue 2 Jest 27 @vue/vue2-jest
Vue 3 Jest 27 @vue/vue3-jest

然后,您只需更新您的 jest 配置(例如在 jest.config.ts 中)并添加一个 transform section

"transform": 
    "^.+\\.vue$": "@vue/vue3-jest"

警告:一定要在npm install 命令和jest.config.ts 中使用正确的vue-jest 包!

【讨论】:

【参考方案2】:

在我found the answer here周围侦查之后

新的 jest.config.js

module.exports = 
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],
  transform: 
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  ,
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: 
    'ts-jest': 
      tsConfig: './src/app/tsconfig.json'
    ,
    NODE_ENV: 'test'
  

注意

transform: 
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  , 

moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],

HTML 加载器文件

const htmlLoader = require('html-loader')

module.exports = 
  process(src, filename, config, options) 
    return htmlLoader(src)
  

这似乎已经奏效了,因为我现在遇到了一个新错误:)

【讨论】:

以上是关于Jest + Vue - SyntaxError: Unexpected token <的主要内容,如果未能解决你的问题,请参考以下文章

Vue Jest 测试套件无法运行:SyntaxError: Unexpected identifier

使用 jest 和 vue 抛出 SyntaxError: Unexpected identifier error for import

vue-jest 错误:“SyntaxError: Unexpected token <”由`import PictureInput from 'vue-picture-input'`引起

Jest + Vue3 + @Vueform/slider “语法错误:不能在模块外使用导入语句”

Jest 给出错误:“SyntaxError: Unexpected token export”

Jest SyntaxError: Unexpected token <