如何让 Jest 正确转换 node_modules/@nativescript/core? Jest + NativeScript + Angular + Nx
Posted
技术标签:
【中文标题】如何让 Jest 正确转换 node_modules/@nativescript/core? Jest + NativeScript + Angular + Nx【英文标题】:How can I get Jest to transpile node_modules/@nativescript/core properly? Jest + NativeScript + Angular + Nx 【发布时间】:2021-05-16 07:02:49 【问题描述】:我目前正在尝试使用 Nx monorepo 工具设置多平台代码共享入门项目。该项目使用 Angular 用于 Web,NativeScript 用于跨平台移动。
理想情况下,我希望能够使用 Jest 运行所有单元测试。目前,我能够使用根目录中的 jest 成功运行单元测试。它们为 Angular 应用程序及其库正确执行,但在尝试为 NativeScript(NativeScript Angular)项目执行单元测试时遇到错误,特别是当这些单元测试导入 NativeScript 组件时(即实际上很有用)。也就是说,期望 true
为 true
的虚拟测试工作正常,因此 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',
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
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"
]
提前致谢。
【问题讨论】:
你解决了吗?我有完全相同的问题... 不幸的是,没有。我还没有找到解决办法。 【参考方案1】:我正在使用 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;
【讨论】:
【参考方案2】:这对我有用:
npm i jest -D
npm i @babel/preset-env -D
npm i @types/jest -D
npm i babel-preset-env -D
npm i @vue/test-utils vue-jest babel-jest -D
npm i --save-dev @vue/vue2-jest
//jest.config.js
module.exports =
verbose: true,
moduleFileExtensions: ["ts", "js", "json", "vue"],
transform:
".*\\.(vue)$": "@vue/vue2-jest",
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
"^.+\\.tsx?$": "ts-jest",
,
moduleNameMapper:
"^@/(.*)": "<rootDir>/app/$1",
"^~/(.*)": "<rootDir>/app/$1",
,
roots: ["<rootDir>/tests/"],
testEnvironment: "jsdom",
setupFiles: ["<rootDir>/tests/setup.ts"],
;
//setup.ts
import Vue from "vue";
import config from "@vue/test-utils";
jest.mock("nativescript-vue", () => Vue);
const NSElements = [
"ActionBar",
"ActionItem",
"FormattedString",
"GridLayout",
"HtmlView",
"NavigationButton",
"Page",
"StackLayout",
"AbsoluteLayout",
"FlexboxLayout",
"TabView",
"TabViewItem",
"TextField",
];
NSElements.forEach((ele) =>
Vue.config.ignoredElements.push(ele);
);
//.babelrc
"presets": [
["env", "modules": false ]
],
"env":
"test":
"presets": [
["env", "targets": "node": "current" ]
]
//tsconfig.json
....
"types": ["jest","node"],
"include": ["app", "types"],
"typeRoots": ["types"], //REMOVE THIS LINE
....
然后:
// Component.test.ts
import shallowMount from "@vue/test-utils";
import Component from "../../app/components/Component.vue";
let wrapper: any;
beforeEach(() =>
wrapper = shallowMount(Component,
propsData: text: "aBC" ,
mocks: ,
stubs: ,
methods: ,
);
);
afterEach(() =>
wrapper.destroy();
);
describe("Component", () =>
it("is a Vue instance", () =>
expect(wrapper.isVueInstance).toBeTruthy();
);
it("ComputedProp", () =>
expect(wrapper.vm.computedProp).toBe("valueExpeted");
);
);
【讨论】:
以上是关于如何让 Jest 正确转换 node_modules/@nativescript/core? Jest + NativeScript + Angular + Nx的主要内容,如果未能解决你的问题,请参考以下文章
未找到转换选项中的模块 <rootDir>/node_modules/vue-jest
未找到转换选项中的模块 <rootDir>/node_modules/jest-preset-angular/preprocessor.js