如何让 Jest 正确转译 node_modules/@nativescript/core ?玩笑 + NativeScript + Angular + Nx

Jam*_*mes 5 typescript jestjs nativescript angular nrwl

我目前正在尝试使用 Nx monorepo 工具设置一个多平台代码共享入门项目。该项目将 Angular 用于 Web,并使用 NativeScript 用于跨平台移动设备。

\n

理想情况下,我希望能够使用 Jest 来运行所有单元测试。目前,我可以使用根目录中的 jest 成功运行单元测试。它们对于 Angular 应用程序及其库正确执行,但在尝试为 NativeScript (NativeScript Angular) 项目执行单元测试时遇到错误,特别是当这些单元测试导入 NativeScript 组件时(即实际上有用)。也就是说,虚拟测试期望true能够true正常工作,因此 Jest 可以毫无问题地找到并运行测试。但是当我尝试导入组件时,我遇到了问题。

\n

我已经解决了一些问题。最初我收到的错误是:

\n
  \xe2\x97\x8f Test suite failed to run\n\n    Jest encountered an unexpected token\n\n    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.\n\n    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".\n\n    Here's what you can do:\n     \xe2\x80\xa2 If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.\n     \xe2\x80\xa2 To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.\n     \xe2\x80\xa2 If you need a custom transformation specify a "transform" option in your config.\n     \xe2\x80\xa2 If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.\n\n    You'll find more details and examples of these config options in the docs:\n    https://jestjs.io/docs/en/configuration.html\n\n    Details:\n\n    /home/james/WebstormProjects/please-remind.me/apps/mobile/node_modules/@nativescript/core/index.js:3\n    import './globals';\n    ^^^^^^\n\n    SyntaxError: Cannot use import statement outside a module\n\n      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1350:14)\n      at node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js:2:85\n      at Object.<anonymous> (node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js:5:2)\n\n
Run Code Online (Sandbox Code Playgroud)\n

因此,我按照说明访问了 Jest 网站,其中指示我对我的 进行以下更改jest.config.js

\n
module.exports = {\n    displayName: 'mobile',\n    preset: '../../jest.preset.js',\n    setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],\n    globals: {\n        'ts-jest': {\n            tsConfig: '<rootDir>/tsconfig.spec.json',\n            stringifyContentPathRegex: '\\\\.(html|svg)$',\n            astTransformers: {\n                before: [\n                    'jest-preset-angular/build/InlineFilesTransformer',\n                    'jest-preset-angular/build/StripStylesTransformer',\n                ],\n            },\n        },\n    },\n    coverageDirectory: '../../coverage/apps/mobile',\n    snapshotSerializers: [\n        'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',\n        'jest-preset-angular/build/AngularSnapshotSerializer.js',\n        'jest-preset-angular/build/HTMLCommentSerializer.js',\n    ],\n    transformIgnorePatterns: [                         <<<<<<< Added\n        '../../node_modules/(?!(@nativescript)/)'      <<<<<<< Added\n    ]                                                  <<<<<<< Added\n};\n
Run Code Online (Sandbox Code Playgroud)\n

应该注意的是,我jest.config.js从网络项目中复制了它,这就是它自动生成的方式。

\n

所以我有一个非常简单的单元测试app.component.spec.ts,尝试导入 AppComponent:

