将笑话与 Typescript、ESM 和别名一起使用

问题描述 投票:0回答:2

我使用 Typescipt 和 ESM 开发了一个模块(

"type": "module"
in
package.json
)。

我还使用了一些路径别名,这是

tsconfig.json

{
    "compilerOptions": {
        "moduleResolution": "Node16",
        "module": "Node16",
        "target": "ES2015",
        "lib": [
            "ES2022"
        ],
        "resolveJsonModule": true,
        "strictNullChecks": true,
        "sourceMap": true,
        "declaration": false,
        "downlevelIteration": true,
        "esModuleInterop": true,
        "baseUrl": ".",
        "paths": {
            "@/*": [
                "./source/*"
            ],
            "@": [
                "./source"
            ],
            "@src/*": [
                "./source/*"
            ],
            "@src": [
                "./source"
            ],
            "@test/*": [
                "./test/*"
            ],
            "@test": [
                "./test"
            ]
        },
        "outDir": "./dist"
    },
    "include": [
        "source",
        "test"
    ]
}

这就是

jest.config.ts

import type { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest';
import tsconfigJson from './tsconfig.json';

const config: Config.InitialOptions = {
    preset: 'ts-jest/presets/default-esm',
    testEnvironment: 'node',
    verbose: true,
    globals: {
        'ts-jest': {
            tsconfig: './tsconfig.json',
            useESM: true
        }
    },
    moduleNameMapper: pathsToModuleNameMapper(tsconfigJson.compilerOptions.paths, { prefix: '<rootDir>/' }),
    transformIgnorePatterns: ['<rootDir>/node_modules/']
};
export default config;

问题是,由于 ESM,模块无法使用别名:

 FAIL  test/suites/modules/mangleTypes.test.ts
  ● Test suite failed to run

    Configuration error:
    
    Could not locate module @src/modules/mangleTypes.js mapped as:
    /home/euber/Github/lifeware-java-mangler/source/$1.
    
    Please check your configuration for these entries:
    {
      "moduleNameMapper": {
        "/^@src\/(.*)$/": "/home/euber/Github/lifeware-java-mangler/source/$1"
      },
      "resolver": undefined
    }

    > 1 | import { mangleType, PrimitiveType } from '@src/modules/mangleTypes.js';
        | ^
      2 |
      3 | describe('Test @/modules/mangleTypes', function () {
      4 |     describe('Primitive types', function () {

      at createNoMappedModuleFoundError (node_modules/jest-resolve/build/resolver.js:900:17)
      at Object.<anonymous> (test/suites/modules/mangleTypes.test.ts:1:1)

我引用了this作为解决方案,但它不起作用。

更新我也尝试过像这样,但它不起作用

typescript jestjs es6-modules ts-jest
2个回答
2
投票

最终我设法通过混合两种解决方案使其发挥作用:

import type { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest';
import tsconfigJson from './tsconfig.json';

function manageKey(key: string): string {
   return key.includes('(.*)') ? key.slice(0, -1) + '\\.js$' : key;
}
function manageMapper(mapper: Record<string, string>): Record<string, string> {
   const newMapper: Record<string, string> = {};
   for (const key in mapper) {
      newMapper[manageKey(key)] = mapper[key];
   }
   newMapper['^\.\/(.*)\\.js$'] = './$1';
   return newMapper;
}

const config: Config.InitialOptions = {
    preset: 'ts-jest/presets/default-esm',
    testEnvironment: 'node',
    verbose: true,
    globals: {
        'ts-jest': {
            tsconfig: './tsconfig.json',
            useESM: true
        }
    },
    moduleNameMapper: manageMapper(pathsToModuleNameMapper(tsconfigJson.compilerOptions.paths, { prefix: '<rootDir>/' }) as Record<string, string>),
    transformIgnorePatterns: ['<rootDir>/node_modules/']
};
export default config;

更新:

newMapper['^\.\/(.*)\\.js$'] = './$1';
../utils/index.js
等情况下不起作用。要将
.js
替换为所有内容,正则表达式应更改为
newMapper['^(.*).js$'] = '$1';
之类的内容。

总代码为:

import type { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest';
import tsconfigJson from './tsconfig.json';

function manageKey(key: string): string {
   return key.includes('(.*)') ? key.slice(0, -1) + '\\.js$' : key;
}
function manageMapper(mapper: Record<string, string>): Record<string, string> {
   const newMapper: Record<string, string> = {};
   for (const key in mapper) {
      newMapper[manageKey(key)] = mapper[key];
   }
   newMapper['^(.*).js$'] = '$1';
   return newMapper;
}

const config: Config.InitialOptions = {
    preset: 'ts-jest/presets/default-esm',
    testEnvironment: 'node',
    verbose: true,
    globals: {
        'ts-jest': {
            tsconfig: './tsconfig.json',
            useESM: true
        }
    },
    coverageProvider: 'v8',
    moduleNameMapper: manageMapper(pathsToModuleNameMapper(tsconfigJson.compilerOptions.paths, { prefix: '<rootDir>/' }) as Record<string, string>),
    transformIgnorePatterns: ['<rootDir>/node_modules/']
};
export default config;

0
投票

如何让 ESM、Jest、TypeScript 和 NX(别名)协同工作的解决方案

jest.config.ts

export default {
  displayName: 'your-app-integration-tests',
  testMatch: ['**/?(*.)+(integration).(test).ts'],
  globals: {},
  preset: 'ts-jest/presets/default-esm', // for ESM support
  extensionsToTreatAsEsm: ['.ts'], // for ESM support
  testEnvironment: 'node',
  transform: {}, // keep blank for ESM
  moduleFileExtensions: ['ts', 'js', 'html', 'node'],
  coverageDirectory: '../../coverage/packages/app',
  moduleNameMapper: {
    '^@core/random-utils-1(.*)$': '<rootDir>/../../libs/random-utils-1/src/index', // this is using NX; your path is probably different
    '^@core/random-utils-2(.*)$': '<rootDir>/../../libs/random-utils-2/src/index'
  }
};

tsconfig.json

{
  "compilerOptions": {
    // all your other options
    "types": ["jest", "node"],
    "lib": ["es2022", "DOM"],
    "module": "esnext",
    "target": "ES2022"
  },
  "exclude": [
    "node_modules",   
    "./.next/**/*",
    "./playwright/**/*"
  ],
  "include": [
    "**/*.ts",
    "**/*.tsx",
    "**/*.js",
    "**/*.jsx",    
  ]
}

export NODE_OPTIONS='--experimental-vm-modules'

确保运行

export NODE_OPTIONS='--experimental-vm-modules'
。在 CI 上,只需在运行 Jest 命令之前运行上述命令即可。

了解更多:https://jestjs.io/docs/ecmascript-modules

© www.soinside.com 2019 - 2024. All rights reserved.