node.js - ioredis'i v5.0.1'e yükselttikten sonra oluşan sorunlar


Redis istemcileri oluşturmak için orijinal kodumuz

import Redis, { Redis as RedisClient, Cluster, ClusterOptions } from 'ioredis';
import config from '../../../config';

const {
  port, host, cluster, transitEncryption,
} = config.redis;

const retryStrategy = (times: number): number => Math.min(times * 50, 10000);

function GetRedisClient(): RedisClient {
  return new Redis({
    host,
    port: port as number,
    retryStrategy,
  });
}

function GetRedisClusterClient(): Cluster {
  const clusterOptions: ClusterOptions = {
    clusterRetryStrategy: retryStrategy,
    redisOptions: { db: 0 },
  };
  if (transitEncryption) {
    clusterOptions.dnsLookup = (address, callback) => callback(null, address);
    clusterOptions.redisOptions!.tls = {};
  }

  return new Redis.Cluster([
    {
      host,
      port: port as number,
    },
  ], clusterOptions);
}

function getClient() {
  return cluster ? GetRedisClusterClient() : GetRedisClient();
}

export default getClient();

ioredis'in 5.0.1 sürümüne yükselttiğimizde bu hale geldi:

import Redis, { Cluster, ClusterOptions } from 'ioredis';
import config from '../../../config';

const {
  port, host, cluster, transitEncryption,
} = config.redis;

const retryStrategy = (times: number): number => Math.min(times * 50, 10000);

function GetRedisClient(): Redis {
  return new Redis({
    host,
    port: port as number,
    retryStrategy,
  });
}

function GetRedisClusterClient(): Cluster {
  const clusterOptions: ClusterOptions = {
    clusterRetryStrategy: retryStrategy,
    redisOptions: { db: 0 },
  };
  if (transitEncryption) {
    clusterOptions.dnsLookup = (address, callback) => callback(undefined, address);
    clusterOptions.redisOptions!.tls = {};
  }

  return new Cluster([
    {
      host,
      port: port as number,
    },
  ], clusterOptions);
}

function getClient() {
  return cluster ? GetRedisClusterClient() : GetRedisClient();
}

export default getClient();

Dev bağımlılığı @types/ioredis package.json dosyamızdan kaldırıldı.

Proje typescript'i derlediğimde semantik bir hata alıyorum.

xxx/node_modules/@types/connect-redis/index.d.ts(22,51): error TS2694: Namespace '"xxx/node_modules/ioredis/built/index"' has no exported member 'Redis'.

Ve jest testleri artık çalışmıyor, 'return new Cluster' satırını işaret ediyor ve şu hatayla başarısız oluyor

 TypeError: _ioredis.Cluster is not a constructor

Testler:

import Redis, { Cluster, ClusterOptions } from 'ioredis';
import config from '../../../config';

jest.mock('ioredis');
jest.mock('../../../config', () => ({
  redis: {
    host: 'redis',
    port: 1234,
    cluster: false,
    transitEncryption: false,
  },
  service_name: 'app name',
  version: 'test',
}));

describe('redis client', () => {
  const clusterTest = (clusterOptions: ClusterOptions) => {
    // eslint-disable-next-line global-require
    require('./client');
    expect(Cluster)
      .toHaveBeenCalled();
  };
  const clusterOptions: ClusterOptions = {
    clusterRetryStrategy: expect.any(Function),
    redisOptions: { db: 0 },
  };
  test('if the cluster variable is set, then the module should return a clustered client', () => {
    config.redis.cluster = true;
    clusterTest(clusterOptions);
  });
  test('if the cluster variable is set and transit encryption is set, then the module should return a clustered client with encryption', () => {
    config.redis.cluster = true;
    config.redis.transitEncryption = true;
    clusterOptions.dnsLookup = expect.any(Function);
    clusterOptions.redisOptions = { db: 0, tls: {} };
    clusterTest(clusterOptions);
  });
  test('if the cluster variable is not set, then the module should return a standalone client', () => {
    config.redis.cluster = false;
    // eslint-disable-next-line global-require
    require('./client');
    expect(Redis).toHaveBeenCalled();
  });
});

Meslektaşım testleri tek tek çalıştırmayı başarıyor gibi görünüyor, ama kod dalını kullanınca yukarıdaki problemi alıyorum.

Yanlış yaptığım yer hakkında herhangi bir öneriniz var mı?

Cevap #1

Typescript sürümünüzü kontrol etmenizi tavsiye ederim.
Eğer 4'ten küçükse, TS'yi 4'ün üzerine yükseltmek bu sorunu çözmelidir.

Cevap #2

Redis.Cluster([]) ile bir örnek oluşturmaya çalışın - import Redis from 'ioredis'

Çünkü import { Cluster } from 'ioredis' bir arayüzdür. Tip bildirimi için faydalıdır.