Skip to content

Commit 8e318ea

Browse files
authored
feat: support for destructuring import.meta.env (#5979)
1 parent b526404 commit 8e318ea

File tree

9 files changed

+258
-101
lines changed

9 files changed

+258
-101
lines changed
Lines changed: 127 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,164 @@
11
import { build, rspackOnlyTest } from '@e2e/helper';
22
import { expect, test } from '@playwright/test';
33

4-
test('should define vars in production mode correctly', async () => {
4+
declare global {
5+
interface Window {
6+
[key: string]: unknown;
7+
}
8+
}
9+
10+
test('should define vars in production mode correctly', async ({ page }) => {
511
const rsbuild = await build({
612
cwd: __dirname,
13+
page,
14+
rsbuildConfig: {
15+
mode: 'production',
16+
},
717
});
818

9-
const file = await rsbuild.getIndexFile();
10-
expect(file.content).toContain(
11-
'console.log("import.meta.env.MODE","production")',
19+
const { content } = await rsbuild.getIndexFile();
20+
21+
// Replaced identifiers
22+
expect(content).toContain('"[value] import.meta.env.MODE","production"');
23+
expect(content).toContain('"[value] process.env.NODE_ENV","production"');
24+
25+
// runtime values
26+
expect(
27+
await page.evaluate(() => window['import.meta.env.MODE === "development"']),
28+
).toBe(undefined);
29+
expect(
30+
await page.evaluate(
31+
() => window['import.meta.env?.MODE === "development"'],
32+
),
33+
).toBe(undefined);
34+
expect(
35+
await page.evaluate(() => window['import.meta.env.MODE === "production"']),
36+
).toBe(true);
37+
expect(
38+
await page.evaluate(() => window['import.meta.env?.MODE === "production"']),
39+
).toBe(true);
40+
expect(await page.evaluate(() => window['import.meta.env.DEV'])).toBe(
41+
undefined,
1242
);
13-
expect(file.content).toContain(
14-
'console.log("process.env.NODE_ENV","production")',
43+
expect(await page.evaluate(() => window['import.meta.env?.DEV'])).toBe(
44+
undefined,
1545
);
16-
expect(file.content).not.toContain('console.log("import.meta.env.DEV")');
17-
expect(file.content).toContain('console.log("import.meta.env.PROD")');
46+
expect(await page.evaluate(() => window['import.meta.env.PROD'])).toBe(true);
47+
expect(await page.evaluate(() => window['import.meta.env?.PROD'])).toBe(true);
48+
expect(await page.evaluate(() => window.destructedValues)).toBe(
49+
'MODE:production,DEV:false,PROD:true',
50+
);
51+
52+
// dead code elimination
53+
expect(content).not.toContain(
54+
'[condition] import.meta.env.MODE === "development"',
55+
);
56+
expect(content).not.toContain('[condition] import.meta.env.DEV');
57+
58+
await rsbuild.close();
1859
});
1960

20-
test('should define vars in development mode correctly', async () => {
61+
test('should define vars in development mode correctly', async ({ page }) => {
2162
const rsbuild = await build({
2263
cwd: __dirname,
64+
page,
2365
rsbuildConfig: {
2466
mode: 'development',
2567
},
2668
});
2769

28-
const file = await rsbuild.getIndexFile();
29-
expect(file.content).toContain(
30-
'console.log(\'import.meta.env.MODE\', "development");',
70+
const { content } = await rsbuild.getIndexFile();
71+
72+
// Replaced identifiers
73+
expect(content).toContain(`'[value] import.meta.env.MODE', "development"`);
74+
expect(content).toContain(`'[value] process.env.NODE_ENV', "development"`);
75+
76+
// runtime values
77+
expect(
78+
await page.evaluate(() => window['import.meta.env.MODE === "development"']),
79+
).toBe(true);
80+
expect(
81+
await page.evaluate(
82+
() => window['import.meta.env?.MODE === "development"'],
83+
),
84+
).toBe(true);
85+
expect(
86+
await page.evaluate(() => window['import.meta.env.MODE === "production"']),
87+
).toBe(undefined);
88+
expect(
89+
await page.evaluate(() => window['import.meta.env?.MODE === "production"']),
90+
).toBe(undefined);
91+
expect(await page.evaluate(() => window['import.meta.env.DEV'])).toBe(true);
92+
expect(await page.evaluate(() => window['import.meta.env?.DEV'])).toBe(true);
93+
expect(await page.evaluate(() => window['import.meta.env.PROD'])).toBe(
94+
undefined,
95+
);
96+
expect(await page.evaluate(() => window['import.meta.env?.PROD'])).toBe(
97+
undefined,
3198
);
32-
expect(file.content).toContain(
33-
'console.log(\'process.env.NODE_ENV\', "development")',
99+
expect(await page.evaluate(() => window.destructedValues)).toBe(
100+
'MODE:development,DEV:true,PROD:false',
34101
);
35-
expect(file.content).toContain("console.log('import.meta.env.DEV');");
36-
expect(file.content).not.toContain("console.log('import.meta.env.PROD');");
102+
103+
await rsbuild.close();
37104
});
38105

39-
test('should define vars in none mode correctly', async () => {
106+
test('should define vars in none mode correctly', async ({ page }) => {
40107
const rsbuild = await build({
41108
cwd: __dirname,
109+
page,
42110
rsbuildConfig: {
43111
mode: 'none',
44112
},
45113
});
46114

47-
const file = await rsbuild.getIndexFile();
48-
expect(file.content).toContain(
49-
'console.log(\'import.meta.env.MODE\', "none");',
115+
const { content } = await rsbuild.getIndexFile();
116+
117+
// Replaced identifiers
118+
expect(content).toContain(`'[value] import.meta.env.MODE', "none"`);
119+
expect(content).toContain(
120+
`'[value] process.env.NODE_ENV', process.env.NODE_ENV`,
121+
);
122+
123+
// runtime values
124+
expect(
125+
await page.evaluate(() => window['import.meta.env.MODE === "development"']),
126+
).toBe(undefined);
127+
expect(
128+
await page.evaluate(
129+
() => window['import.meta.env?.MODE === "development"'],
130+
),
131+
).toBe(undefined);
132+
expect(
133+
await page.evaluate(() => window['import.meta.env.MODE === "production"']),
134+
).toBe(undefined);
135+
expect(
136+
await page.evaluate(() => window['import.meta.env?.MODE === "production"']),
137+
).toBe(undefined);
138+
expect(await page.evaluate(() => window['import.meta.env.DEV'])).toBe(
139+
undefined,
140+
);
141+
expect(await page.evaluate(() => window['import.meta.env?.DEV'])).toBe(
142+
undefined,
143+
);
144+
expect(await page.evaluate(() => window['import.meta.env.PROD'])).toBe(
145+
undefined,
50146
);
51-
expect(file.content).toContain(
52-
"console.log('process.env.NODE_ENV', process.env.NODE_ENV)",
147+
expect(await page.evaluate(() => window['import.meta.env?.PROD'])).toBe(
148+
undefined,
53149
);
54-
expect(file.content).not.toContain("console.log('import.meta.env.DEV');");
55-
expect(file.content).not.toContain("console.log('import.meta.env.PROD');");
150+
expect(await page.evaluate(() => window.destructedValues)).toBe(
151+
'MODE:none,DEV:false,PROD:false',
152+
);
153+
154+
await rsbuild.close();
56155
});
57156

58157
rspackOnlyTest('should allow to disable NODE_ENV injection', async () => {
59158
const rsbuild = await build({
60159
cwd: __dirname,
61160
rsbuildConfig: {
161+
mode: 'production',
62162
tools: {
63163
rspack: {
64164
optimization: { nodeEnv: false },
@@ -67,8 +167,8 @@ rspackOnlyTest('should allow to disable NODE_ENV injection', async () => {
67167
},
68168
});
69169

70-
const file = await rsbuild.getIndexFile();
71-
expect(file.content).toContain(
72-
'console.log("process.env.NODE_ENV",process.env.NODE_ENV)',
170+
const { content } = await rsbuild.getIndexFile();
171+
expect(content).toContain(
172+
'[value] process.env.NODE_ENV",process.env.NODE_ENV',
73173
);
74174
});

e2e/cases/mode/define/src/index.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,39 @@
1-
console.log('process.env.NODE_ENV', process.env.NODE_ENV);
2-
console.log('import.meta.env.MODE', import.meta.env.MODE);
1+
try {
2+
console.log('[value] process.env.NODE_ENV', process.env.NODE_ENV);
3+
console.log('[value] import.meta.env.MODE', import.meta.env.MODE);
4+
} catch {}
5+
6+
if (import.meta.env.MODE === 'development') {
7+
window['import.meta.env.MODE === "development"'] = true;
8+
}
9+
10+
if (import.meta.env?.MODE === 'development') {
11+
window['import.meta.env?.MODE === "development"'] = true;
12+
}
13+
14+
if (import.meta.env.MODE === 'production') {
15+
window['import.meta.env.MODE === "production"'] = true;
16+
}
17+
18+
if (import.meta.env?.MODE === 'production') {
19+
window['import.meta.env?.MODE === "production"'] = true;
20+
}
321

422
if (import.meta.env.DEV) {
5-
console.log('import.meta.env.DEV');
23+
window['import.meta.env.DEV'] = true;
24+
}
25+
26+
if (import.meta.env?.DEV) {
27+
window['import.meta.env?.DEV'] = true;
628
}
729

830
if (import.meta.env.PROD) {
9-
console.log('import.meta.env.PROD');
31+
window['import.meta.env.PROD'] = true;
1032
}
33+
34+
if (import.meta.env?.PROD) {
35+
window['import.meta.env?.PROD'] = true;
36+
}
37+
38+
const { MODE, DEV, PROD } = import.meta.env;
39+
window.destructedValues = `MODE:${MODE},DEV:${DEV},PROD:${PROD}`;

packages/compat/webpack/tests/__snapshots__/default.test.ts.snap

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,13 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = `
377377
},
378378
DefinePlugin {
379379
"definitions": {
380-
"import.meta.env.ASSET_PREFIX": "\\"\\"",
381-
"import.meta.env.BASE_URL": "\\"/\\"",
382-
"import.meta.env.DEV": true,
383-
"import.meta.env.MODE": "\\"development\\"",
384-
"import.meta.env.PROD": false,
380+
"import.meta.env": {
381+
"ASSET_PREFIX": "\\"\\"",
382+
"BASE_URL": "\\"/\\"",
383+
"DEV": true,
384+
"MODE": "\\"development\\"",
385+
"PROD": false,
386+
},
385387
"process.env.ASSET_PREFIX": "\\"\\"",
386388
"process.env.BASE_URL": "\\"/\\"",
387389
},
@@ -832,11 +834,13 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ
832834
},
833835
DefinePlugin {
834836
"definitions": {
835-
"import.meta.env.ASSET_PREFIX": "\\"\\"",
836-
"import.meta.env.BASE_URL": "\\"/\\"",
837-
"import.meta.env.DEV": false,
838-
"import.meta.env.MODE": "\\"production\\"",
839-
"import.meta.env.PROD": true,
837+
"import.meta.env": {
838+
"ASSET_PREFIX": "\\"\\"",
839+
"BASE_URL": "\\"/\\"",
840+
"DEV": false,
841+
"MODE": "\\"production\\"",
842+
"PROD": true,
843+
},
840844
"process.env.ASSET_PREFIX": "\\"\\"",
841845
"process.env.BASE_URL": "\\"/\\"",
842846
},
@@ -1220,11 +1224,13 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
12201224
},
12211225
DefinePlugin {
12221226
"definitions": {
1223-
"import.meta.env.ASSET_PREFIX": "\\"\\"",
1224-
"import.meta.env.BASE_URL": "\\"/\\"",
1225-
"import.meta.env.DEV": false,
1226-
"import.meta.env.MODE": "\\"production\\"",
1227-
"import.meta.env.PROD": true,
1227+
"import.meta.env": {
1228+
"ASSET_PREFIX": "\\"\\"",
1229+
"BASE_URL": "\\"/\\"",
1230+
"DEV": false,
1231+
"MODE": "\\"production\\"",
1232+
"PROD": true,
1233+
},
12281234
"process.env.ASSET_PREFIX": "\\"\\"",
12291235
"process.env.BASE_URL": "\\"/\\"",
12301236
},
@@ -1591,11 +1597,13 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe
15911597
},
15921598
DefinePlugin {
15931599
"definitions": {
1594-
"import.meta.env.ASSET_PREFIX": "\\"\\"",
1595-
"import.meta.env.BASE_URL": "\\"/\\"",
1596-
"import.meta.env.DEV": false,
1597-
"import.meta.env.MODE": "\\"production\\"",
1598-
"import.meta.env.PROD": true,
1600+
"import.meta.env": {
1601+
"ASSET_PREFIX": "\\"\\"",
1602+
"BASE_URL": "\\"/\\"",
1603+
"DEV": false,
1604+
"MODE": "\\"production\\"",
1605+
"PROD": true,
1606+
},
15991607
"process.env.ASSET_PREFIX": "\\"\\"",
16001608
"process.env.BASE_URL": "\\"/\\"",
16011609
},

packages/core/src/plugins/define.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ export const pluginDefine = (): RsbuildPlugin => ({
5353
const assetPrefix = JSON.stringify(getPublicPathFromChain(chain, false));
5454

5555
const builtinVars: Define = {
56-
'import.meta.env.MODE': JSON.stringify(config.mode),
57-
'import.meta.env.DEV': config.mode === 'development',
58-
'import.meta.env.PROD': config.mode === 'production',
59-
'import.meta.env.BASE_URL': baseUrl,
60-
'import.meta.env.ASSET_PREFIX': assetPrefix,
56+
'import.meta.env': {
57+
MODE: JSON.stringify(config.mode),
58+
DEV: config.mode === 'development',
59+
PROD: config.mode === 'production',
60+
BASE_URL: baseUrl,
61+
ASSET_PREFIX: assetPrefix,
62+
},
6163
'process.env.BASE_URL': baseUrl,
6264
'process.env.ASSET_PREFIX': assetPrefix,
6365
};

packages/core/tests/__snapshots__/builder.test.ts.snap

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,13 @@ exports[`should use Rspack as the default bundler > apply Rspack correctly 1`] =
461461
DefinePlugin {
462462
"_args": [
463463
{
464-
"import.meta.env.ASSET_PREFIX": "\\"\\"",
465-
"import.meta.env.BASE_URL": "\\"/\\"",
466-
"import.meta.env.DEV": true,
467-
"import.meta.env.MODE": "\\"development\\"",
468-
"import.meta.env.PROD": false,
464+
"import.meta.env": {
465+
"ASSET_PREFIX": "\\"\\"",
466+
"BASE_URL": "\\"/\\"",
467+
"DEV": true,
468+
"MODE": "\\"development\\"",
469+
"PROD": false,
470+
},
469471
"process.env.ASSET_PREFIX": "\\"\\"",
470472
"process.env.BASE_URL": "\\"/\\"",
471473
},

0 commit comments

Comments
 (0)