带有 nx 测试的 Angular v13 Jest - SyntaxError:无法在 Runtime.createScriptFromCode 的模块外部使用 import 语句

1an*_*es1 8 javascript nomachine-nx jestjs angular

我试图每一条评论中都给出一个可能的解决方案。我还依赖 github 上的一个示例项目,它运行得很好。

\n

在手动更新所有内容之后,这也开始发生在我身上,并且在运行 nx test 命令时,发生此错误。

\n

我的 jest.config.js 位于apps/my-app 内:

\n
module.exports = {\n    preset: "../../jest.preset.js",\n    coverageDirectory: "../../coverage/apps/my-app",\n    moduleFileExtensions: ["ts", "html", "js", "json", "mjs"],\n    extensionsToTreatAsEsm: [".ts"],\n    resolver: "jest-preset-angular/build/resolvers/ng-jest-resolver.js",\n    setupFilesAfterEnv: ["<rootDir>/src/test-setup.ts"],\n    globals: {\n        "ts-jest": {\n            tsconfig: "<rootDir>/tsconfig.spec.json",\n            stringifyContentPathRegex: "\\\\.(html|svg)$",\n            useESM: true\n        }\n    },\n    transform: {\n        "^.+\\\\.(ts|js|mjs|html|svg)$": "jest-preset-angular",\n    },\n    displayName: "my-app",\n    snapshotSerializers: [\n        "jest-preset-angular/build/serializers/no-ng-attributes",\n        "jest-preset-angular/build/serializers/ng-snapshot",\n        "jest-preset-angular/build/serializers/html-comment",\n    ],\n    transformIgnorePatterns: [\n        "node_modules/(?!.*\\\\.mjs$)",\n        "node_modules/(?!lodash-es)",\n        "node_modules/(?!@ngrx|@ionic-native|@ionic)"\n    ]\n};\n
Run Code Online (Sandbox Code Playgroud)\n

项目根目录中的jest.config.js :

\n
const { getJestProjects } = require("@nrwl/jest");\n\nmodule.exports = { projects: getJestProjects() };\n
Run Code Online (Sandbox Code Playgroud)\n

根项目中的jest.preset.js :

\n
const nxPreset = require("@nrwl/jest/preset");\nmodule.exports = {\n    ...nxPreset,\n    testMatch: ["**/+(*.)+(spec|test).+(ts|js)?(x)"],\n    transform: {\n        "^.+\\\\.(ts|js|html)$": "ts-jest",\n    },\n    resolver: "@nrwl/jest/plugins/resolver",\n    moduleFileExtensions: ["ts", "js", "html"],\n    coverageReporters: ["html"],\n};\n
Run Code Online (Sandbox Code Playgroud)\n

包.json:

