Skip to content

Commit d382a5a

Browse files
committed
feat: proxies currentEnvironment in webpack plugin
1 parent 6dec0fe commit d382a5a

File tree

4 files changed

+96
-3
lines changed

4 files changed

+96
-3
lines changed

app-config-webpack/src/index.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,77 @@ describe('frontend-webpack-project example', () => {
160160
});
161161
});
162162

163+
it('fills in currentEnvironment function', async () => {
164+
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
165+
166+
await new Promise<void>((done, reject) => {
167+
webpack([createOptions({}, true)], (err, stats) => {
168+
if (err) return reject(err);
169+
if (!stats) return reject(new Error('no stats'));
170+
if (stats.hasErrors()) reject(stats.toString());
171+
172+
const { children } = stats.toJson({ source: true });
173+
const [{ modules = [] }] = children || [];
174+
175+
expect(
176+
modules.some(({ source }) => source?.includes('export function currentEnvironment()')),
177+
).toBe(true);
178+
expect(modules.some(({ source }) => source?.includes('return "test";'))).toBe(true);
179+
180+
done();
181+
});
182+
});
183+
});
184+
185+
it('fills in currentEnvironment function with custom environment', async () => {
186+
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
187+
process.env.APP_CONFIG_ENV = 'foobar';
188+
189+
await new Promise<void>((done, reject) => {
190+
webpack([createOptions({}, true)], (err, stats) => {
191+
if (err) return reject(err);
192+
if (!stats) return reject(new Error('no stats'));
193+
if (stats.hasErrors()) reject(stats.toString());
194+
195+
const { children } = stats.toJson({ source: true });
196+
const [{ modules = [] }] = children || [];
197+
198+
expect(
199+
modules.some(({ source }) => source?.includes('export function currentEnvironment()')),
200+
).toBe(true);
201+
expect(modules.some(({ source }) => source?.includes('return "foobar";'))).toBe(true);
202+
203+
done();
204+
});
205+
});
206+
});
207+
208+
it('uses custom options for currentEnvironment', async () => {
209+
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
210+
process.env.APP_CONFIG_ENV = 'test';
211+
212+
await new Promise<void>((done, reject) => {
213+
webpack(
214+
[createOptions({ loading: { environmentOverride: 'foobar' } }, true)],
215+
(err, stats) => {
216+
if (err) return reject(err);
217+
if (!stats) return reject(new Error('no stats'));
218+
if (stats.hasErrors()) reject(stats.toString());
219+
220+
const { children } = stats.toJson({ source: true });
221+
const [{ modules = [] }] = children || [];
222+
223+
expect(
224+
modules.some(({ source }) => source?.includes('export function currentEnvironment()')),
225+
).toBe(true);
226+
expect(modules.some(({ source }) => source?.includes('return "foobar";'))).toBe(true);
227+
228+
done();
229+
},
230+
);
231+
});
232+
});
233+
163234
it.skip('does not bundle the validateConfig function', async () => {
164235
process.env.APP_CONFIG = JSON.stringify({ externalApiUrl: 'https://localhost:3999' });
165236

app-config-webpack/src/loader.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getOptions, parseQuery } from 'loader-utils';
22
import { loadValidatedConfig } from '@app-config/main';
3+
import { currentEnvironment, asEnvOptions } from '@app-config/node';
34
import type { Options } from './index';
45

56
type LoaderContext = Parameters<typeof getOptions>[0];
@@ -11,7 +12,7 @@ const loader = function AppConfigLoader(this: Loader) {
1112
if (this.cacheable) this.cacheable();
1213

1314
const callback = this.async()!;
14-
const { noGlobal = false, loading, schemaLoading }: Options = {
15+
const { noGlobal = false, loading = {}, schemaLoading }: Options = {
1516
...getOptions(this),
1617
...parseQuery(this.resourceQuery),
1718
};
@@ -63,6 +64,18 @@ const loader = function AppConfigLoader(this: Loader) {
6364
`;
6465
}
6566

67+
const { environmentOverride, environmentAliases, environmentSourceNames } = loading;
68+
69+
generatedText = `${generatedText}
70+
export function currentEnvironment() {
71+
return ${JSON.stringify(
72+
currentEnvironment(
73+
asEnvOptions(environmentOverride, environmentAliases, environmentSourceNames),
74+
),
75+
)};
76+
}
77+
`;
78+
6679
return generatedText;
6780
};
6881

tests/webpack-projects/webpack5/cypress/integration/main.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,10 @@ describe('Config Loading', () => {
4545
`"longStringProperty": "some long string with a \\" char and '\\\\n"`,
4646
);
4747
});
48+
49+
it('renders currentEnvironment', () => {
50+
cy.visit('/');
51+
52+
cy.get('body').should('contain', `Environment: production`);
53+
});
4854
});
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { config, validateConfig } from '@app-config/main';
1+
import { config, validateConfig, currentEnvironment } from '@app-config/main';
22

33
validateConfig(config);
44

@@ -7,5 +7,8 @@ if (validateConfig.errors) {
77
.map((err) => err.message)
88
.join(', ')}`;
99
} else {
10-
document.body.innerHTML = `<pre>${JSON.stringify(config, null, 2)}</pre>`;
10+
document.body.innerHTML = `
11+
<pre>${JSON.stringify(config, null, 2)}</pre>
12+
<pre>Environment: ${currentEnvironment()}</pre>
13+
`;
1114
}

0 commit comments

Comments
 (0)