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

问题描述

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

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

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

  ● 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:
     • If you are trying to use ECMAScript Modules,see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • 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:

    /home/james/WebstormProjects/please-remind.me/apps/mobile/node_modules/@nativescript/core/index.js:3
    import './globals';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1350:14)
      at node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js:2:85
      at Object.<anonymous> (node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js:5:2)

所以我按照说明访问了 Jest 网站,在那里我被指示对我的 jest.config.js 进行以下更改:

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

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

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

import { Testbed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';

describe('AppComponent',() => {
    beforeEach(async () => {
        await Testbed.configureTestingModule({
            imports: [RouterTestingModule],declarations: [AppComponent],}).compileComponents();
    });

    it('should create the app',() => {
        const fixture = Testbed.createComponent(AppComponent);
        const app = fixture.componentInstance;
        expect(app).toBeTruthy();
    });
});

现在的错误是:

  ● Test suite Failed to run

    Cannot find module './application' from 'node_modules/@nativescript/core/index.js'

    Require stack:
      node_modules/@nativescript/core/index.js
      node_modules/@nativescript/angular/bundles/nativescript-angular.umd.js
      src/app/app.component.ts
      src/app/app.component.spec.ts

      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:306:11)
      at Object.<anonymous> (node_modules/@nativescript/core/index.js:4:1)

  console.log
    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'

      at Object.<anonymous> (node_modules/@nativescript/core/profiling/index.js:134:17)

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

module.exports = {
    displayName: 'mobile',transformIgnorePatterns: [                         <<<<<<< Added
        '../../node_modules/(?!(@nativescript)/)'      <<<<<<< Added
    ]                                                  <<<<<<< Added
    testEnvironment: "node"                            <<<<<<< Added
};

然后出现一个不同的错误

  ● Test suite Failed to run

    Cannot find module '../timer' from 'node_modules/@nativescript/core/globals/index.js'

      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:306:11)
      at Object.loader (node_modules/@nativescript/core/globals/index.js:256:46)
      at loadModule (node_modules/@nativescript/core/globals/index.js:203:43)
      at Object.get [as clearInterval] (node_modules/@nativescript/core/globals/index.js:9:30)

  console.log
    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'

      at Object.<anonymous> (node_modules/@nativescript/core/profiling/index.js:134:17)

因此,ts-jest 肯定涉及某些内容,它是一种“及时”转译。我在想我需要在我的 tsconfig.spec.json 中设置一个标志:

{
  "extends": "./tsconfig.json","compilerOptions": {
    "outDir": "../../dist/out-tsc","module": "commonjs","allowJs": true,"types": ["jest","node"]
  },"files": ["src/test-setup.ts"],"include": ["**/*.spec.ts","**/*.d.ts"]
}

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

{
    "compilerOptions": {
        "module": "esnext","target": "es2017","moduleResolution": "node","experimentalDecorators": true,"emitDecoratorMetadata": true,"noEmitHelpers": true,"noEmitOnError": true,"skipLibCheck": true,"lib": [
            "es2017","dom"
        ],"baseUrl": ".","paths": {
            "~/*": [
                "src/*"
            ]
        }
    },"exclude": [
        "node_modules","platforms"
    ]
}

提前致谢。

解决方法

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

不要在 .vue 文件中使用 import Vue from "nativescript-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;
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...