使用jest + vuejs + vuetify时出现意外的标识符错误。

12

我已经四处寻找答案了。我怀疑这是一个.babelrc的问题,但我找不到可行的解决方法。

应用程序运行得非常好,但我发现,Jest和Rollup确实依赖于.babelrc。另一个可能的罪魁祸首是Leaflet。在所有我构建和测试的组件中,只有包含Leaflet和vue2-leaflet的一个似乎存在这个问题。考虑到我正在开发一个地图应用程序,这对我来说非常关键。

我在这里发布,因为我无法证明任何事情。而且还有许多其他人也遇到了类似的问题。

终端输出:

nr test:unit

> cxl-vue-leaflet@3.0.1-SNAPSHOT test:unit /Users/dan.mahoney/Projects/cxl-vue-leaflet
> NODE_ENV=testing BABEL_DISABLE_CACHE=1 jest --verbose --no-cache

Determining test suites to run...

# Starting...
# 1 test suites found.

#  FAIL  src/components/__test__/specs/cxl-vue-leaflet.spec.js

#
#   /Users/dan.mahoney/Projects/cxl-vue-leaflet/node_modules/vuetify/lib/index.js:1
#
#   ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Vuetify from './components/Vuetify';
#                                                                                                   ^^^^^^^
#
#   SyntaxError: Unexpected identifier
#
#   Stack:
#
#       at new Script (vm.js:85:7)

1..0

# Test Suites:  0%            , 1 failed, 1 total
# Tests:       0 total
# Time:        2.088s

# Ran all test suites.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! cxl-vue-leaflet@3.0.1-SNAPSHOT test:unit: `NODE_ENV=testing BABEL_DISABLE_CACHE=1 jest --verbose --no-cache`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the cxl-vue-leaflet@3.0.1-SNAPSHOT test:unit 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!     /Users/dan.mahoney/.npm/_logs/2019-03-08T21_06_53_748Z-debug.log

.babelrc:

{
  "sourceMaps": true,
  "presets": [
    [
      "@babel/preset-env",
    ]
  ],
  "env": {
    "test": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "current"
            }
          }
        ]
      ]
    }
  },
  "plugins": [
      "transform-es2015-modules-commonjs",
      ["add-module-exports", {
        "vuetify": {
          "transform": "vuetify/es5/components/${member}",
          "preventFullImport": "false"
        },
      }],
  ]
}

package.json中的Jest配置:

"jest": {
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/"
    ],
    "moduleFileExtensions": [
      "js",
      "vue"
    ],
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1",
      "^.+\\.(css)$": "identity-obj-proxy"
    },
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.vue$": "vue-jest",
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "reporters": [
      "jest-tap-reporter"
    ],
    "collectCoverageFrom": [
      "**/components/*.vue",
      "!**/node_modules/**"
    ]
  },

依赖项:

