background

Recently, I needed to internationalize a project that had been developed for about two years and supported Both Chinese and English. I went around the community but found no wheels that could solve the pain points well, such as:

  • Maintaining resource files is too cumbersome
  • The code is too intrusive, I don’t want to change a two-year project, file by file

So I decided to write my own tool:

  • Resource files are automatically generated and updated
  • Code 0 invades, and you don’t have to think about internationalization when you write code

In general, as long as the tool is introduced, the post-maintenance cost is only one, and only the translation resource files are considered.

Train of thought

Essentially implementing a WebPack Loader that handles internationalization automatically at packaging time:

  • Through all the code, extract the Chinese string in the code, generate the resource file (resource file key, through the corresponding ChineseMD5Encrypted generation)
  • Hangs the resource file content globally$i18nOn the object
  • Go through all the code and replace the Chinese in the code with$i18n[key]

The code has been put on Github: Miao-I18n

How to use

Using create-react-app as an example, create a project:

create-react-app myapp
Copy the code

Since we need to add the WebPack Loader, we need to expose the configuration:

yarn eject
Copy the code

Install miao – i18n:

yarn add miao-i18n
Copy the code

Configuration webpack, open the myapp/config/webpackDevServer config. Js, because the loader is executed from bottom to top, all we need to put our loader configuration to the top, this is very important.

module: {
    strictExportPresence: true.rules: [
    // Disable require.ensure as it's not a standard language feature.
    { parser: { requireEnsure: false } },
+    {
+    test: /\.(js|mjs|jsx|ts|tsx)$/,
+    exclude: /node_module/,
+    loader: require.resolve("miao-i18n"), +},... }Copy the code

The configuration is complete and you can start your fun 😊

yarn start	
Copy the code

After the project is started, you can see that an i18N folder is automatically generated in the SRC directory:

├ ─ SRC | ├ ─ i18n | | ├ ─ i18n. Js | | ├ ─ useful | | | └ data. The json | | ├ ─ en | | | └ data. The jsonCopy the code

Zh and en correspond to Chinese and English resources respectively, not to mention this one.

I18n.js is used to import and switch resource files:

import zh  from "./zh/data.json"
import en  from "./en/data.json"

/** If you need to switch languages with buttons, you can expose this method to button click callbacks. * /
function i18n(lang) {
  let data;
  switch (lang) {
    case "zh":
      data = zh;
      break;
    case "en":
      data = en;
      break;

    default:
      data = zh;
      break;
  }
  window.$i18n = data;
};


i18n("en")// Switch to English
Copy the code

Finally, i18N.js was introduced into the project. Open SRC /index.js and introduce i18n.js at the front of the project

+ import "./i18n/i18n"
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker'.Copy the code

Configuration complete! 🍾 🍾 🍾

Try adding Chinese.

Open SRC/app.js and modify the code as follows

import React from 'react';
function App() {
  return (
    <div className="App"> <p> Apple </p> <p> banana </p> <p> grape </p> </div>); }export default App;
Copy the code

Save the file and view the browser:

If you open the console, you can see that the source code has been automatically compiled internationally:

SRC /i18n/en/data.json or SRC /i18n/en/data.json

{
    "e6803e21b9c61f9ab3d04088638cecd2": The word "apple"."b7c03bbf2b8bb334e1dfae5939d82d1b": "Banana"."05b1b3102be250f2a6fadf800f8ad8b6": "Grapes"
}
Copy the code

SRC /i18n/en/data.json has been translated

{- "e6803e21b9c61f9ab3d04088638cecd2" : "apple", - "b7c03bbf2b8bb334e1dfae5939d82d1b" : "Banana", - "05 b1b3102be250f2a6fadf800f8ad8b6" : "grape" + "e6803e21b9c61f9ab3d04088638cecd2" : "Apple", + "b7c03bbf2b8bb334e1dfae5939d82d1b": "banana", + "05b1b3102be250f2a6fadf800f8ad8b6": "grape" }Copy the code

Save the code and look in your browser

Page display for English, done! 🙂

The last

Since this tool is only used in my project at present, there must be a lot of things I haven’t considered. Welcome your suggestions and opinions

Thanks for reading! 🌹