Last active
December 2, 2019 09:53
-
-
Save timofei-iatsenko/e122abbafaaf2191b84cbc8a7ca8a9a8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
const webpack = require('webpack'); | |
const os = require('os'); | |
const rimraf = require('rimraf'); | |
const helpers = require('../helpers'); | |
const gutil = require('gulp-util'); | |
const argv = require('process').argv; | |
const fs = require('fs'); | |
const path = require('path'); | |
const {statsToString, statsErrorsToString, statsWarningsToString} = require('../stats'); | |
const {getEmittedFiles} = require('@angular-devkit/build-webpack/src/utils'); | |
const {createTranslationLoader} = require('@angular-devkit/build-angular/src/utils/load-translations'); | |
const {i18nInlineEmittedFiles} = require('@angular-devkit/build-angular/src/utils/i18n-inlining'); | |
// Run this function to start build. It might be a gulp task or just standalone script to execute. | |
function bundle(config) { | |
return new Promise((resolve) => { | |
// If inlining, store the output in a temporary location to facilitate post-processing | |
const tempPath = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'angular-cli-i18n-')); | |
const origingalOutputPath = config.output.path; | |
config.output.path = tempPath; | |
// Remove temporary directory used for i18n processing | |
process.on('exit', () => { | |
try { | |
rimraf.sync(tempPath); | |
} catch (e) {} | |
}); | |
// run Webpack with passed config | |
webpack(config, async (err, stats) => { | |
if (err) { | |
throw err; // hard error | |
} | |
// you may skip these lines until createI18nInlinedBundles function, | |
// they are not important and need just to run webpack without webpack-cli | |
const colors = gutil.colors.supportsColor; | |
const json = stats.toJson(config.stats); | |
console.info(statsToString(json, colors)); | |
if (stats.hasWarnings()) { | |
console.warn(statsWarningsToString(json, colors)); | |
} | |
if (stats.hasErrors()) { | |
console.error(statsErrorsToString(json, colors)); | |
} | |
// Create inlined bundles | |
await createI18nInlinedBundles(stats, tempPath, origingalOutputPath); | |
resolve(); | |
}); | |
}); | |
} | |
async function createI18nInlinedBundles(stats, tempPath, outputPath) { | |
// Create appropriate structure of data using provided by angular-devkit functions | |
const emittedFiles = getEmittedFiles(stats.compilation); | |
const context = { | |
logger: console, | |
}; | |
// Create a configuration | |
const i18n = { | |
inlineLocales: new Set(['ru', 'de']), | |
sourceLocale: 'en-US', | |
locales: { | |
ru: { | |
file: './src/translates/messages.ru.xlf', | |
}, | |
de: { | |
file: './src/translates/messages.de.xlf', | |
}, | |
}, | |
shouldInline: true, | |
flatOutput: true, | |
}; | |
const loader = await createTranslationLoader(); | |
for (const [locale, desc] of Object.entries(i18n.locales)) { | |
if (i18n.inlineLocales.has(locale) && desc.file) { | |
// helpers.path.root() returns absolute path to project | |
const result = loader(path.join(helpers.path.root(), desc.file)); | |
for (const diagnostics of result.diagnostics.messages) { | |
if (diagnostics.type === 'error') { | |
throw new Error( | |
`Error parsing translation file '${desc.file}': ${diagnostics.message}`, | |
); | |
} else { | |
context.logger.warn(`WARNING [${desc.file}]: ${diagnostics.message}`); | |
} | |
} | |
desc.format = result.format; | |
desc.translation = result.translation; | |
desc.integrity = result.integrity; | |
desc.dataPath = path.join(findLocaleDataBasePath(helpers.path.root()), locale + '.js'); | |
} | |
} | |
// During this step following function spawn workers | |
// for each language and each file and replace all plachelders to translations | |
// It takes bundles from `tempPath` and copying them to the `outputPath`. | |
const success = await i18nInlineEmittedFiles( | |
context, | |
emittedFiles, | |
i18n, | |
outputPath, | |
[outputPath], | |
[], | |
tempPath, // temp path generated for i18n | |
true, | |
'warning', | |
); | |
// Probable here you might want to throw non-zero result if error happened to stop all your pipeline | |
console.log(success); | |
} | |
// function copied and simplified from @angular-devkit | |
function findLocaleDataBasePath(projectRoot) { | |
try { | |
const commonPath = path.dirname( | |
require.resolve('@angular/common/package.json', {paths: [projectRoot]}), | |
); | |
const localesPath = path.join(commonPath, 'locales/global'); | |
if (!fs.existsSync(localesPath)) { | |
return null; | |
} | |
return localesPath; | |
} catch (e) { | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment