From 8cb6a86475c52cce8cd4cdcec188b4311e92f838 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 10 Apr 2020 14:03:08 +0200 Subject: [PATCH] Do not load Intl.js polyfill by default on Node This change updates the `with-react-intl` example to prevent it from polyfilling `Intl` in a Node environment when it is not needed. --- examples/with-react-intl/package.json | 1 + examples/with-react-intl/server.js | 37 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/examples/with-react-intl/package.json b/examples/with-react-intl/package.json index 3ed553a87fff60..95d67b31902c47 100644 --- a/examples/with-react-intl/package.json +++ b/examples/with-react-intl/package.json @@ -15,6 +15,7 @@ "full-icu": "^1.3.0", "glob": "^7.1.4", "intl": "^1.2.5", + "intl-locales-supported": "1.8.4", "next": "latest", "react": "^16.9.0", "react-dom": "^16.9.0", diff --git a/examples/with-react-intl/server.js b/examples/with-react-intl/server.js index bd3d2285df96c6..c2874d60f2479f 100644 --- a/examples/with-react-intl/server.js +++ b/examples/with-react-intl/server.js @@ -1,13 +1,33 @@ +const { basename } = require('path') +const glob = require('glob') +const areIntlLocalesSupported = require('intl-locales-supported').default + +// Get the supported languages by looking for translations in the `lang/` dir. +const supportedLanguages = glob + .sync('./lang/*.json') + .map(f => basename(f, '.json')) + // Polyfill Node with `Intl` that has data for all locales. // See: https://formatjs.io/guides/runtime-environments/#server -const IntlPolyfill = require('intl') -Intl.NumberFormat = IntlPolyfill.NumberFormat -Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat +if (global.Intl) { + // Determine if the built-in `Intl` has the locale data we need. + if (!areIntlLocalesSupported(supportedLanguages)) { + // `Intl` exists, but it doesn't have the data we need, so load the + // polyfill and patch the constructors we need with the polyfills. + const IntlPolyfill = require('intl') + Intl.NumberFormat = IntlPolyfill.NumberFormat + Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat + Intl.__disableRegExpRestore = IntlPolyfill.__disableRegExpRestore + } +} else { + // No `Intl`, so use and load the polyfill. + global.Intl = require('intl') +} // Fix: https://github.com/zeit/next.js/issues/11777 // See related issue: https://github.com/andyearnshaw/Intl.js/issues/308 -if (IntlPolyfill.__disableRegExpRestore) { - IntlPolyfill.__disableRegExpRestore() +if (Intl.__disableRegExpRestore) { + Intl.__disableRegExpRestore() } // Polyfill DOMParser for **pre-v4** react-intl used by formatjs. @@ -17,10 +37,8 @@ if (IntlPolyfill.__disableRegExpRestore) { // global.DOMParser = DOMParser const { readFileSync } = require('fs') -const { basename } = require('path') const { createServer } = require('http') const accepts = require('accepts') -const glob = require('glob') const next = require('next') const port = parseInt(process.env.PORT, 10) || 3000 @@ -28,11 +46,6 @@ const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() -// Get the supported languages by looking for translations in the `lang/` dir. -const supportedLanguages = glob - .sync('./lang/*.json') - .map(f => basename(f, '.json')) - // We need to expose React Intl's locale data on the request for the user's // locale. This function will also cache the scripts by lang in memory. const localeDataCache = new Map()