Zenan
Zenan

Reputation: 21

How to feature flag/toggle TypeScript service/class

I would like to feature flag a service in my React app so I can toggle it on and off by changing a boolean in a config file. However, I am unsure as to how best to do so. The service is as below:

class Service {
  constructor() {
    // do stuff
  }

  doA() {
    // do stuff
  }

  doB() {
    // do stuff
  }

  // more methods
}

export const serviceInstance = new Service();

This service's methods are called in different parts of the application.

Currently, I am flagging it by creating another class with the same methods and attributes as Service and then exporting the relevant instance based on the feature flag boolean:

class ServiceMock {
  constructor() {
    return;
  }

  doA() {
    return;
  }

  doB() {
    return;
  }

  // more empty return methods
}

export const serviceInstance = serviceFlag ? new Service() : new ServiceMock();

It works but I am worried that this is rather inefficient, especially when the number of methods and attributes grow. Is there a better way to feature flag something like this?

Upvotes: 2

Views: 1616

Answers (2)

BruceWan
BruceWan

Reputation: 31

You should have used webpack in your project. The best way is just to build what code you need. But in your demo code export const serviceInstance = serviceFlag ? new Service() : new ServiceMock();, It'll build all the two services into your runtime code.

It would help if you did this config in webpack.

module.exports = {
  //...
  plugins: [
    new webpack.DefinePlugin({
      'process.env.serviceFlag': JSON.stringify(process.env.serviceFlag),
    }),
  ],
};

Then to use the environment variable in your code like so export const serviceInstance = process.env.serviceFlag === "true" ? new Service() : new ServiceMock();. Finally don't forget to pass the environment variable in the npm script.

{
  "scripts": {
    "build": "cross-env serviceFlag=true umi build",
    "build:mock": "cross-env serviceFlag=false umi build",
  },
}

Now you can npm run build or npm run build:mock, the runtime code just includes one of the service.

Upvotes: 0

Sean Summers
Sean Summers

Reputation: 2694

I'm new to TypeScript, but does this help any?

interface IService {
    doA(): void
    doB(): void
}

class Service implements IService {
    doA(): void {
        console.log("doA");
    }
    doB(): void {
        console.log("doB");
    }
}

class ServiceMock implements IService {
    doA(): void {
        console.log("mockA");
    }
    doB(): void {
        console.log("mockB");
    }
}

function createService(serviceFlag: boolean): IService {
    return (serviceFlag) ? new Service() : new ServiceMock();
}

const originalServiceInstance = createService(true);
const mockServiceInstance = createService(false);
originalServiceInstance.doA();
mockServiceInstance.doA();

If anyone has improvements or suggestions, I'm still struggling with coming to TypeScript from python and would be happy to improve this answer.

It runs without error at TypeScript Playground.

Upvotes: 1

Related Questions