From aecf3ef93e28f4c98b008c6e2ec72e88fc432c02 Mon Sep 17 00:00:00 2001 From: Amol Umbark Date: Wed, 10 Aug 2022 23:09:34 +0530 Subject: [PATCH] fix: added cache bursting for translations using file hash (#1478) * fix: added cache bursting for translations using file hash Co-authored-by: Palash Gupta --- .gitignore | 1 + frontend/.eslintignore | 1 + frontend/i18-generate-hash.js | 24 ++++++++++++++++++++++++ frontend/package.json | 17 +++++++++-------- frontend/src/ReactI18/index.tsx | 11 ++++++++++- 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 frontend/i18-generate-hash.js diff --git a/.gitignore b/.gitignore index 0c5487f5f5..f584e2c656 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ package.json deploy/docker/environment_tiny/common_test frontend/node_modules frontend/.pnp +frontend/i18n-translations-hash.json *.pnp.js # testing diff --git a/frontend/.eslintignore b/frontend/.eslintignore index 545037e39a..402f7ae028 100644 --- a/frontend/.eslintignore +++ b/frontend/.eslintignore @@ -1,3 +1,4 @@ node_modules build *.typegen.ts +i18-generate-hash.js \ No newline at end of file diff --git a/frontend/i18-generate-hash.js b/frontend/i18-generate-hash.js new file mode 100644 index 0000000000..97476e40af --- /dev/null +++ b/frontend/i18-generate-hash.js @@ -0,0 +1,24 @@ +/* eslint-disable */ +// @ts-ignore +// @ts-nocheck + +const crypto = require('crypto'); +const fs = require('fs'); +const glob = require('glob'); + +function generateChecksum(str, algorithm, encoding) { + return crypto + .createHash(algorithm || 'md5') + .update(str, 'utf8') + .digest(encoding || 'hex'); +} + +const result = {}; + +glob.sync(`public/locales/**/*.json`).forEach(path => { + const [_, lang] = path.split('public/locales'); + const content = fs.readFileSync(path, { encoding: 'utf-8' }); + result[lang.replace('.json', '')] = generateChecksum(content); +}); + +fs.writeFileSync('./i18n-translations-hash.json', JSON.stringify(result)); diff --git a/frontend/package.json b/frontend/package.json index 1fd5563c0b..9dae2b906d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,19 +4,20 @@ "description": "", "main": "webpack.config.js", "scripts": { - "dev": "cross-env NODE_ENV=development webpack serve --progress", - "build": "webpack --config=webpack.config.prod.js --progress", + "i18n:generate-hash": "node ./i18-generate-hash.js", + "dev": "npm run i18n:generate-hash && cross-env NODE_ENV=development webpack serve --progress", + "build": "npm run i18n:generate-hash && webpack --config=webpack.config.prod.js --progress", "prettify": "prettier --write .", - "lint": "eslint ./src", - "lint:fix": "eslint ./src --fix", + "lint": "npm run i18n:generate-hash && eslint ./src", + "lint:fix": "npm run i18n:generate-hash && eslint ./src --fix", "jest": "jest", "jest:coverage": "jest --coverage", "jest:watch": "jest --watch", "postinstall": "is-ci || yarn husky:configure", - "playwright": "NODE_ENV=testing playwright test --config=./playwright.config.ts", + "playwright": "npm run i18n:generate-hash && NODE_ENV=testing playwright test --config=./playwright.config.ts", "playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium", - "playwright:codegen:local":"playwright codegen http://localhost:3301", - "playwright:codegen:local:auth":"yarn playwright:codegen:local --load-storage=tests/auth.json", + "playwright:codegen:local": "playwright codegen http://localhost:3301", + "playwright:codegen:local:auth": "yarn playwright:codegen:local --load-storage=tests/auth.json", "husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*", "commitlint": "commitlint --edit $1" }, @@ -184,4 +185,4 @@ "@types/react": "17.0.0", "@types/react-dom": "17.0.0" } -} +} \ No newline at end of file diff --git a/frontend/src/ReactI18/index.tsx b/frontend/src/ReactI18/index.tsx index 3b37751caf..a2d89e3c4d 100644 --- a/frontend/src/ReactI18/index.tsx +++ b/frontend/src/ReactI18/index.tsx @@ -3,6 +3,8 @@ import LanguageDetector from 'i18next-browser-languagedetector'; import Backend from 'i18next-http-backend'; import { initReactI18next } from 'react-i18next'; +import cacheBursting from '../../i18n-translations-hash.json'; + i18n // load translation using http -> see /public/locales .use(Backend) @@ -17,7 +19,14 @@ i18n interpolation: { escapeValue: false, // not needed for react as it escapes by default }, - + backend: { + loadPath: (language, namespace) => { + const ns = namespace[0]; + const pathkey = `/${language}/${ns}`; + const hash = cacheBursting[pathkey as keyof typeof cacheBursting] || ''; + return `/locales/${language}/${namespace}.json?h=${hash}`; + }, + }, react: { useSuspense: false, },