Skip to content

Commit

Permalink
feat: support for import.meta.env.MODE (#3168)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan committed Aug 8, 2024
1 parent d50a5a6 commit c26edc1
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 24 deletions.
File renamed without changes.
File renamed without changes.
47 changes: 47 additions & 0 deletions e2e/cases/mode/define/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { build } from '@e2e/helper';
import { expect, test } from '@playwright/test';

test('should define vars in production mode correctly', async () => {
const rsbuild = await build({
cwd: __dirname,
});

const file = await rsbuild.getIndexFile();
expect(file.content).toContain(
'console.log("import.meta.env.MODE","production")',
);
expect(file.content).not.toContain('console.log("import.meta.env.DEV")');
expect(file.content).toContain('console.log("import.meta.env.PROD")');
});

test('should define vars in development mode correctly', async () => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
mode: 'development',
},
});

const file = await rsbuild.getIndexFile();
expect(file.content).toContain(
'console.log(\'import.meta.env.MODE\', "development");',
);
expect(file.content).toContain("console.log('import.meta.env.DEV');");
expect(file.content).not.toContain("console.log('import.meta.env.PROD');");
});

test('should define vars in none mode correctly', async () => {
const rsbuild = await build({
cwd: __dirname,
rsbuildConfig: {
mode: 'none',
},
});

const file = await rsbuild.getIndexFile();
expect(file.content).toContain(
'console.log(\'import.meta.env.MODE\', "none");',
);
expect(file.content).not.toContain("console.log('import.meta.env.DEV');");
expect(file.content).not.toContain("console.log('import.meta.env.PROD');");
});
7 changes: 7 additions & 0 deletions e2e/cases/mode/define/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
console.log('import.meta.env.MODE', import.meta.env.MODE);
if (import.meta.env.DEV) {
console.log('import.meta.env.DEV');
}
if (import.meta.env.PROD) {
console.log('import.meta.env.PROD');
}
5 changes: 0 additions & 5 deletions e2e/cases/mode/rsbuild.config.ts

This file was deleted.

14 changes: 0 additions & 14 deletions e2e/cases/mode/tsconfig.json

This file was deleted.