\n
{\n    "name": "my-app",\n    "version": "1.1.10",\n    "license": "MIT",\n    "scripts": {\n      ...\n    },\n    "private": true,\n    "dependencies": {\n        "@angular-devkit/architect": "0.1301.2",\n        "@angular/animations": "13.1.0",\n        "@angular/common": "13.1.0",\n        "@angular/compiler": "13.1.0",\n        "@angular/core": "13.1.0",\n        "@angular/forms": "13.1.0",\n        "@angular/platform-browser": "13.1.0",\n        "@angular/platform-browser-dynamic": "13.1.0",\n        "@angular/router": "13.1.0",\n        "@angular/service-worker": "13.1.0",\n        "@awesome-cordova-plugins/device": "5.37.2",\n        "@ionic-enterprise/cordova": "9.0.3",\n        "@ionic-native/app-version": "5.36.0",\n        "@ionic-native/clipboard": "5.36.0",\n        "@ionic-native/core": "5.36.0",\n        "@ionic-native/fingerprint-aio": "5.36.0",\n        "@ionic-native/in-app-browser": "5.36.0",\n        "@ionic-native/ionic-webview": "5.36.0",\n        "@ionic-native/secure-storage": "5.36.0",\n        "@ionic-native/social-sharing": "5.36.0",\n        "@ionic-native/splash-screen": "5.36.0",\n        "@ionic-native/status-bar": "5.36.0",\n        "@ionic-native/unique-device-id": "5.36.0",\n        "@ionic/angular": "6.0.0",\n        "@ionic/storage-angular": "3.0.6",\n        "@ng-idle/core": "11.1.0",\n        "@ng-idle/keepalive": "11.0.3",\n        "@ngx-translate/core": "14.0.0",\n        "@ngx-translate/http-loader": "7.0.0",\n        "@sentry/angular": "6.16.1",\n        "@sentry/tracing": "6.16.1",\n        "cordova-android": "8.1.0",\n        "cordova-plugin-device": "2.0.3",\n        "cordova-plugin-inappbrowser": "5.0.0",\n        "cordova-plugin-ionic-keyboard": "2.2.0",\n        "cordova-plugin-ionic-webview": "5.0.0",\n        "cordova-plugin-splashscreen": "6.0.0",\n        "cordova-plugin-statusbar": "3.0.0",\n        "cordova-plugin-whitelist": "1.3.5",\n        "core-js": "3.19.3",\n        "crypto-es": "1.2.7",\n        "document-register-element": "1.14.10",\n        "dom-to-image": "2.6.0",\n        "lodash-es": "4.17.21",\n        "moment": "2.29.1",\n        "native-run": "1.5.0",\n        "ng-circle-progress": "1.6.0",\n        "node-forge": "0.10.0",\n        "npm": "8.3.0",\n        "reflect-metadata": "0.1.13",\n        "rxjs": "7.4.0",\n        "sass": "1.45.0",\n        "tslib": "2.3.1",\n        "uuid": "8.3.2",\n        "zone.js": "0.11.4"\n    },\n    "devDependencies": {\n        "@angular-architects/ddd": "1.5.1",\n        "@angular-devkit/build-angular": "13.1.0",\n        "@angular-eslint/builder": "13.0.1",\n        "@angular-eslint/eslint-plugin": "13.0.1",\n        "@angular-eslint/eslint-plugin-template": "13.0.1",\n        "@angular-eslint/schematics": "13.0.1",\n        "@angular-eslint/template-parser": "13.0.1",\n        "@angular/cli": "13.1.0",\n        "@angular/compiler-cli": "13.1.0",\n        "@angular/language-service": "13.1.0",\n        "@angularclass/hmr": "3.0.0",\n        "@ionic/angular-toolkit": "5.0.3",\n        "@ionic/cli": "6.18.1",\n        "@nrwl/angular": "13.3.2",\n        "@nrwl/cli": "13.3.1",\n        "@nrwl/cypress": "13.3.1",\n        "@nrwl/eslint-plugin-nx": "13.3.1",\n        "@nrwl/jest": "13.3.1",\n        "@nrwl/linter": "13.3.1",\n        "@nrwl/node": "13.3.1",\n        "@nrwl/workspace": "13.3.1",\n        "@schematics/angular": "13.1.0",\n        "@types/dom-to-image": "2.6.4",\n        "@types/jest": "27.0.3",\n        "@types/lodash-es": "4.17.5",\n        "@types/node": "16.11.12",\n        "@types/node-forge": "0.10.10",\n        "@types/uuid": "8.3.3",\n        "@typescript-eslint/eslint-plugin": "5.3.1",\n        "@typescript-eslint/parser": "5.3.1",\n        "codelyzer": "6.0.2",\n        "compare-func": "2.0.0",\n        "cordova": "10.0.0",\n        "cordova-browser": "6.0.0",\n        "cordova-clipboard": "1.3.0",\n        "cordova-ios": "6.2.0",\n        "cordova-plugin-add-swift-support": "2.0.2",\n        "cordova-plugin-androidx": "3.0.0",\n        "cordova-plugin-androidx-adapter": "1.1.3",\n        "cordova-plugin-app-version": "0.1.12",\n        "cordova-plugin-fingerprint-aio": "5.0.0",\n        "cordova-plugin-iroot": " 3.1.0",\n        "cordova-plugin-proguard": "2.2.0",\n        "cordova-plugin-secure-storage-echo": " 5.1.1",\n        "cordova-plugin-x-socialsharing": "6.0.3",\n        "cordova-res": "0.15.4",\n        "cordova-sqlite-storage": "6.0.0",\n        "cordova-unique-device-id": "1.3.2",\n        "cypress": "8.7.0",\n        "dotenv": "10.0.0",\n        "dtslint": "4.2.1",\n        "es6-promise-plugin": "4.2.2",\n        "eslint": "8.4.1",\n        "eslint-config-prettier": "8.3.0",\n        "eslint-plugin-cypress": "2.12.1",\n        "eslint-plugin-prettier": "4.0.0",\n        "fuzzy": "0.1.3",\n        "inquirer": "8.2.0",\n        "inquirer-autocomplete-prompt": "1.4.0",\n        "jest": "27.4.5",\n        "jest-preset-angular": "11.0.1",\n        "ncu": "0.2.1",\n        "ng-packagr": "13.1.0",\n        "ngx-unused-css": "3.0.0",\n        "npm-check-updates": "12.0.3",\n        "npx": "10.2.2",\n        "open": "8.4.0",\n        "prettier": "2.5.1",\n        "stylelint": "14.1.0",\n        "stylelint-config-standard": "24.0.0",\n        "ts-jest": "27.0.5",\n        "ts-node": "9.1.1",\n        "typescript": "^4.4.4",\n        "webpack": "5.30.0",\n        "xml2js": "0.4.23"\n    },\n    "description": "An ionic project",\n    "browser": {\n        "crypto": false,\n        "stream": false\n    },\n    "cordova": {\n        "plugins": {\n            "cordova-plugin-ionic-keyboard": {},\n            "cordova-plugin-splashscreen": {},\n            "cordova-plugin-statusbar": {},\n            "cordova-plugin-whitelist": {},\n            "cordova-plugin-ionic-webview": {},\n            "cordova-plugin-inappbrowser": {},\n            "cordova-plugin-x-socialsharing": {\n                "PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION": "La aplicaci\xc3\xb3n requiere acceso a la biblioteca de fotos para funcionar apropiadamente.",\n                "PHOTO_LIBRARY_USAGE_DESCRIPTION": "La aplicaci\xc3\xb3n requiere acceso a la biblioteca de fotos para funcionar apropiadamente."\n            },\n            "cordova-plugin-androidx": {},\n            "cordova-plugin-androidx-adapter": {},\n            "cordova-plugin-proguard": {},\n            "cordova-sqlite-storage": {},\n            "cordova-unique-device-id": {},\n            "cordova-plugin-app-version": {},\n            "cordova-plugin-fingerprint-aio": {\n                "FACEID_USAGE_DESCRIPTION": " "\n            },\n            "cordova-plugin-secure-storage-echo": {},\n            "cordova-plugin-iroot": {},\n            "cordova-clipboard": {},\n            "cordova-plugin-add-swift-support": {},\n            "cordova-plugin-device": {}\n        },\n        "platforms": [\n            "browser",\n            "ios",\n            "android"\n        ]\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我仍然不断收到此错误::/

\n
    You\'ll find more details and examples of these config options in the docs:\n    https://jestjs.io/docs/configuration\n    For information about custom transformations, see:\n    https://jestjs.io/docs/code-transformation\n\n    Details:\n\n    C:\\Repos\\temp-repos\\my-app\\node_modules\\@angular\\core\\fesm2015\\testing.mjs:7\n    import { getDebugNode, RendererFactory2, \xc9\xb5stringify, \xc9\xb5ReflectionCapabilities, Directive, Component, Pipe, NgModule, \xc9\xb5getInjectableDef, resolveForwardRef, \xc9\xb5NG_COMP_DEF, \xc9\xb5Render3NgModuleRef, ApplicationInitStatus, LOCALE_ID, \xc9\xb5DEFAULT_LOCALE_ID, \xc9\xb5setLocaleId, \xc9\xb5Render3ComponentFactory, \xc9\xb5compileComponent, \xc9\xb5NG_DIR_DEF, \xc9\xb5compileDirective, \xc9\xb5NG_PIPE_DEF, \xc9\xb5compilePipe, \xc9\xb5NG_MOD_DEF, \xc9\xb5transitiveScopesFor, \xc9\xb5patchComponentDefWithScope, \xc9\xb5NG_INJ_DEF, \xc9\xb5compileNgModuleDefs, NgZone, Compiler, COMPILER_OPTIONS, \xc9\xb5NgModuleFactory, ModuleWithComponentFactories, InjectionToken, Injector, InjectFlags, \xc9\xb5resetCompiledComponents, \xc9\xb5flushModuleScopingQueueAsMuchAsPossible } from \'@angular/core\';       \n    ^^^^^^\n\n    SyntaxError: Cannot use import statement outside a module\n\n      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1728:14)\n
Run Code Online (Sandbox Code Playgroud)\n

感谢您的回复。

\n

ste*_*nja 30

从我在网上发现的情况来看,这似乎是使用 Jest 并升级到 Angular 13 的项目的常见问题。我们的项目没有使用,nx但以下是 Jest 配置的更新:

// jest.config.js
const esModules = ['@angular', '@ngrx', 'd3', [...] ];

module.exports = {
  // [...]
  extensionsToTreatAsEsm: ['.ts'],
  globals: {
    'ts-jest': {
      useESM: true,
      tsconfig: '<rootDir>/tsconfig.spec.json',
      stringifyContentPathRegex: '\\.html$',
    },
  },
  moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'],
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  transform: {
    '^.+\\.(ts|js|mjs|html|svg)$': 'jest-preset-angular',
  },
  transformIgnorePatterns: [
    `<rootDir>/node_modules/(?!.*\\.mjs$|${esModules.join('|')})`,
  ]
};
Run Code Online (Sandbox Code Playgroud)

解决我的问题的是对一个已关闭问题(jest-preset-Angular)的评论。在我的例子中,忽略模块@angular@ngrx,解决了您问题中发布的错误。具体来说这一行:

const esModules = ['@angular', '@ngrx', 'd3', [...] ];
Run Code Online (Sandbox Code Playgroud)

更新:转换忽略模式合并为 node_module 文件和模块的单个模式,以解决不同的问题。