Creating multiple language bundles from one source module

I’m wondering whether and how webpack can be used to create multiple outputs from a single module.

Scenario

Our packages have resource files and we are importing them directly:

import strings from './resources.json'

The files within the packages are in a default language (english) and will be overriden depending on the loaded language. We only want to load the language that is required, therefore we would want resources.json to be the same JSON object, but with the correct translated resources when we import the strings. All language resources should be built at build time.

Current implementation

Right now, we have a quite hacky solution, which results in parallel builds per language:

  • There are two entries, which point to the same entry point:
entries: {
  code: './index.js',
  en: './index.js',
}
  • A custom loader for resource files loads the correct resources for a file from an external resource. The language is set as a loader option.
  • A custom plugin removes the language resources from the chunk that is named ‘code’, they will now only exist in the ‘en’ chunk.
  • A CommonsChunkPlugin instance is ran on top of the two chunks. This leads to the code chunk containing all code except the language resources and the ‘en’ chunk only containing the language resources.

These steps are repeated with parallel builds for various languages, which means we end up with the following structure:

code.js (Bundle with all code, no language resources)
en.js (Language resources for English)
de.js (Language resources for German)
...

The language resources are then loaded dynamically through scriptjs during the app initialization.

Question

The current implementation works but it seems very hacky and wasteful, since supporting 8 languages triggers 8 parallel builds.

Is there a better way to solve this problem?

Author: Fantashit

1 thought on “Creating multiple language bundles from one source module

  1. Use i18n-webpack-plugin.

    Your webpack.config.js should looks like this:

    var path = require("path");
    var I18nPlugin = require("i18n-webpack-plugin");
    var languages = {
        "en": null,
        "de": require("./de.json")
    };
    module.exports = Object.keys(languages).map(function(language) {
        return {
            name: language,
            entry: "./index.js",
            output: {
                path: path.join(__dirname, "js"),
                filename: language + ".output.js"
            },
            plugins: [
                new I18nPlugin(
                    languages[language],
                    {
                        functionName:'TRS',
                    }
                )
            ]
        };
    });
    
    

    And in your js file, whenever you want to do a translation, put TRS in front. Something like this:
    console.log(TRS("Hello world!")).

    Also you need to put the translation into a file, e.g.de.json in this example.

    It will do the trick.

    ps: the above example is taken from the example folder in webpack repo.

Comments are closed.