javascript - Jest: Kan ikke lese egenskapen til undefined når man importerer fra egen pakke
Jeg har opprettet en pakke kalt @package/test. Når den importeres til en ny, tom React TypeScript-app fungerer den perfekt. Problemene begynner i Jest-testsett.
Versjonen av commonJS-pakken får Jest til å kaste:
Test suite failed to run. TypeError:Cannot read property 'getSelectors' of undefinedimport { Test } from `@package/test
const selectors = Test.getSelectors(...); //error here indicating that Test is undefined
Når jeg kompilerte en ES modules-pakkeversjon, får det Jest til å feile
export * from './common';
^^^^^^
SyntaxError: Unexpected token export
som er den første linjen i min src/index.ts inne i pakken min.
Jeg har testet mange løsninger, for eksempel:
- Definerer
transformIgnorePatternsfor Jest - Søker etter sirkulære avhengigheter ved å bruke
eslint-plugins ogMadge - Testet på Node.js-versjoner: 10.20.0, 12.21.0, 15.12.0
- Testet på TypeScript-versjoner: 3.7.5, 4.1.2
Noen detaljer om pakken:
/* package.json */
{
"name": "@package/test",
"version": "2.4.0",
"main": "./dist/index.js",
"scripts": {
"build": "tsc -b ./tsconfig.package.json"
},
"typings": "./dist/index.d.ts",
"files": [
"dist"
],
"dependencies": {...},
"peerDependencies": {...},
"sideEffects": "false"
}
/* tsconfig.package.json */
{
"extends": "../../tsconfig.packages.json",
"compilerOptions": { "outDir": "./dist", "rootDir": "./src", "composite": true },
"references": [],
"include": ["src"],
"exclude": ["src/**/*.spec.*", "dist", "node_modules"]
}
/* tsconfig.packages.json */
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"module": "es2020",
"lib": ["es5", "es2015", "es2020", "dom"]
}
}
/* tsconfig.base.json */
{
"compileOnSave": false,
"compilerOptions": {
"declaration": true,
"sourceMap": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react",
"strict": true,
"target": "es5"
}
}
Hvordan Test eksporteres:
import * as actions from './actions';
import reducer, { Action, RootState} from './reducer';
import getSelectors from './getSelectors';
export const Test = {
actions,
reducer,
getSelectors,
};
export { Action, RootState};
export * from './types';
export * from './helpers';
Hvordan getSelectors eksporteres:
export default function getSelectors<S>(selectNavigation: Selector<S, RootState>) {
const getInitialized = createSelector(selectNavigation, (s) => s.initialized);
...
return { getInitialized, ... };
}
Detaljer om React-testapplikasjon
/* package.json */
{
"name": "jest-verify",
"version": "0.1.0",
"private": true,
"dependencies": {
"@package/test": "2.4.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
}
/* tsconfig.json */
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
REDIGER: Jeg klarte å få det til å fungere i min test React-app med transformIgnorePatterns, men dessverre fungerer det ikke i min Angular 1.6 (webpack, babel) app. La også til noen babel-plugins for å transformere pakken til commonJS, men ingen effekt.
Svar #1
Problemet var mye mer komplekst enn det så ut.
Ekstra utgave:
Jest respekterte ikke Babel-konfigurasjonen i json-filen. Jeg måtte transformere den til js.
Løsning nr. 1:
- Installer
@babel/preset-envsom en dev-avhengighet. - Registrer det som en forhåndsinnstilling i Babels konfigurasjon:
env: {
test: {
presets: ['@babel/preset-env'],
},
}
- Registrer nødvendig
transformIgnorePatternsiJest-konfigurasjon - Legg dette til i
transform-seksjonen iJest-konfigurasjonen:"^.+\\.js$": "babel-jest"
Løsninger nr. 2:
- Installer
babel-jestog@babel/plugin-transform-modules-commonjssom utviklingsavhengigheter. - Registrer pluginen i Babels konfigurasjon:
env: {
test: {
plugins: ['@babel/plugin-transform-modules-commonjs'],
},
}
- Registrer nødvendig
transformIgnorePatternsiJest-konfigurasjon - Legg dette til i
transform-seksjonen iJest-konfigurasjonen:"^.+\\.js$": "babel-jest"