\n
import { TestBed } from '@angular/core/testing';\nimport { RouterTestingModule } from '@angular/router/testing';\nimport { AppComponent } from './app.component';\n\ndescribe('AppComponent', () => {\n    beforeEach(async () => {\n        await TestBed.configureTestingModule({\n            imports: [RouterTestingModule],\n            declarations: [AppComponent],\n        }).compileComponents();\n    });\n\n    it('should create the app', () => {\n        const fixture = TestBed.createComponent(AppComponent);\n        const app = fixture.componentInstance;\n        expect(app).toBeTruthy();\n    });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

现在错误是:

\n
  \xe2\x97\x8f Test suite failed to run\n\n    Cannot find module './application' from 'node_modules/@nativescript/core/index.js'\n\n    Require stack:\n      node_modules/@nativescript/core/index.js\n      node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js\n      src/app/app.component.ts\n      src/app/app.component.spec.ts\n\n      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:306:11)\n      at Object.<anonymous> (node_modules/@nativescript/core/index.js:4:1)\n\n  console.log\n    Profiling startup failed to figure out defaults from package.json, error: Error: Cannot find module '~/package.json' from 'node_modules/@nativescript/core/profiling/index.js'\n\n      at Object.<anonymous> (node_modules/@nativescript/core/profiling/index.js:134:17)\n\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试将其添加testEnvironment: "node",到我的 jest.config.js 中:

\n
module.exports = {\n    displayName: 'mobile',\n    preset: '../../jest.preset.js',\n    setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],\n    globals: {\n        'ts-jest': {\n            tsConfig: '<rootDir>/tsconfig.spec.json',\n            stringifyContentPathRegex: '\\\\.(html|svg)$',\n            astTransformers: {\n                before: [\n                    'jest-preset-angular/build/InlineFilesTransformer',\n                    'jest-preset-angular/build/StripStylesTransformer',\n                ],\n            },\n        },\n    },\n    coverageDirectory: '../../coverage/apps/mobile',\n    snapshotSerializers: [\n        'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',\n        'jest-preset-angular/build/AngularSnapshotSerializer.js',\n        'jest-preset-angular/build/HTMLCommentSerializer.js',\n    ],\n    transformIgnorePatterns: [                         <<<<<<< Added\n        '../../node_modules/(?!(@nativescript)/)'      <<<<<<< Added\n    ]                                                  <<<<<<< Added\n    testEnvironment: "node"                            <<<<<<< Added\n};\n
Run Code Online (Sandbox Code Playgroud)\n

并且出现不同的错误:

\n
  \xe2\x97\x8f Test suite failed to run\n\n    Cannot find module '../timer' from 'node_modules/@nativescript/core/globals/index.js'\n\n      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:306:11)\n      at Object.loader (node_modules/@nativescript/core/globals/index.js:256:46)\n      at loadModule (node_modules/@nativescript/core/globals/index.js:203:43)\n      at Object.get [as clearInterval] (node_modules/@nativescript/core/globals/index.js:9:30)\n\n  console.log\n    Profiling startup failed to figure out defaults from package.json, error: Error: Cannot find module '~/package.json' from 'node_modules/@nativescript/core/profiling/index.js'\n\n      at Object.<anonymous> (node_modules/@nativescript/core/profiling/index.js:134:17)\n
Run Code Online (Sandbox Code Playgroud)\n

因此,肯定涉及到ts-jest某种“及时”转译。我想我需要在我的以下任一位置设置一个标志tsconfig.spec.json

\n
{\n  "extends": "./tsconfig.json",\n  "compilerOptions": {\n    "outDir": "../../dist/out-tsc",\n    "module": "commonjs",\n    "allowJs": true,\n    "types": ["jest", "node"]\n  },\n  "files": ["src/test-setup.ts"],\n  "include": ["**/*.spec.ts", "**/*.d.ts"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

tsconfig.json这是上面扩展的基础:

\n
{\n    "compilerOptions": {\n        "module": "esnext",\n        "target": "es2017",\n        "moduleResolution": "node",\n        "experimentalDecorators": true,\n        "emitDecoratorMetadata": true,\n        "noEmitHelpers": true,\n        "noEmitOnError": true,\n        "skipLibCheck": true,\n        "lib": [\n            "es2017",\n            "dom"\n        ],\n        "baseUrl": ".",\n        "paths": {\n            "~/*": [\n                "src/*"\n            ]\n        }\n    },\n    "exclude": [\n        "node_modules",\n        "platforms"\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

提前致谢。

\n

小智 0

我正在使用 Nativescript-vue,并且遇到了与您相同的错误。我找到了一个解决方案,但我不知道它对你有用吗?

不要import Vue from "nativescript-vue";在您的 .vue 文件中使用。当import { Vue } from "vue-property-decorator"; 你想在“nativescript-vue”而不是“vue-property-decorator”中使用某些东西时,你会得到一些编译错误。您可以添加extend/vue-extend.ts文件来添加接口,然后编译错误就会消失。vue-extend.ts 会像下面这样。

import { Vue } from "vue-property-decorator";
declare module "vue-property-decorator" {
  interface Vue {
    $navigateTo(args: any): any;
    $navigateTo(args: any, {}): any;
    $navigateBack(): any;
  }
}
Run Code Online (Sandbox Code Playgroud)