Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🏗 build and copy story localization strings to dist on
amp build
an…
…d `amp dist` (#37623) * add compile localization code * build and copy story localization strings to dist on `amp build` and `amp dist` We need to start deploying these json files on the Google AMP cache as we will soon lazy load amp-story strings to reduce the size of the story JavaScript binaries. * fix lint * make sure to ensure fallback codes * Update build-system/tasks/build-story-localization.js Co-authored-by: Daniel Rozenberg <me@danielrozenberg.com> * Update build-system/tasks/build-story-localization.js Co-authored-by: Daniel Rozenberg <me@danielrozenberg.com> * fix refactor bug * add watch functionality * re-use the code found in the json importer babel transformer * remove comment * rename function * rename unsed param to _ to appease typecheck Co-authored-by: Daniel Rozenberg <me@danielrozenberg.com>
- Loading branch information
1 parent
572ca92
commit 0f8357b
Showing
5 changed files
with
141 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const {readFileSync} = require('fs'); | ||
/** | ||
* JSON reviver that converts {"string": "foo", ...} to just "foo". | ||
* This minifies the format of locale files. | ||
* @param {string} _ | ||
* @param {*} value | ||
* @return {*} | ||
*/ | ||
function minifyLocalesJsonReviver(_, value) { | ||
// Always default to original `value` since this reviver is called for any | ||
// property pair, including the higher-level containing object. | ||
return value?.string || value; | ||
} | ||
|
||
/** | ||
* @param {string} filename | ||
* @return {*} | ||
*/ | ||
function readJson(filename) { | ||
// Treat files under /_locales/ specially in order to minify their format. | ||
const reviver = filename.includes('/_locales/') | ||
? minifyLocalesJsonReviver | ||
: undefined; | ||
return JSON.parse(readFileSync(filename, 'utf8'), reviver); | ||
} | ||
|
||
module.exports = {readJson, minifyLocalesJsonReviver}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
const fs = require('fs-extra'); | ||
const fastGlob = require('fast-glob'); | ||
const pathMod = require('path'); | ||
const debounce = require('../common/debounce'); | ||
const {endBuildStep, watchDebounceDelay} = require('./helpers'); | ||
const {watch} = require('chokidar'); | ||
const {readJson} = require('../json-locales'); | ||
|
||
const dest = 'dist/v0'; | ||
|
||
const LOCALES_DIR = 'extensions/amp-story/1.0/_locales/*.json'; | ||
|
||
const FALLBACK_LANGUAGE_CODE = 'en'; | ||
|
||
const LANGUAGE_CODE_CHUNK_REGEX = /\w+/gi; | ||
|
||
/** | ||
* Finds fallback language codes for the current language code. | ||
* @param {string} languageCode the language code to get fallbacks for | ||
* @return {string[]} | ||
*/ | ||
function getLanguageCodeFallbacks(languageCode) { | ||
if (!languageCode) { | ||
return [FALLBACK_LANGUAGE_CODE]; | ||
} | ||
const matches = languageCode.match(LANGUAGE_CODE_CHUNK_REGEX) || []; | ||
return matches.reduce( | ||
(fallbackLanguageCodeList, _, index) => { | ||
const fallbackLanguageCode = matches | ||
.slice(0, index + 1) | ||
.join('-') | ||
.toLowerCase(); | ||
fallbackLanguageCodeList.push(fallbackLanguageCode); | ||
return fallbackLanguageCodeList; | ||
}, | ||
[FALLBACK_LANGUAGE_CODE] | ||
); | ||
} | ||
|
||
/** | ||
* Reads the language files found in amp-story and stores it in a | ||
* Object. | ||
* @return {Promise<Object>} | ||
*/ | ||
async function getLanguageStrings() { | ||
const langs = Object.create(null); | ||
const jsonFiles = await fastGlob(LOCALES_DIR); | ||
for (const jsonFile of jsonFiles) { | ||
const langKey = pathMod.basename(jsonFile, '.json'); | ||
langs[langKey] = readJson(jsonFile); | ||
} | ||
return langs; | ||
} | ||
|
||
/** | ||
* Retrieves the fallback language codes for each current locale | ||
* and merges any strings from the fallback language. | ||
* @param {Object} languages | ||
*/ | ||
function mergeFallbacks(languages) { | ||
for (const langKey in languages) { | ||
languages[langKey] = getLanguageCodeFallbacks(langKey) | ||
.map((x) => languages[x]) | ||
.reduce((prev, cur) => Object.assign(prev, cur), Object.create(null)); | ||
} | ||
} | ||
|
||
/** | ||
* Write the localization files to dist/v0/ | ||
* @return {Promise<void>} | ||
*/ | ||
async function writeStoryLocalizationFiles() { | ||
const startTime = Date.now(); | ||
await fs.ensureDir(dest); | ||
const languages = await getLanguageStrings(); | ||
mergeFallbacks(languages); | ||
// Write out each individual lang file. | ||
for (const langKey in languages) { | ||
await fs.writeJson(`${dest}/amp-story.${langKey}.json`, languages[langKey]); | ||
} | ||
// Write out all the languages into one file. | ||
await fs.writeJson(`${dest}/amp-story.all-lang.json`, languages); | ||
endBuildStep('Generated Story JSON Localization files into', dest, startTime); | ||
} | ||
|
||
/** | ||
* Flattens the structure of the json locale strings and writes them out to the | ||
* dist directory. | ||
* @param {Object=} options | ||
* @return {Promise<void>} | ||
*/ | ||
async function buildStoryLocalization(options = {}) { | ||
if (options.watch) { | ||
watch(LOCALES_DIR).on( | ||
'change', | ||
debounce(writeStoryLocalizationFiles, watchDebounceDelay) | ||
); | ||
} | ||
await writeStoryLocalizationFiles(); | ||
} | ||
|
||
module.exports = {buildStoryLocalization}; | ||
|
||
buildStoryLocalization.description = | ||
'Flattens the structure of the json locale strings and writes them out to the dist directory'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters