Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
feat(conditionalIntl): added env var for Itnl
Browse files Browse the repository at this point in the history
  • Loading branch information
timBarton96 authored Mar 26, 2024
1 parent 8e543f4 commit 7b65266
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 12 deletions.
11 changes: 11 additions & 0 deletions __tests__/client/prerender.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ describe('loadPrerenderScripts', () => {
expect(getLocalePack).not.toHaveBeenCalled();
})
);

it('should still resolve if useNativeIntl is set to true but not call getLocalePack', async () => {
window.useNativeIntl = true;
const { getLocalePack } = require('@americanexpress/one-app-ducks');
const initialState = fromJS({ intl: { activeLocale: 'es-ES' } });
getLocalePack.mockClear();

await loadPrerenderScripts(initialState);

expect(getLocalePack).not.toHaveBeenCalled();
});
});

describe('moveHelmetScripts', () => {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/integration/helpers/testRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const setUpTestRunner = async ({
}));

// uncomment this line in order to view full logs for debugging
// logWatcherDuplex.pipe(process.stdout);
logWatcherDuplex.pipe(process.stdout);

try {
await Promise.all([
Expand Down
16 changes: 16 additions & 0 deletions __tests__/server/config/env/runTime.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,4 +525,20 @@ describe('runTime', () => {
expect(() => otelTraceCollectorUrl.validate()).not.toThrow();
});
});

describe('ONE_CONFIG_USE_NATIVE_INTL', () => {
const useNativeIntl = getEnvVarConfig('ONE_CONFIG_USE_NATIVE_INTL');

it('should have a default value of false', () => {
expect(useNativeIntl.defaultValue).toBe('false');
});

it('should normalise the value to false when not explicitly true', () => {
expect(useNativeIntl.normalize('Value')).toBe('false');
expect(useNativeIntl.normalize('VALUE')).toBe('false');
expect(useNativeIntl.normalize('true')).toBe('true');
expect(useNativeIntl.normalize('TRUE')).toBe('true');
expect(useNativeIntl.normalize('FALSE')).toBe('false');
});
});
});
31 changes: 31 additions & 0 deletions __tests__/server/plugins/reactHtml/index.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import reactHtml, {
renderModuleScripts,
renderExternalFallbacks,
checkStateForRedirectAndStatusCode,
renderEnvironmentVariables,
} from '../../../../src/server/plugins/reactHtml';
import { getClientStateConfig } from '../../../../src/server/utils/stateConfig';
import transit from '../../../../src/universal/utils/transit';
Expand Down Expand Up @@ -301,6 +302,8 @@ describe('reactHtml', () => {
cdnUrl: '/cdnUrl/',
rootModuleName: 'test-root',
}));

process.env.ONE_CONFIG_USE_NATIVE_INTL = 'false';
});