"dependencies": {
    "get-value": "^3.0.1",
    "leaflet": "^1.4.0",
    "leaflet.icon.glyph": "^0.2.0",
    "moment": "^2.23.0",
    "vue-moment": "^4.0.0",
    "vue2-leaflet": "^2.0.2",
    "vue2-leaflet-markercluster": "^3.0.0",
    "vuetify": "^1.5.5"
  },
  "devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.3.4",
    "@babel/plugin-transform-runtime": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@vue/cli-service": "^3.5.0",
    "@vue/test-utils": "^1.0.0-beta.28",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^24.3.1",
    "babel-plugin-add-module-exports": "^1.0.0",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-plugin-source-map-support": "^2.0.1",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
    "babel-plugin-transform-imports": "^1.4.1",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "chromedriver": "^2.38.3",
    "eslint": "^5.15.1",
    "eslint-config-airbnb-base": "^13.1.0",
    "eslint-config-standard": "^12.0.0",
    "eslint-config-strict": "^14.0.1",
    "eslint-config-strict-es": "^1.0.4",
    "eslint-detailed-reporter": "^0.7.3",
    "eslint-import-resolver-webpack": "^0.11.0",
    "eslint-loader": "^2.1.0",
    "eslint-plugin-html": "^5.0.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jest": "^22.1.3",
    "eslint-plugin-leon-require-jsdoc": "0.0.1",
    "eslint-plugin-node": "^8.0.1",
    "eslint-plugin-promise": "^4.0.1",
    "eslint-plugin-security": "^1.4.0",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^5.1.0",
    "eslint-plugin-vue-a11y": "0.0.28",
    "growl": "^1.10.2",
    "husky": "^1.3.1",
    "identity-obj-proxy": "^3.0.0",
    "is-image": "^2.0.0",
    "jest": "^24.3.1",
    "jest-tap-reporter": "^1.9.0",
    "jest-transform-stub": "^2.0.0",
    "jest-vue-preprocessor": "^1.5.0",
    "jsdoc": "^3.5.5",
    "jsdoc-vue": "^1.0.0",
    "jsdom": "^13.0.0",
    "jsdom-global": "^3.0.2",
    "material-design-icons-iconfont": "^4.0.2",
    "minimist": "^1.2.0",
    "nightwatch": "^1.0.11",
    "npm-merge-driver": "^2.3.5",
    "parse5": "^5.1.0",
    "raf": "^3.4.0",
    "require-extension-hooks": "^0.3.2",
    "require-extension-hooks-babel": "^0.1.1",
    "require-extension-hooks-vue": "^2.0.0",
    "rollup": "^1.6.0",
    "rollup-plugin-analyzer": "^3.0.0",
    "rollup-plugin-babel": "^4.3.0",
    "rollup-plugin-babel-minify": "^7.0.0",
    "rollup-plugin-commonjs": "^9.1.8",
    "rollup-plugin-postcss": "^2.0.1",
    "rollup-plugin-replace": "^2.1.0",
    "rollup-plugin-vue": "^4.3.2",
    "selenium": "^2.20.0",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.1",
    "tap-summary": "^4.0.0",
    "vue": "^2.6.8",
    "vue-jest": "^3.0.4",
    "vue-loader": "^15.7.0",
    "vue-meta": "^1.5.8",
    "vue-template-compiler": "^2.6.8",
    "vuepress": "^1.0.0-alpha.42",
    "vuepress-jsdoc": "^1.0.3",
    "vuetify-loader": "^1.0.8"
  },

我真的很无助。感谢任何帮助。

2个回答

11

默认情况下,Jest 不会转换node_modules中的任何内容(其中包含vuetify包),但实际上你需要通过配置babel-jest转换来运行vuetify,以便能够转译import。为此,请在jest.config.js中使用以下配置:

module.exports = {
  transformIgnorePatterns: [
    '<rootDir>/node_modules/(?!vuetify)'
  ],
  ...
}

刚刚提交了一个Pull Request来记录这个陷阱


1

对于仍然在使用Vue 3 / Vuetify 3的用户,我遇到的解决方法类似,但是我没有使用原始问题中提到的许多包:

Jest配置

  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
    "transform": {
      "^.+\\.vue$": "@vue/vue3-jest",
      "^.+\\.(js|mjs)$": "babel-jest"
    },
    "transformIgnorePatterns": ["/node_modules/(?!(vuetify)/)"]
    // plus some globals and a module alias
  }

Babel配置

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
  ],
};

依赖版本

"dependencies": {
    "vue": "^3.2.31",
    "vuetify": "^3.0.4",
    "@vue/cli-plugin-babel": "^5.0.8",
    "@vue/cli-plugin-unit-jest": "~5.0.8",
    "@vue/cli-service": "~5.0.1",
    "@vue/compiler-sfc": "^3.0.7",
    "@vue/test-utils": "^2.2.6",
    "@vue/vue3-jest": "^27.0.0-alpha.4",
    "jest": "^27.5.1"
  }

解决方法是配置 transform/transformIgnorePatterns,因为之前我们并不需要转换任何 Node 模块。这样就可以解决 Jest 遇到意外的令牌/语法错误:无法在模块外使用 import 语句 的问题。

但我仍然遇到了一个问题,在我的测试文件中无法导入 Vuetify 组件,会出现以下错误:

    Cannot find module 'vuetify/components' from 'tests/unit/InfoWindow/sections/DisplayFields/ScheduleDisplay.spec.js'

      1 | import {shallowMount} from '@vue/test-utils';
      2 | import {createVuetify} from 'vuetify';
    > 3 | import * as components from 'vuetify/components';
        | ^
      4 | import * as directives from 'vuetify/directives';

我不确定原因是什么,但解决方法是在Jest配置中添加显式映射:

    "moduleNameMapper": {
      "^vuetify/components$": "<rootDir>/node_modules/vuetify/lib/components/index.mjs",
      "^vuetify/directives$": "<rootDir>/node_modules/vuetify/lib/directives/index.mjs"
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接