12 changes: 12 additions & 0 deletions packages/compat/webpack/tests/__snapshots__/default.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = `
},
DefinePlugin {
"definitions": {
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
},
Expand Down Expand Up @@ -667,6 +670,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ
},
DefinePlugin {
"definitions": {
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""production"",
"import.meta.env.PROD": true,
"process.env.ASSET_PREFIX": """",
},
},
Expand Down Expand Up @@ -971,6 +977,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
RsbuildCorePlugin {},
DefinePlugin {
"definitions": {
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""production"",
"import.meta.env.PROD": true,
"process.env.ASSET_PREFIX": """",
},
},
Expand Down Expand Up @@ -1258,6 +1267,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
RsbuildCorePlugin {},
DefinePlugin {
"definitions": {
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""production"",
"import.meta.env.PROD": true,
"process.env.ASSET_PREFIX": """",
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ exports[`webpackConfig > should allow to append and prepend plugins 1`] = `
},
DefinePlugin {
"definitions": {
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""none"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
},
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/plugins/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export const pluginDefine = (): RsbuildPlugin => ({
api.modifyBundlerChain((chain, { CHAIN_ID, bundler, environment }) => {
const { config } = environment;
const builtinVars: Define = {
'import.meta.env.MODE': JSON.stringify(config.mode),
'import.meta.env.DEV': config.mode === 'development',
'import.meta.env.PROD': config.mode === 'production',
'process.env.ASSET_PREFIX': JSON.stringify(
getPublicPathFromChain(chain, false),
),
Expand Down
3 changes: 3 additions & 0 deletions packages/core/tests/__snapshots__/builder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ exports[`should use rspack as default bundler > apply rspack correctly 1`] = `
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
12 changes: 12 additions & 0 deletions packages/core/tests/__snapshots__/default.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = `
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down Expand Up @@ -817,6 +820,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when prod
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""production"",
"import.meta.env.PROD": true,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down Expand Up @@ -1152,6 +1158,9 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down Expand Up @@ -1557,6 +1566,9 @@ exports[`tools.rspack > should match snapshot 1`] = `
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
3 changes: 3 additions & 0 deletions packages/core/tests/__snapshots__/define.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ exports[`plugin-define > should register define plugin correctly 1`] = `
"_args": [
{
"NAME": ""Jack"",
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""none"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
6 changes: 6 additions & 0 deletions packages/core/tests/__snapshots__/environments.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,9 @@ exports[`environment config > tools.rspack / bundlerChain can be used in environ
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down Expand Up @@ -2000,6 +2003,9 @@ exports[`environment config > tools.rspack / bundlerChain can be used in environ
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-react/tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ exports[`plugins/react > should work with swc-loader 1`] = `
DefinePlugin {
"_args": [
{
"import.meta.env.DEV": true,
"import.meta.env.MODE": ""development"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
3 changes: 3 additions & 0 deletions packages/plugin-vue/tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ DefinePlugin {
"__VUE_OPTIONS_API__": true,
"__VUE_PROD_DEVTOOLS__": false,
"__VUE_PROD_HYDRATION_MISMATCH_DETAILS__": false,
"import.meta.env.DEV": false,
"import.meta.env.MODE": ""none"",
"import.meta.env.PROD": false,
"process.env.ASSET_PREFIX": """",
},
],
Expand Down
43 changes: 38 additions & 5 deletions website/docs/en/guide/advanced/env-vars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,39 @@ Rsbuild supports injecting environment variables or expressions into the code du

## Default Variables

### import.meta.env.MODE

You can use `import.meta.env.MODE` in the client code to read the value of the [mode](/config/mode) configuration.

```ts
if (import.meta.env.MODE === 'development') {
console.log('this is development mode');
}
```

In development mode, the above code will be compiled to:

```js
if (true) {
console.log('this is development mode');
}
```

In production mode, the above code will be compiled to:

```js
if (false) {
console.log('this is development mode');
}
```

During code minification, `if (false) { ... }` will be recognized as invalid code and removed automatically.

You can also use the following environment variables:

- `import.meta.env.DEV`: If [mode](/config/mode) is `'development'`, the value is `true`; otherwise, it is `false`.
- `import.meta.env.PROD`: If [mode](/config/mode) is `'production'`, the value is `true`; otherwise, it is `false`.

### process.env.NODE_ENV

By default, Rsbuild will automatically set the `process.env.NODE_ENV` environment variable to `'development'` in development mode and `'production'` in production mode.
Expand All @@ -16,23 +49,23 @@ if (process.env.NODE_ENV === 'development') {
}
```

In development mode, the above code will be compiled as:
In development mode, the above code will be compiled to:

```js
if (true) {
console.log('this is a development log');
}
```

In production mode, the above code will be compiled as:
In production mode, the above code will be compiled to:

```js
if (false) {
console.log('this is a development log');
}
```

After code minification, `if (false) { ... }` will be recognized as invalid code and removed automatically.
During code minification, `if (false) { ... }` will be recognized as invalid code and removed automatically.

### process.env.ASSET_PREFIX

Expand Down Expand Up @@ -62,13 +95,13 @@ Then we can access the image URL in the client code:
const Image = <img src={`${process.env.ASSET_PREFIX}/static/icon.png`} />;
```

In development mode, the above code will be compiled as:
In development mode, the above code will be compiled to:

```jsx
const Image = <img src={`/static/icon.png`} />;
```

In production mode, the above code will be compiled as:
In production mode, the above code will be compiled to:

```jsx
const Image = <img src={`https://example.com/static/icon.png`} />;
Expand Down
33 changes: 33 additions & 0 deletions website/docs/zh/guide/advanced/env-vars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,39 @@ Rsbuild 支持在编译过程中向代码中注入环境变量或表达式,这

## 默认环境变量

### import.meta.env.MODE

你可以在 client 代码中使用 `import.meta.env.MODE` 来读取 [mode](/config/mode) 配置项的值。

```ts
if (import.meta.env.MODE === 'development') {
console.log('this is development mode');
}
```

在开发模式,以上代码会被编译为:

```js
if (true) {
console.log('this is development mode');
}
```

在生产模式,以上代码会被编译为:

```js
if (false) {
console.log('this is development mode');
}
```

在代码压缩过程中,`if (false) { ... }` 会被识别为无效代码,并被自动移除。

此外,你还可以使用以下环境变量:

- `import.meta.env.DEV`:当 [mode](/config/mode)`'development'` 时,值为 `true`,否则为 `false`
- `import.meta.env.PROD`:当 [mode](/config/mode)`'production'` 时,值为 `true`,否则为 `false`

### process.env.NODE_ENV

默认情况下,Rsbuild 会自动设置 `process.env.NODE_ENV` 环境变量,在开发模式为 `'development'`,生产模式为 `'production'`
Expand Down

0 comments on commit c26edc1

Please sign in to comment.