1

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?

Zenan
  • 11
  • 1

2 Answers2

0

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.

Sean Summers
  • 2,514
  • 19
  • 26
0

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.

BruceWan
  • 31
  • 6