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.