1 | /**
|
2 | * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
3 | * For licensing, see LICENSE.md.
|
4 | */
|
5 |
|
6 | ;
|
7 |
|
8 | const chalk = require( 'chalk' );
|
9 | const serveTranslations = require( './servetranslations' );
|
10 | const MultipleLanguageTranslationService = require( '@ckeditor/ckeditor5-dev-utils/lib/translations/multiplelanguagetranslationservice' );
|
11 |
|
12 | /**
|
13 | * CKEditorWebpackPlugin, for now, consists only of the translation mechanism (@ckeditor/ckeditor5#624, @ckeditor/ckeditor5#387,
|
14 | * @ckeditor/ckeditor5#6526).
|
15 | *
|
16 | * The main language specified in `language` option will be statically added to the bundle. Translations for all languages from
|
17 | * the `additionalLanguages` option (if set) will be saved separately in the directory specified by the `outputDirectory` option
|
18 | * (which defaults to `lang`).
|
19 | *
|
20 | * If the `allowMultipleJSOutputs` is unset (or set to `false`) and when multiple outputs are defined, then translations for all languages
|
21 | * (from both `language` and `additionalLanguages` options) will be saved separately.
|
22 | * In that situation user will be warned that he needs to load at least one translation file manually to get editor working.
|
23 | *
|
24 | * If the `allowMultipleJSOutputs` is set to `true` and when multiple JS outputs are defined, then translations for the main language
|
25 | * will be added to all JS outputs and other translations will be saved separately.
|
26 | *
|
27 | * Translation files will be emitted in the `outputDirectory` or `'lang'` directory if `outputDirectory` is not set.
|
28 | *
|
29 | * This plugin tries to clean the output translation directory before each build to make sure, that all translations are correct.
|
30 | * See https://github.com/ckeditor/ckeditor5/issues/700 for more information.
|
31 | */
|
32 | module.exports = class CKEditorWebpackPlugin {
|
33 | /**
|
34 | * @param {CKEditorWebpackPluginOptions} options Plugin options.
|
35 | */
|
36 | constructor( options ) {
|
37 | if ( !options ) {
|
38 | throw new Error( 'The `CKEditorWebpackPlugin` plugin requires an object.' );
|
39 | }
|
40 |
|
41 | this.options = {
|
42 | language: options.language,
|
43 | additionalLanguages: options.additionalLanguages,
|
44 | outputDirectory: options.outputDirectory || 'translations',
|
45 | strict: !!options.strict,
|
46 | verbose: !!options.verbose,
|
47 | addMainLanguageTranslationsToAllAssets: !!options.addMainLanguageTranslationsToAllAssets,
|
48 | buildAllTranslationsToSeparateFiles: !!options.buildAllTranslationsToSeparateFiles,
|
49 | sourceFilesPattern: options.sourceFilesPattern || /[/\\]ckeditor5-[^/\\]+[/\\]src[/\\].+\.js$/,
|
50 | packageNamesPattern: options.packageNamesPattern || /[/\\]ckeditor5-[^/\\]+[/\\]/,
|
51 | corePackagePattern: options.corePackagePattern || /[/\\]ckeditor5-core/,
|
52 | corePackageSampleResourcePath: options.corePackageSampleResourcePath || '@ckeditor/ckeditor5-core/src/editor/editor.js',
|
53 | corePackageContextsResourcePath: options.corePackageContextsResourcePath || '@ckeditor/ckeditor5-core/lang/contexts.json',
|
54 | translationsOutputFile: options.translationsOutputFile,
|
55 | includeCorePackageTranslations: !!options.includeCorePackageTranslations,
|
56 | skipPluralFormFunction: !!options.skipPluralFormFunction
|
57 | };
|
58 | }
|
59 |
|
60 | apply( compiler ) {
|
61 | if ( !this.options.language ) {
|
62 | console.warn( chalk.yellow(
|
63 | 'The `language` option is required by the `CKEditorWebpackPlugin` plugin.' +
|
64 | 'If you do not want to localize the CKEditor 5 code do not add this plugin to your webpack configuration.'
|
65 | ) );
|
66 |
|
67 | return;
|
68 | }
|
69 |
|
70 | const {
|
71 | addMainLanguageTranslationsToAllAssets,
|
72 | buildAllTranslationsToSeparateFiles,
|
73 | language: mainLanguage
|
74 | } = this.options;
|
75 |
|
76 | let compileAllLanguages = false;
|
77 | let additionalLanguages = this.options.additionalLanguages || [];
|
78 |
|
79 | if ( typeof additionalLanguages == 'string' ) {
|
80 | if ( additionalLanguages !== 'all' ) {
|
81 | throw new Error( 'Error: The `additionalLanguages` option should be an array of language codes or `all`.' );
|
82 | }
|
83 |
|
84 | compileAllLanguages = true;
|
85 | additionalLanguages = []; // They will be searched in runtime.
|
86 | }
|
87 |
|
88 | // Currently, there is only one strategy to build translation files.
|
89 | // Though, bear in mind that there might be a need for a different build strategy in the future,
|
90 | // hence the translation service is separated from the webpack-specific environment.
|
91 | // See the TranslationService interface in the `servetranslation.js` file.
|
92 | const translationService = new MultipleLanguageTranslationService( {
|
93 | mainLanguage,
|
94 | compileAllLanguages,
|
95 | additionalLanguages,
|
96 | addMainLanguageTranslationsToAllAssets,
|
97 | buildAllTranslationsToSeparateFiles,
|
98 | translationsOutputFile: this.options.translationsOutputFile,
|
99 | skipPluralFormFunction: this.options.skipPluralFormFunction
|
100 | } );
|
101 |
|
102 | serveTranslations( compiler, this.options, translationService );
|
103 | }
|
104 | };
|
105 |
|
106 | /**
|
107 | * @typedef {Object} CKEditorWebpackPluginOptions CKEditorWebpackPluginOptions options.
|
108 | *
|
109 | * @property {String} language The main language for internationalization - translations for that language
|
110 | * will be added to the bundle(s).
|
111 | * @property {Array.<String>|'all'} [additionalLanguages] Additional languages. Build is optimized when this option is not set.
|
112 | * When `additionalLanguages` is set to 'all' then script will be looking for all languages and according translations during
|
113 | * the compilation.
|
114 | * @property {String} [outputDirectory='translations'] The output directory for the emitted translation files,
|
115 | * should be relative to the webpack context.
|
116 | * @property {Boolean} [strict] An option that make the plugin throw when the error is found during the compilation.
|
117 | * @property {Boolean} [verbose] An option that make this plugin log all warnings into the console.
|
118 | * @property {Boolean} [addMainLanguageTranslationsToAllAssets] An option that allows outputting translations to more than one
|
119 | * JS asset.
|
120 | * @property {String} [corePackageSampleResourcePath] A path (ES6 import) to the file that determines whether the `ckeditor5-core` package
|
121 | * exists. The package contains common translations used by many packages. To avoid duplications, they are shared by the core package.
|
122 | * @property {String} [corePackageContextsResourcePath] A path (ES6 import) to the file where all contexts are specified
|
123 | * for the `ckeditor5-core` package.
|
124 | * @property {Boolean} [buildAllTranslationsToSeparateFiles] An option that makes all translations output to separate files.
|
125 | * @property {String} [sourceFilesPattern] An option that allows override the default pattern for CKEditor 5 source files.
|
126 | * @property {String} [packageNamesPattern] An option that allows override the default pattern for CKEditor 5 package names.
|
127 | * @property {String} [corePackagePattern] An option that allows override the default CKEditor 5 core package pattern.
|
128 | * @property {String|Function|RegExp} [translationsOutputFile] An option allowing outputting all translation file to the given file.
|
129 | * If a file specified by a path (string) does not exist, then it will be created. Otherwise, translations will be outputted to the file.
|
130 | * @property {Boolean} [includeCorePackageTranslations=false] A flag that determines whether all translations found in the core package
|
131 | * should be added to the output bundle file. If set to true, translations from the core package will be saved even if are not
|
132 | * used in the source code (*.js files).
|
133 | * @property {Boolean} [skipPluralFormFunction=false] Whether the `getPluralForm()` function should be added in the output bundle file.
|
134 | */
|