开玩笑:从自己的包导入时无法读取未定义的属性

Tri*_*iti 6 javascript typescript reactjs jestjs

我创建了一个名为 的包@package/test。当导入到新的空 React typescript 应用程序时,效果非常好。问题始于 Jest 测试套件。


commonJS版本导致 Jest 抛出:

Test suite failed to run. TypeError:Cannot read property 'getSelectors' of undefined

import { Test } from `@package/test
const selectors = Test.getSelectors(...); //error here indicating that Test is undefined
Run Code Online (Sandbox Code Playgroud)

当我编译ES modules软件包版本时,它会导致 Jest 抛出

export * from './common';
^^^^^^
SyntaxError: Unexpected token export
Run Code Online (Sandbox Code Playgroud)

src/index.ts这是我的包裹里面的第一行。

我测试过很多解决方案,例如:

  • transformIgnorePatterns为玩笑定义
  • eslint使用插件搜索循环依赖关系Madge
  • 在 Node.js 版本上测试:10.20.0、12.21.0、15.12.0
  • 在打字稿版本上测试:3.7.5、4.1.2

有关该包的一些详细信息

export * from './common';
^^^^^^
SyntaxError: Unexpected token export
Run Code Online (Sandbox Code Playgroud)
/* 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"
}
Run Code Online (Sandbox Code Playgroud)
/* tsconfig.package.json */
{
  "extends": "../../tsconfig.packages.json",
  "compilerOptions": { "outDir": "./dist", "rootDir": "./src", "composite": true },
  "references": [],
  "include": ["src"],
  "exclude": ["src/**/*.spec.*", "dist", "node_modules"]
}
Run Code Online (Sandbox Code Playgroud)
/* tsconfig.packages.json */
{
  "extends": "../tsconfig.base.json",
  "compilerOptions": {
    "module": "es2020",
    "lib": ["es5", "es2015", "es2020", "dom"]
  }
}
Run Code Online (Sandbox Code Playgroud)

如何Test导出:

/* 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"
  }
}
Run Code Online (Sandbox Code Playgroud)

如何getSelectors导出:

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';

Run Code Online (Sandbox Code Playgroud)

React 测试应用程序详细信息

export default function getSelectors<S>(selectNavigation: Selector<S, RootState>) {
  const getInitialized = createSelector(selectNavigation, (s) => s.initialized);
    ...
  return { getInitialized, ... };
}
Run Code Online (Sandbox Code Playgroud)
/* 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"
  },
}
Run Code Online (Sandbox Code Playgroud)

编辑:我设法让它在我的测试 React 应用程序中工作transformIgnorePatterns,但不幸的是它在我的 Angular 1.6(webpack、babel)应用程序中不起作用。还添加了一些babel插件将package转换为commonJS,但没有效果。

Tri*_*iti 4

问题比看上去要复杂得多。

额外问题:

Jest不尊重文件Babel中的配置json。我必须将其转换为js.

解决方案编号 1:

  • @babel/preset-env作为开发依赖项安装。
  • 将其注册为 Babel 配置中的预设:
env: {
    test: {
      presets: ['@babel/preset-env'],
    },
}
Run Code Online (Sandbox Code Playgroud)
  • 配置transformIgnorePatterns中需要注册Jest
  • 将其添加到配置transform中的部分Jest"^.+\\.js$": "babel-jest"

解决方案编号 2:

  • 安装babel-jest@babel/plugin-transform-modules-commonjs作为开发依赖项。
  • 在 Babel 的配置中注册插件:
env: {
    test: {
      plugins: ['@babel/plugin-transform-modules-commonjs'],
    },
}
Run Code Online (Sandbox Code Playgroud)
  • 配置transformIgnorePatterns中需要注册Jest
  • 将其添加到配置transform中的部分Jest"^.+\\.js$": "babel-jest"