function removeInitialState(body) {
Expand Down Expand Up @@ -448,6 +451,15 @@ describe('reactHtml', () => {
expect(reply.send.mock.calls[0][0]).not.toContain('src="/cdnUrl/app/1.2.3-rc.4-abc123/i18n/');
});

it('sends a rendered page without the locale data script tag when te ONE_CONFIG_USE_NATIVE_INTL environment variable is true', () => {
process.env.ONE_CONFIG_USE_NATIVE_INTL = 'true';
setFullMap();
sendHtml(request, reply);

expect(reply.send).toHaveBeenCalledTimes(1);
expect(reply.send.mock.calls[0][0]).not.toContain('src="/cdnUrl/app/1.2.3-rc.4-abc123/i18n/');
});

it('sends a rendered page with the module styles and scripts', () => {
sendHtml(request, reply);
expect(reply.send).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -1349,4 +1361,23 @@ describe('reactHtml', () => {
expect(reply.send.mock.calls[0][0]).toContain('<title>One App</title>');
});
});

describe('renderEnvironmentVariables', () => {
it('should set useNativeIntl to false if the environment variable is not true', () => {
expect(renderEnvironmentVariables('')).toMatchInlineSnapshot(`
"<script id="environment-variables" >
window.useNativeIntl = false
</script>"
`);
});

it('should set useNativeIntl to true is the environment variable is true', () => {
process.env.ONE_CONFIG_USE_NATIVE_INTL = 'true';
expect(renderEnvironmentVariables('')).toMatchInlineSnapshot(`
"<script id="environment-variables" >
window.useNativeIntl = true
</script>"
`);
});
});
});
26 changes: 25 additions & 1 deletion docs/api/server/Environment-Variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ One App can be configured via Environment Variables:
* [`ONE_CLIENT_ROOT_MODULE_NAME`](#one_client_root_module_name) ⚠️
* [`ONE_CLIENT_CDN_URL`](#one_client_cdn_url) ⚠️
* [`ONE_CONFIG_ENV`](#one_config_env) ⚠️
* [`ONE_CONFIG_USE_NATIVE_INTL`](#one_config_use_native_intl)
* Running in Development
* [`NODE_ENV`](#node_env) ⚠️
* [`ONE_CLIENT_ROOT_MODULE_NAME`](#one_client_root_module_name) ⚠️
* [`ONE_CONFIG_ENV`](#one_config_env) ⚠️
* [`ONE_DANGEROUSLY_ACCEPT_BREAKING_EXTERNALS`](#ONE_DANGEROUSLY_ACCEPT_BREAKING_EXTERNALS)
* [`ONE_CSP_ALLOW_INLINE_SCRIPTS`](#ONE_CSP_ALLOW_INLINE_SCRIPTS)
* [`ONE_DANGEROUSLY_DISABLE_CSP`](#ONE_DANGEROUSLY_DISABLE_CSP)
* [`ONE_CONFIG_USE_NATIVE_INTL`](#one_config_use_native_intl)
* Server Settings
* [`HOLOCRON_SERVER_MAX_MODULES_RETRY`](#holocron_server_max_modules_retry)
* [`HOLOCRON_SERVER_MAX_SIM_MODULES_FETCH`](#holocron_server_max_sim_modules_fetch)
Expand Down Expand Up @@ -79,6 +81,7 @@ One App can be configured via Environment Variables:
* [`ONE_CLIENT_REPORTING_URL`](#one_client_reporting_url) ⚠️
* [`ONE_CLIENT_ROOT_MODULE_NAME`](#one_client_root_module_name) ⚠️
* [`ONE_CONFIG_ENV`](#one_config_env) ⚠️
* [`ONE_CONFIG_USE_NATIVE_INTL`](#one_config_use_native_intl)
* [`ONE_ENABLE_POST_TO_MODULE_ROUTES`](#one_enable_post_to_module_routes)
* [`ONE_ENABLE_REQUEST_LOGGING_WHILE_TRACING`](#one_enable_request_logging_while_tracing)
* [`ONE_MAP_POLLING_MAX`](#one_map_polling_max)
Expand Down Expand Up @@ -550,6 +553,27 @@ ONE_CONFIG_ENV=staging
ONE_CONFIG_ENV=undefined
```
## `ONE_CONFIG_USE_NATIVE_INTL`
**Runs In**
* ✅ Production
* ✅ Development
Feature flag to disable lean-intl polyfill.
This allows you to use modern intl features such as timezones, but will result in your application supporting fewer older browsers.
**Shape**
```bash
ONE_CONFIG_USE_NATIVE_INTL=Boolean
```
**Example**
```bash
ONE_CONFIG_USE_NATIVE_INTL=true
```
**Default Value**
```bash
ONE_CONFIG_USE_NATIVE_INTL=false
```
## `ONE_DANGEROUSLY_ACCEPT_BREAKING_EXTERNALS`
**Runs In**
Expand Down Expand Up @@ -903,4 +927,4 @@ ONE_ENABLE_REQUEST_LOGGING_WHILE_TRACING=true
[`HTTPS_PRIVATE_KEY_PASS_FILE_PATH`]: #https_private_key_pass_file_path
[`HTTPS_PORT`]: #https_port
[OTel Environment Variable Specification]: https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/
[OTel Resource SDK documentation]: https://opentelemetry.io/docs/specs/otel/resource/sdk/#specifying-resource-information-via-an-environment-variable
[OTel Resource SDK documentation]: https://opentelemetry.io/docs/specs/otel/resource/sdk/#specifying-resource-information-via-an-environment-variable
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"dependencies": {
"@americanexpress/env-config-utils": "^2.0.4",
"@americanexpress/fetch-enhancers": "^1.1.5",
"@americanexpress/one-app-ducks": "^4.4.4",
"@americanexpress/one-app-ducks": "^4.5.1",
"@americanexpress/one-app-router": "^1.2.1",
"@americanexpress/one-app-server-bundler": "^1.0.2",
"@americanexpress/vitruvius": "^3.0.1",
Expand Down
6 changes: 4 additions & 2 deletions src/client/polyfill/Intl.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@

import Intl from 'lean-intl';

global.Intl = Intl;
global.IntlPolyfill = Intl;
if (!(window && window.useNativeIntl)) {
global.Intl = Intl;
global.IntlPolyfill = Intl;
}
2 changes: 1 addition & 1 deletion src/client/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function initializeClientStore() {

export function loadPrerenderScripts(initialState) {
const locale = initialState && initialState.getIn(['intl', 'activeLocale']);
return locale ? getLocalePack(locale) : Promise.resolve();
return locale && !window?.useNativeIntl ? getLocalePack(locale) : Promise.resolve();
}

export function moveHelmetScripts() {
Expand Down
10 changes: 10 additions & 0 deletions src/server/config/env/runTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ const runTime = [
validate: (value) => { if (!value) { throw new Error('The `ONE_CLIENT_ROOT_MODULE_NAME` environment variable must be defined.'); } },
defaultValue: () => (process.env.NODE_ENV === 'development' ? argv.rootModuleName : undefined),
},
{
name: 'ONE_CONFIG_USE_NATIVE_INTL',
defaultValue: 'false',
normalize: (input) => {
if (input?.toLowerCase() === 'true') {
return 'true';
}
return 'false';
},
},
{
name: 'ONE_REFERRER_POLICY_OVERRIDE',
defaultValue: () => '',
Expand Down
14 changes: 13 additions & 1 deletion src/server/plugins/reactHtml/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ const legacyBrowserChunkAssets = getChunkAssets(readJsonFile('../../../.build-me
.map((chunkAsset) => `legacy/${chunkAsset}`);

function renderI18nScript(clientInitialState, appBundlesURLPrefix) {
if (process.env.ONE_CONFIG_USE_NATIVE_INTL === 'true') {
return '';
}

const i18nFile = getI18nFileFromState(clientInitialState);
if (!i18nFile) {
return '';
Expand Down Expand Up @@ -236,6 +240,12 @@ export function getHead({
`;
}

export function renderEnvironmentVariables(nonce) {
return `<script id="environment-variables" ${nonce}>
window.useNativeIntl = ${process.env.ONE_CONFIG_USE_NATIVE_INTL === 'true'}
</script>`;
}

export function getBody({
isLegacy,
helmetInfo,
Expand All @@ -253,13 +263,14 @@ export function getBody({
const bundle = isLegacy ? 'legacyBrowser' : 'browser';
const { bodyAttributes, script } = helmetInfo;
const bundlePrefixForBrowser = isLegacy ? `${appBundlesURLPrefix}/legacy` : appBundlesURLPrefix;
const nonce = scriptNonce ? `nonce="${scriptNonce}"` : '';
return `
<body${(bodyAttributes && ` ${bodyAttributes.toString()}`) || ''}>
<div id="root">${appHtml || ''}</div>
${disableScripts
? ''
: `
<script id="initial-state" ${scriptNonce ? `nonce="${scriptNonce}"` : ''}>
<script id="initial-state" ${nonce}>
window.__webpack_public_path__ = ${jsonStringifyForScript(`${appBundlesURLPrefix}/`)};
window.__CLIENT_HOLOCRON_MODULE_MAP__ = ${jsonStringifyForScript(clientModuleMapCache[bundle])};
window.__INITIAL_STATE__ = ${jsonStringifyForScript(serializeClientInitialState(clientInitialState, request))};
Expand All @@ -268,6 +279,7 @@ export function getBody({
window.__render_mode__ = '${renderMode}';
window.__HOLOCRON_EXTERNALS__ = ${jsonStringifyForScript(getRequiredExternalsRegistry())};
</script>
${renderEnvironmentVariables(nonce)}
${assets}
${renderI18nScript(clientInitialState, bundlePrefixForBrowser)}
${renderExternalFallbacks({
Expand Down
6 changes: 5 additions & 1 deletion src/server/polyfill/intl.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@
* permissions and limitations under the License.
*/

global.Intl = require('lean-intl');
import Intl from 'lean-intl';

if (process.env.ONE_CONFIG_USE_NATIVE_INTL !== 'true') {
global.Intl = Intl;
}

0 comments on commit 7b65266

Please sign in to comment.