javascript - Jest: לא ניתן לקרוא מאפיין של לא מוגדר בעת ייבוא מחבילה שלי
יצרתי חבילה בשם @package/test. כאשר היא מיובאת לאפליקציית React TypeScript חדשה וריקה היא עובדת בצורה מושלמת. הבעיות מתחילות בערכות המבחנים של Jest.
גרסת החבילה commonJS גורמת ל-Jest להתרסק:
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
כאשר אני מכין גרסת חבילת ES modules, זה גורם ל-Jest להתרסק
export * from './common';
^^^^^^
SyntaxError: Unexpected token export
שזו השורה הראשונה של src/index.ts שלי בתוך החבילה שלי.
ניסיתי פתרונות רבים לדוגמה:
- הגדרת
transformIgnorePatternsעבור Jest - חיפוש תלות מעגלית באמצעות תוספי
eslintו-Madge - נבדק על גרסאות Node.js: 10.20.0, 12.21.0, 15.12.0
- נבדק על גרסאות TypeScript: 3.7.5, 4.1.2
כמה פרטים על החבילה:
/* 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"
}
}
איך Test מיוצא:
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';
איך getSelectors מיוצא:
export default function getSelectors<S>(selectNavigation: Selector<S, RootState>) {
const getInitialized = createSelector(selectNavigation, (s) => s.initialized);
...
return { getInitialized, ... };
}
פרטי אפליקציית הבדיקה של React
/* 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"
]
}
עריכה: הצלחתי לגרום לזה לעבוד באפליקציית React שלי לניסיון עם transformIgnorePatterns, אבל למרבה הצער זה לא עובד באפליקציית Angular 1.6 שלי (webpack, babel). הוספתי גם כמה פלאגינים של babel כדי להפוך את החבילה ל-commonJS, אבל ללא השפעה.
תשובה #1
הבעיה הייתה הרבה יותר מורכבת ממה שנראה.
בעיה נוספת:
Jest לא כיבד את הגדרת Babel בקובץ json. נאלצתי להמיר אותו ל-js.
פתרון מס' 1:
- התקן את
@babel/preset-envכתלות לפיתוח. - רשום זאת כברירת מחדל בקונפיגורציה של Babel:
env: {
test: {
presets: ['@babel/preset-env'],
},
}
- יש לרשום את
transformIgnorePatternsבקונפיגורציה שלJest - הוסף את זה לקטע
transformבקונפיגורצייתJest:"^.+\\.js$": "babel-jest"
פתרונות מס' 2:
- התקן את
babel-jestואת@babel/plugin-transform-modules-commonjsכתלויות פיתוח. - רשום את התוסף בקובץ ההגדרות של Babel:
env: {
test: {
plugins: ['@babel/plugin-transform-modules-commonjs'],
},
}
- יש לרשום את
transformIgnorePatternsבהגדרותJest - הוסף את זה לקטע
transformבקונפיגורצייתJest:"^.+\\.js$": "babel-jest"
