CiccioMiami
CiccioMiami

Reputation: 8266

Store/retrieve config settings in React project with Typescript

I am currently working on a project in React and I use Typescript as language. In my project I have Webpack installed. Everything works fine but now, since we are going to production, I would like to have an easy way to store/retrieve config settings such as server URL (which is usually different between development, testing and production phases) and I got stuck. I tried to use the webpack.config.js file by adding the "externals" key:

externals: {
  'config': JSON.stringify(process.env.ENV === 'production' ? {
    serviceUrl: "https://prod.myserver.com"
  } : {
    serviceUrl: "http://localhost:8000"
  })
} 

and then try to reference the file from my tsx component files as such (take into account that the webpack.config.js is in the root folder and my components in /ClientApp/components):

import config from '../../webpack.config.js';

or

import {externals} from '../../webpack.config.js';

but I get the following error message:

'webpack.config.js' was resolved to '[PROJECT_DIR]/webpack.config.js', but '--allowJs' is not set.

Any solution/alternative to solve this issue? Thanks

Upvotes: 3

Views: 2966

Answers (2)

Estus Flask
Estus Flask

Reputation: 222626

import config from '../../webpack.config.js' shouldn't be used in the application itself, it will cause ill effects (it is supposed to be used by Webpack) and won't provide necessary export.

externals: { 'config': ... } means that non-existing config module export is mapped to specified value.

It is supposed to be used like:

import * as config from 'config';

A more conventional approach is to provide environment constant as a global and use it in real config.ts module.

Upvotes: 1

Nathan Friend
Nathan Friend

Reputation: 12834

My favorite way of solving the problem you're describing is to use Webpack's DefinePlugin:

The DefinePlugin allows you to create global constants which can be configured at compile time. This can be useful for allowing different behavior between development builds and release builds.

In your webpack.config.js, you can create a global constant that you can access in your application code like this:

new webpack.DefinePlugin({
    ENVIRONMENT: 'prod'
})

Then, in your TypeScript code, you can access this constant like this:

declare const ENVIRONMENT: 'prod' | 'test' | 'dev' | 'etc...';
if (ENVIRONMENT === 'prod') {
    serverUrl = 'https://example.com';
} else {
    .... 
}

Note that this method requires that you build your application separately for each environment. If instead you build your application once, and then deploy the output to multiple environments, you might consider putting this kind of configuration in a JSON file that you can swap out on a per-environment basis.

Upvotes: 3

Related Questions