Rsbuild supports injecting environment variables or expressions into your code during the build. This helps distinguish between different running environments or replace constants.
This chapter explains how to use environment variables in Rsbuild.
Rsbuild injects some environment variables into your code by default using source.define. These are replaced with their specified values during the build:
import.meta.env
contains these environment variables:
process.env
contains these environment variables:
'production' | 'development' | 'none'
Use import.meta.env.MODE
in client code to read the mode configuration value.
In development mode, the above code will be compiled to:
In production mode, the above code will be compiled to:
During code minification, if (false) { ... }
will be recognized as invalid code and removed automatically.
boolean
If mode is 'development'
, the value is true
; otherwise, it is false
.
boolean
If mode is 'production'
, the value is true
; otherwise, it is false
.
string
You can use import.meta.env.BASE_URL
in client code to access the server's base path. The base path is determined by the server.base configuration and is useful for referencing public folder assets in your code.
For example, we set the server's base path to /foo
using the server.base configuration:
Then, the URL for the favicon.ico
file in the public directory is http://localhost:3000/foo/favicon.ico
. You can use import.meta.env.BASE_URL
to construct the URL in JavaScript files:
string
You can use import.meta.env.ASSET_PREFIX
in client code to access the URL prefix of static assets.
assetPrefix
to make string concatenation easier.For example, we copy the static/icon.png
image to the dist
directory using the output.copy configuration:
Then we can access the image URL in client code:
In development mode, the above code will be compiled to:
In production mode, the above code will be compiled to:
string
Rsbuild also allows using process.env.BASE_URL
, which is an alias of import.meta.env.BASE_URL.
For example, in the HTML template, you can use process.env.BASE_URL
to concatenate the URL:
string
Rsbuild also allows using process.env.ASSET_PREFIX
, which is an alias of import.meta.env.ASSET_PREFIX.
For example, in the HTML template, you can use process.env.ASSET_PREFIX
to concatenate the URL:
string
By default, Rsbuild sets the process.env.NODE_ENV
environment variable to 'development'
in development mode and 'production'
in production mode.
You can use process.env.NODE_ENV
directly in Node.js and in client code.
In development mode, the above code will be compiled to:
In production mode, the above code will be compiled to:
During code minification, if (false) { ... }
will be recognized as invalid code and removed automatically.
process.env.NODE_ENV
is injected by Rspack by default. To disable the injection or customize the value, use Rspack's optimization.nodeEnv option:
.env
fileWhen a .env
file exists in the project root directory, Rsbuild CLI automatically uses dotenv to load these environment variables and add them to the current Node.js process. The Public Variables will be exposed in client code.
You can access these environment variables through import.meta.env.[name]
or process.env.[name]
.
Rsbuild supports reading the following types of env files:
File Name | Description |
---|---|
.env | Loaded by default in all scenarios. |
.env.local | Local usage of the .env file, should be added to .gitignore. |
.env.development | Read when process.env.NODE_ENV is 'development' . |
.env.production | Read when process.env.NODE_ENV is 'production' . |
.env.development.local | Local usage of the .env.development file, should be added to .gitignore. |
.env.production.local | Local usage of the .env.production file, should be added to .gitignore. |
If multiple of the above files exist, they will all be loaded, with files listed lower in the table having higher priority.
Rsbuild also supports reading .env.[mode]
and .env.[mode].local
files. You can specify the env mode using the --env-mode <mode>
flag.
For example, set the env mode as test
:
Rsbuild will read these files in the following order and merge their contents. If the same environment variable is defined in multiple files, values from files loaded later will override those from files loaded earlier:
The --env-mode
option takes precedence over process.env.NODE_ENV
.
We recommend using --env-mode
to set the env mode instead of modifying process.env.NODE_ENV
.
By default, the .env
file is located in the root directory of the project. You can specify the env directory by using the --env-dir <dir>
option in the CLI.
For example, to specify the env directory as config
:
In this case, Rsbuild will read the ./config/.env
and other env files.
For example, create a .env
file and add the following contents:
Then in the rsbuild.config.ts
file, you can access the environment variables using import.meta.env.[name]
or process.env.[name]
:
Now, create a .env.local
file and add the following contents:
The value of BAR
is overwritten to '2'
:
If you are not using the Rsbuild CLI and are using the JavaScript API instead, you will need to manually call the loadEnv method to read environment variables and inject them via the source.define config.
You can disable loading .env
files by using the --no-env
flag in the CLI.
When using the --no-env
flag, Rsbuild CLI will not read any .env
files. You can then manage environment variables using other tools like dotenvx.
All environment variables starting with PUBLIC_
can be accessed in client code. For example, if the following variables are defined:
In client code, you can access these environment variables through import.meta.env.PUBLIC_*
or process.env.PUBLIC_*
. Rsbuild will match the identifiers and replace them with their corresponding values.
Public variables will replace identifiers in client code. The replacement scope includes:
.js
, .ts
, .tsx
, etc.Note that public variables will not replace identifiers in the following files:
.css
, .scss
, .less
, etc.Rsbuild provides the loadEnv method, which can inject environment variables with any prefix into client code.
For example, when migrating a Create React App project to Rsbuild, you can read environment variables starting with REACT_APP_
and inject them through the source.define config as follows:
By using source.define, you can replace global identifiers with expressions or values at compile time.
define
is similar to macro definition capabilities in other languages. It is often used to inject environment variables and other information into code during build time.
The most basic use case for define
is to replace global identifiers at compile time.
The value of the environment variable NODE_ENV
affects the behavior of many vendor packages. Usually, we need to set it to production
.
Note that the value provided here must be a JSON string, e.g. process.env.NODE_ENV
with a value of "production"
should be passed in as "\"production\""
to be processed correctly.
Similarly, { foo: "bar" }
should be converted to "{\"foo\":\"bar\"}"
. If you pass the object directly, it means replacing the identifier process.env.NODE_ENV.foo
with the identifier bar
.
For more about source.define
, refer to the API References.
The NODE_ENV
environment variable shown in the example above is already injected by Rsbuild, so you usually don't need to configure it manually.
Note that source.define
can only match complete global identifiers. You can think of it as a text replacement process.
If the identifier in the code doesn't exactly match the key defined in define
, Rsbuild will not replace it.
When using source.define
, avoid replacing the entire process.env
object. For example, the following usage is not recommended:
If you use the above approach, it will cause the following problems:
process.env
reference will be replaced by a complete environment variable object, increasing bundle size and decreasing performance.Therefore, inject environment variables on process.env
according to actual needs and avoid replacing it entirely.
When you access a public environment variable in a TypeScript file, TypeScript may report that the variable lacks a type definition. You'll need to add the corresponding type declaration.
For example, if you reference a PUBLIC_FOO
variable, TypeScript will display the following error:
To fix this, you can create a src/env.d.ts
file in your project and add the following content:
Rsbuild provides default TypeScript type definitions for import.meta.env
through Preset types.
If you have customized environment variables starting with import.meta.env
, you can extend the ImportMetaEnv
interface:
By default, Rsbuild's preset types allow you to access any property on import.meta.env
without TypeScript type errors.
For stricter type safety, you can enable the strictImportMetaEnv
option by extending the RsbuildTypeOptions
interface. When this option is enabled, only properties predefined by Rsbuild or explicitly declared in your project can be accessed. Accessing any other property will cause a TypeScript type error.
You can add the following code to your src/env.d.ts
file:
If the type for process.env
is missing, please install the dependency @types/node:
Then extend the type of process.env
:
define
can also mark dead code to assist Rspack with tree shaking optimization.
Build different artifacts for different languages by replacing import.meta.env.LANGUAGE
with a specific value. For example:
For an internationalized code:
Specifying the environment variable LANGUAGE=zh
and then running build will eliminate the dead code:
Unused components will not be bundled, and their dependencies will be removed accordingly, resulting in a smaller build output.