Jest/Ionic 4 beta - import { Platform } from '@ionic/angular'; gets SyntaxError: Unexpected token export in Jest testing, not Ionic
Jest/Ionic 4 beta - import { Platform } from '@ionic/angular'; gets SyntaxError: Unexpected token export in Jest testing, not Ionic
当 运行ning Jest 针对基础包时,我在 Jest 中 运行ning 测试时出现错误,仅 运行ning [=13= 时不会出现该错误]. Jest 在
上出错
import { Platform } from '@ionic/angular';
即:
export { IonicModule } from './ionic-module';
^^^^^^
SyntaxError: Unexpected token export
3 | import { RouterTestingModule } from '@angular/router/testing';
4 |
> 5 | import { Platform } from '@ionic/angular';
| ^
6 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
7 | import { StatusBar } from '@ionic-native/status-bar/ngx';
8 |
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at Object.<anonymous> (src/app/app.component.spec.ts:5:1)
我的Jest.config.json
module.exports = {
collectCoverage: true,
collectCoverageFrom: [
"src/**/*.ts"
],
coverageDirectory: "<rootDir>/coverage/",
moduleNameMapper: {
"@core/(.*)": "<rootDir>/src/app/core/",
"@state/(.*)": "<rootDir>/src/app/state/"
},
preset: "jest-preset-angular",
roots: ['src'],
setupTestFrameworkScriptFile: "<rootDir>/src/setup-jest.ts",
transformIgnorePatterns: [
"node_modules/(?!(@ionic-native|@ionic|angularfire2)/)"
],
verbose: false
}
我只是在使用示例侧面菜单模板并将组件调整为 运行 Jest。
当某些文件需要预处理才能在 Jest 中使用时,就会出现此问题。在这种情况下,需要对离子导入进行预处理,但通常会通过 transformIgnorePatterns
忽略。但这只是问题的一半。我们还需要添加一些 babel 来处理文件,以便它们可以 运行.
我能够通过添加具有以下配置的 .babelrc 文件来解决这个问题
{
"presets": [["@babel/preset-env", {
"modules": "commonjs",
"targets": {
"node": "current"
}
}]],
"plugins": ["transform-export-extensions", "@babel/plugin-transform-runtime"]
}
我使用了以下 jest 配置
{
"jest": {
"preset": "jest-preset-angular",
"setupTestFrameworkScriptFile": "<rootDir>/src/setup-jest.ts",
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.jest.json",
"useBabelrc": true
},
"__TRANSFORM_HTML__": true
},
"transformIgnorePatterns": [
"node_modules/(?!@ngrx|angular2-ui-switch|ng-dynamic|@ionic|@ionic-native)"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
}
}
src/tsconfig。spec.json 也需要一些小的调整。
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"baseUrl": "./",
"module": "commonjs",
"allowJs": true,
"types": [
"jest",
"jquery",
"jsdom",
"node"
]
},
"include": [
"polyfills.ts",
"**/*.spec.ts",
"**/*.d.ts"
]
}
你的回答对我不起作用。但是,我注意到删除额外的括号可以消除错误。尝试更改:
transformIgnorePatterns: [
"node_modules/(?!(@ionic-native|@ionic|angularfire2)/)"
],
至
transformIgnorePatterns: [
"node_modules/(?!@ionic-native|@ionic|angularfire2)"
],
不过,对我来说,这现在带来了一个新错误:
Cannot find module '@ionic/core/loader' from 'app-initialize.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:221:17)
at Object.<anonymous> (node_modules/@ionic/angular/dist/app-initialize.js:1:1)
这一切都很好,直到我升级到 Ionic 4 beta 11(从 beta 8)。我现在也在使用 Jest 23.6.0,但它在 Jest 23.5.0 中也失败了。
无论是否使用您的 babelrc
配置,我都会遇到这些错误。
供参考,这是我的 ionic info
:
Ionic:
ionic (Ionic CLI) : 4.1.2
Ionic Framework : @ionic/angular 4.0.0-beta.11
@angular-devkit/core : 0.8.3
@angular-devkit/schematics : 0.8.3
@angular/cli : 6.2.3
@ionic/ng-toolkit : 1.0.7
@ionic/schematics-angular : 1.0.6
Cordova:
cordova (Cordova CLI) : 7.1.0
Cordova Platforms : none
Cordova Plugins : no whitelisted plugins (0 plugins total)
System:
Android SDK Tools : 26.1.1 (/Users/rc101077/Library/Android/sdk)
ios-deploy : 2.0.0
ios-sim : 7.0.0
NodeJS : v8.11.4 (/Users/rc101077/.nvm/versions/node/v8.11.4/bin/node)
npm : 6.4.1
OS : macOS High Sierra
Xcode : Xcode 9.4.1 Build version 9F2000
看到所有答案都很长,我决定在阅读 Jest unit testing no longer works with Ionic 4 后展示对我有用的内容。
要使其正常工作,您需要添加到 jest.config.ts
:
transformIgnorePatterns: [
"node_modules/(?!@ionic-native|@ionic)"
],
并在 tsconfig.spec.json
中设置:
"compilerOptions": {
"allowJs": true,
},
就我而言,使用 Ionic 5、Angular 10 和 NX monorepo,我必须执行以下操作才能启用 Ionic 应用程序的 Jest 测试。
注意:如果您已经有标准的 Jest 设置,请跳过前 4 个步骤。
注意 2:步骤的顺序并不重要。
1.删除所有 Karma 和 Jasmine 文件和依赖项
- 删除
karma.conf.js
和src/test.ts
。
- 从
package.json
中删除与 karma
和 jasmine
相关的所有内容(例如 @types/jasmine
、karma
等)
2。添加 Jest 依赖项
将 jest
、jest-preset-angular
、@types/jest
和 ts-jest
添加到您的 devDependencies
,如果您还没有它们:
# if you use yarn:
yarn add --dev jest jest-preset-angular @types/jest ts-jest
# or if you use npm:
npm install --save-dev jest jest-preset-angular @types/jest ts-jest
3。更新 angular.json
更新您的 angular.json
文件。将 Karma 的 architect
-> test
配置替换为 Jest 的配置:
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "apps/my-app/jest.config.js",
"polyfills": "apps/my-app/src/polyfills.ts"
}
}
注意:我使用 @nrwl/jest:jest
生成器。如果您不使用 NX monorepo,只需将 @angular-builders/jest:run
指定为构建器,然后从配置选项中删除“apps/my-app/”。
4.创建test-setup.ts
创建 src/test-setup.ts
包含单行内容的文件:
import 'jest-preset-angular';
5.添加 Babel 依赖项
将 babel-jest
、@babel/preset-env
和 @babel/plugin-syntax-dynamic-import
添加到您的 devDependencies
:
# if you use yarn:
yarn add --dev babel-jest @babel/preset-env @babel/plugin-syntax-dynamic-import
# or if you use npm:
npm install --save-dev babel-jest @babel/preset-env @babel/plugin-syntax-dynamic-import
6.更新 tsconfig.spec.json
将 "allowJs": true
和 types
添加到您的 TypeScript 配置中的 compilerOptions
。添加 files
以编译之前创建的 test-setup.ts
文件。
我的最终版本tsconfig.spec.json
:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowJs": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}
7.创建或更新 jest.config.js
在您的应用程序根目录(您有 package.json
的地方)创建 jest.config.js
,如果您还没有的话。
注意:我为 Angular.
添加了 transformIgnorePatterns
和 global.ts-jest.babelConfig
设置到 Jest 配置的默认版本
文件的最终版本如下所示:
const esModules = ['@ionic'].join('|');
module.exports = {
preset: '../../jest.preset.js',
coverageDirectory: '../../coverage/apps/mobile-ui',
snapshotSerializers: [
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
'jest-preset-angular/build/AngularSnapshotSerializer.js',
'jest-preset-angular/build/HTMLCommentSerializer.js',
],
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], // leave `<rootDir>` string as is
globals: {
'ts-jest': {
babelConfig: {
presets: [
[
'@babel/preset-env',
{ targets: { node: true }, modules: 'commonjs' }
]
],
plugins: ['@babel/plugin-syntax-dynamic-import']
},
tsConfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\.(html|svg)$',
astTransformers: {
before: [
'jest-preset-angular/build/InlineFilesTransformer',
'jest-preset-angular/build/StripStylesTransformer',
]
},
},
},
// To transform Ionic modules to UMD, because Jest can't import them otherwise
// (see here: https://medium.com/@gregor.woiwode/how-to-setup-jest-in-an-ionic-4-project-ff1e5b72dd79)
transformIgnorePatterns: [
`/node_modules/(?!${esModules})`
],
displayName: 'my-app',
};
感谢这篇文章,它帮助我确定了这些步骤:How to setup Jest in an Ionic 4 project | Gregor Woiwode | Apr 25, 2019 | Medium
当 运行ning Jest 针对基础包时,我在 Jest 中 运行ning 测试时出现错误,仅 运行ning [=13= 时不会出现该错误]. Jest 在
上出错import { Platform } from '@ionic/angular';
即:
export { IonicModule } from './ionic-module';
^^^^^^
SyntaxError: Unexpected token export
3 | import { RouterTestingModule } from '@angular/router/testing';
4 |
> 5 | import { Platform } from '@ionic/angular';
| ^
6 | import { SplashScreen } from '@ionic-native/splash-screen/ngx';
7 | import { StatusBar } from '@ionic-native/status-bar/ngx';
8 |
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at Object.<anonymous> (src/app/app.component.spec.ts:5:1)
我的Jest.config.json
module.exports = {
collectCoverage: true,
collectCoverageFrom: [
"src/**/*.ts"
],
coverageDirectory: "<rootDir>/coverage/",
moduleNameMapper: {
"@core/(.*)": "<rootDir>/src/app/core/",
"@state/(.*)": "<rootDir>/src/app/state/"
},
preset: "jest-preset-angular",
roots: ['src'],
setupTestFrameworkScriptFile: "<rootDir>/src/setup-jest.ts",
transformIgnorePatterns: [
"node_modules/(?!(@ionic-native|@ionic|angularfire2)/)"
],
verbose: false
}
我只是在使用示例侧面菜单模板并将组件调整为 运行 Jest。
当某些文件需要预处理才能在 Jest 中使用时,就会出现此问题。在这种情况下,需要对离子导入进行预处理,但通常会通过 transformIgnorePatterns
忽略。但这只是问题的一半。我们还需要添加一些 babel 来处理文件,以便它们可以 运行.
我能够通过添加具有以下配置的 .babelrc 文件来解决这个问题
{
"presets": [["@babel/preset-env", {
"modules": "commonjs",
"targets": {
"node": "current"
}
}]],
"plugins": ["transform-export-extensions", "@babel/plugin-transform-runtime"]
}
我使用了以下 jest 配置
{
"jest": {
"preset": "jest-preset-angular",
"setupTestFrameworkScriptFile": "<rootDir>/src/setup-jest.ts",
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.jest.json",
"useBabelrc": true
},
"__TRANSFORM_HTML__": true
},
"transformIgnorePatterns": [
"node_modules/(?!@ngrx|angular2-ui-switch|ng-dynamic|@ionic|@ionic-native)"
],
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
}
}
src/tsconfig。spec.json 也需要一些小的调整。
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"baseUrl": "./",
"module": "commonjs",
"allowJs": true,
"types": [
"jest",
"jquery",
"jsdom",
"node"
]
},
"include": [
"polyfills.ts",
"**/*.spec.ts",
"**/*.d.ts"
]
}
你的回答对我不起作用。但是,我注意到删除额外的括号可以消除错误。尝试更改:
transformIgnorePatterns: [
"node_modules/(?!(@ionic-native|@ionic|angularfire2)/)"
],
至
transformIgnorePatterns: [
"node_modules/(?!@ionic-native|@ionic|angularfire2)"
],
不过,对我来说,这现在带来了一个新错误:
Cannot find module '@ionic/core/loader' from 'app-initialize.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:221:17)
at Object.<anonymous> (node_modules/@ionic/angular/dist/app-initialize.js:1:1)
这一切都很好,直到我升级到 Ionic 4 beta 11(从 beta 8)。我现在也在使用 Jest 23.6.0,但它在 Jest 23.5.0 中也失败了。
无论是否使用您的 babelrc
配置,我都会遇到这些错误。
供参考,这是我的 ionic info
:
Ionic:
ionic (Ionic CLI) : 4.1.2
Ionic Framework : @ionic/angular 4.0.0-beta.11
@angular-devkit/core : 0.8.3
@angular-devkit/schematics : 0.8.3
@angular/cli : 6.2.3
@ionic/ng-toolkit : 1.0.7
@ionic/schematics-angular : 1.0.6
Cordova:
cordova (Cordova CLI) : 7.1.0
Cordova Platforms : none
Cordova Plugins : no whitelisted plugins (0 plugins total)
System:
Android SDK Tools : 26.1.1 (/Users/rc101077/Library/Android/sdk)
ios-deploy : 2.0.0
ios-sim : 7.0.0
NodeJS : v8.11.4 (/Users/rc101077/.nvm/versions/node/v8.11.4/bin/node)
npm : 6.4.1
OS : macOS High Sierra
Xcode : Xcode 9.4.1 Build version 9F2000
看到所有答案都很长,我决定在阅读 Jest unit testing no longer works with Ionic 4 后展示对我有用的内容。
要使其正常工作,您需要添加到 jest.config.ts
:
transformIgnorePatterns: [
"node_modules/(?!@ionic-native|@ionic)"
],
并在 tsconfig.spec.json
中设置:
"compilerOptions": {
"allowJs": true,
},
就我而言,使用 Ionic 5、Angular 10 和 NX monorepo,我必须执行以下操作才能启用 Ionic 应用程序的 Jest 测试。
注意:如果您已经有标准的 Jest 设置,请跳过前 4 个步骤。
注意 2:步骤的顺序并不重要。
1.删除所有 Karma 和 Jasmine 文件和依赖项
- 删除
karma.conf.js
和src/test.ts
。 - 从
package.json
中删除与karma
和jasmine
相关的所有内容(例如@types/jasmine
、karma
等)
2。添加 Jest 依赖项
将 jest
、jest-preset-angular
、@types/jest
和 ts-jest
添加到您的 devDependencies
,如果您还没有它们:
# if you use yarn:
yarn add --dev jest jest-preset-angular @types/jest ts-jest
# or if you use npm:
npm install --save-dev jest jest-preset-angular @types/jest ts-jest
3。更新 angular.json
更新您的 angular.json
文件。将 Karma 的 architect
-> test
配置替换为 Jest 的配置:
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "apps/my-app/jest.config.js",
"polyfills": "apps/my-app/src/polyfills.ts"
}
}
注意:我使用 @nrwl/jest:jest
生成器。如果您不使用 NX monorepo,只需将 @angular-builders/jest:run
指定为构建器,然后从配置选项中删除“apps/my-app/”。
4.创建test-setup.ts
创建 src/test-setup.ts
包含单行内容的文件:
import 'jest-preset-angular';
5.添加 Babel 依赖项
将 babel-jest
、@babel/preset-env
和 @babel/plugin-syntax-dynamic-import
添加到您的 devDependencies
:
# if you use yarn:
yarn add --dev babel-jest @babel/preset-env @babel/plugin-syntax-dynamic-import
# or if you use npm:
npm install --save-dev babel-jest @babel/preset-env @babel/plugin-syntax-dynamic-import
6.更新 tsconfig.spec.json
将 "allowJs": true
和 types
添加到您的 TypeScript 配置中的 compilerOptions
。添加 files
以编译之前创建的 test-setup.ts
文件。
我的最终版本tsconfig.spec.json
:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowJs": true,
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}
7.创建或更新 jest.config.js
在您的应用程序根目录(您有 package.json
的地方)创建 jest.config.js
,如果您还没有的话。
注意:我为 Angular.
添加了transformIgnorePatterns
和 global.ts-jest.babelConfig
设置到 Jest 配置的默认版本
文件的最终版本如下所示:
const esModules = ['@ionic'].join('|');
module.exports = {
preset: '../../jest.preset.js',
coverageDirectory: '../../coverage/apps/mobile-ui',
snapshotSerializers: [
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
'jest-preset-angular/build/AngularSnapshotSerializer.js',
'jest-preset-angular/build/HTMLCommentSerializer.js',
],
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], // leave `<rootDir>` string as is
globals: {
'ts-jest': {
babelConfig: {
presets: [
[
'@babel/preset-env',
{ targets: { node: true }, modules: 'commonjs' }
]
],
plugins: ['@babel/plugin-syntax-dynamic-import']
},
tsConfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\.(html|svg)$',
astTransformers: {
before: [
'jest-preset-angular/build/InlineFilesTransformer',
'jest-preset-angular/build/StripStylesTransformer',
]
},
},
},
// To transform Ionic modules to UMD, because Jest can't import them otherwise
// (see here: https://medium.com/@gregor.woiwode/how-to-setup-jest-in-an-ionic-4-project-ff1e5b72dd79)
transformIgnorePatterns: [
`/node_modules/(?!${esModules})`
],
displayName: 'my-app',
};
感谢这篇文章,它帮助我确定了这些步骤:How to setup Jest in an Ionic 4 project | Gregor Woiwode | Apr 25, 2019 | Medium