preface

We already know how to configure internationalization in air-UI by building the VUE component air-UI (12) — Internationalization Mechanism in the previous section. However, several problems remain unsolved:

  1. We now have a default introductionzh-CN.jsThis file, this will cause us to pack out laterair-ui.common.jsAs the volume increases, how do we pull it out?
  2. If components are packaged separately, how can they be integrated into multiple languages when introduced?

Extract the language pack file reference separately

We know that when we hit air-ui.mon.js, we put zh-cn.js in the language pack because if there’s a reference in the entry file, it’s going to be packed by default. The packing chain looks like this:

components/index.js -> components/select/index.js -> components/select/select.vue -> mixins/locale -> local/index.js -> lang/zh-CN.js
Copy the code

So if we want to leave lang/ zh-cn. js untyped, we will ignore this file and refer to it as an external resource package when we pack the webpack. The externals field is used for the webpack packing. – Some resources are ignored (I will cover the whole build in a later section, just know how to do this), so we need to ignore this resource when we call the vUE file.

const nodeExternals = require('webpack-node-externals');
Copy the code
  // Do not pack some files, otherwise the size of common will become very large, especially the language files. The consequence is that if common does not include these files, the files will be typed separately and the path will not change, and if not packaged, the reference will become an absolute path reference and cannot be used again
  externals: [Object.assign({
    vue: 'vue'
  }, {
    '.. /lang/zh-CN': 'air-ui/lib/lang/zh-CN'
  }), nodeExternals()],
Copy the code

This will become, when packing, find this… The /lang/ zh-cn resource will not be packaged in webpack, but will be replaced with the corresponding absolute reference address air-ui/lib/lang/ zh-cn, so once we do this, our lang directory will be loaded with the dist component package. We need to copy it individually so that air-ui.mon.js can use this absolute path to find the language packets. We can see that air-ui.mon.js references to the language pack become absolute paths when the pack is finished:

When packaged this way, language packages are referred to as absolute paths to external resources. It wouldn’t have gone in.

Element – the practice of the UI

Element-ui also pulls out the language package, but it pulls SRC /locale/index.js, treats that file as an external resource, and imports it with absolute paths:

But this resource doesn’t just import language files, there are other resources, such as methods in Utils. Once that resource is not packaged but referred to as an external resource, then it refers to other dependent resources and must also be referred to in an absolute path. For example, locale is an external resource, and then it refers to methods in utils. If utils doesn’t also become an external resource, But if you push it into common.js as an internal resource, you’re going to lose locale references, so the situation where you use absolute path dependencies is that all of your dependencies become external resources, all of your dependencies become absolute path references. That’s what element-UI does. It makes all resources other than components external and references them in absolute paths.

Logically, of course, this is not an error. That’s ok. One of the things that can happen is that SOME of my components refer to resources in relative and absolute paths, which was actually confusing when I first looked at the source code. And what’s even weirder is that even in the same directory, you have to use an absolute path reference, so that packaging doesn’t go wrong.

So WHEN I was dealing with air-UI multilanguage packaging, I had to take this lesson and use relative paths all over the code, and then use absolute paths only for language files as external resources when packaging. And the rest of the references are still going into air-ui.mon.js. This way, I can ensure that I use all relative paths for reference when developing, and don’t need to worry about packaging. Another is the directory structure of the package is also better. In addition to the air-ui.mon.js file, there is only one lang directory that stores the language pack files:

What pitfalls do I encounter if I use absolute path writing

Although I ended up taking all the relative path references. But there is actually a process. In the early days of the experiment, we used to refer to the absolute path in the code by referring to the element-UI method:

The development environment then reported an error:

This dependency was not found:

* air-ui/src/lang/zh-CN in ./src/locale/index.js

To install it, you can run: npm install --save air-ui/src/lang/zh-CN
Copy the code

Webpack.base.conf.js adds a configuration to make the global path reference:

There’s no problem building this way. Of course, since @ is the SRC directory by default, it can also be written as

import defaultLang from '@/lang/zh-CN';
Copy the code

That’s ok. But I’m inclined to go that way.

This way the test environment is no problem. Externals (dist) : externals (lang) : externals (dist) : externals (lang) : externals (dist)

const nodeExternals = require('webpack-node-externals');

// Do not pack some files, otherwise the size of common will become very large, especially the language files. The consequence is that if common does not include these files, the files will be typed separately and the path will not change, and if not packaged, the reference will become an absolute path reference and cannot be used again
externals: [Object.assign({
  vue: 'vue'
}, {
  'air-ui/src/lang/zh-CN': 'air-ui/lib/lang/zh-CN'
}), nodeExternals()],
Copy the code

So we’re going to change this absolute path to the packed path, and we’re going to do yarn dist. And then we’re going to do a search on air-ui.mon.js. Found no Chinese, the language package was completely removed.

But we found that the lang folder is not exported to the lib directory, so we need to do something here. During the packaging process, we will also export the lang directory to the lib target directory:

//============= process the language file and move it to the lib directory start===========
gulp.task('copylang'.function() {
  return gulp.src('./src/lang/**')
    .pipe(gulp.dest('./lib/lang'));
});
//============= process the language file and move it to the lib directory end=============
Copy the code

Then add it to the dist task. This way the lang directory is packaged into the lib directory. That doesn’t seem to be a problem. When using VuePress, this problem occurs:

He can’t find the path, even if it’s at sign. Embarrassed, he can only use the relative path;

import defaultLang from '.. /lang/zh-CN';
Copy the code

Therefore, in order to be compatible with the vuepress document, we can only use relative path in the code, and then replace it with absolute path when building, so when packaging, change it to:

externals: [Object.assign({
  vue: 'vue'
}, {
  '.. /lang/zh-CN': 'air-ui/lib/lang/zh-CN'
}), nodeExternals()],
Copy the code

Since it is matched with a re, make sure there is no other non-verbal string in the code called.. /lang/ zh-cn, otherwise it will be replaced, so it is ok. This ensures that VuePress works and that language files are not packaged.

How to introduce multilingual mechanisms when components are packaged separately

We already know that when we write the Common package, we can pull out multiple languages and refer to them as external resources using absolute paths. But when our components are packaged and referenced separately, how can I use multiple languages and extract the multilingual files as well?

We can follow the syntax, the actual reference should look like this:

import Vue from 'vue';
import Select from 'air-ui/lib/select';
import Row from 'air-ui/lib/row';
import 'air-ui/lib/styles/select.css';
import 'air-ui/lib/styles/row.css';
import App from './App.vue';

Vue.use(Button);
Vue.use(Row);
Copy the code

In this case, the locale object would have to be used to set up multiple languages (otherwise use and i18n methods were used), but the locale object was loaded into the air-ui.mon.js file. If we had to load on demand, So this object has to be exported again, so you export the locale object in webpack.component.js, so you add this line to component.json:

"locale": "./src/locale/index.js".Copy the code

The exported component contains the locale object, which can be used to set multiple languages:

So there you go. Import this:

import Vue from 'vue'

import Select from 'air-ui/lib/select';
import Option from 'air-ui/lib/option';
import Row from 'air-ui/lib/row';
import locale from 'air-ui/lib/locale';
import 'air-ui/lib/styles/select.css'
import 'air-ui/lib/styles/row.css'
import 'air-ui/lib/styles/option.css'
import lang from 'air-ui/lib/lang/en'

locale.use(lang)
Vue.component(Row.name, Row)
Vue.component(Select.name, Select)
Vue.component(Option.name, Option)
Copy the code

This is loading on demand and importing the corresponding multilingual. But it doesn’t work because the local in select is relative to the path, and it wasn’t pulled out when building dist.

The locale object that causes the read is not referenced later, but the locale object in select.js:

If you want to build components separately, you need to change the reference to local to the absolute path, so in webpack.ponnent.js you need to add this line:

  // Do not pack some files, otherwise the size of common will become very large, especially the language files. The consequence is that if common does not include these files, the files will be typed separately and the path will not change, and if not packaged, the reference will become an absolute path reference and cannot be used again
  externals: [Object.assign({
    vue: 'vue'
  }, {
    '.. /lang/zh-CN': 'air-ui/lib/lang/zh-CN'.// Note that locale path substitutions are only required when packaging individual components, because loading components separately also requires multilingual support, not when packaging common, because they are integrated
    '.. /.. /.. /.. /src/locale': 'air-ui/lib/locale'.'.. /locale': 'air-ui/lib/locale',
  }), nodeExternals()],
Copy the code

So when you build your select this way, the locale that you’re referring to, it’s going to be the packaged locale. That way the objects will match.

Note here that we only need to pump the locale object when webpack.ponents.js is packing individual components. If we’re packing air-ui.mon.js, we don’t need to do that.

Several ways to internationalize

Finally, let’s summarize several ways to introduce internationalization:

A complete introduction

// Fully introduce AirUI
import Vue from 'vue'
import AirUI from 'air-ui'
import locale from 'air-ui/lib/lang/en'

Vue.use(AirUI, { locale })
Copy the code

Partial introduction (full loading)

import Vue from 'vue'
import { Row, Select, Option, locale } from 'air-ui'
import 'air-ui/lib/styles/index.css'
import lang from 'air-ui/lib/lang/en'

locale.use(lang)
Vue.component(Row.name, Row)
Vue.component(Select.name, Select)
Vue.component(Option.name, Option)
Copy the code

One more detail to note here is that locale is exported separately, so when exporting components/index.js, export the locale object as well:

import locale from '.. /.. /src/locale'

module.exports = {
  locale: locale,
  ...
}
Copy the code

So that it can be referenced in this way.

Load and import as needed

// Load and import AirUI on demand
import Vue from 'vue'
import Select from 'air-ui/lib/select';
import Option from 'air-ui/lib/option';
import Row from 'air-ui/lib/row';
import locale from 'air-ui/lib/locale';
import 'air-ui/lib/styles/select.css'
import 'air-ui/lib/styles/row.css'
import 'air-ui/lib/styles/option.css'
import lang from 'air-ui/lib/lang/en'

locale.use(lang)
Vue.component(Row.name, Row)
Vue.component(Select.name, Select)
Vue.component(Option.name, Option)
Copy the code

Replace the default Chinese language pack

If you use other languages, Chinese language by default package remains were introduced, can use webpack NormalModuleReplacementPlugin replace the default language pack:

{
  plugins: [
    new webpack.NormalModuleReplacementPlugin(/air-ui[\/\\]lib[\/\\]lang[\/\\]zh-CN/.'air-ui/lib/lang/en')]}Copy the code

conclusion

This section is mainly about packaging, multi-language file extraction and processing. This includes how to type common files and individual component packages, and how they differ from Element-UI. This section has covered some cases of packaged builds. In the next section, we’ll take a closer look at the air-UI package build, especially the Dist package.


Series of articles:

  • Air-ui (1) — Why do I need to build an Element UI component
  • Self-built VUE component AIR-UI (2) — Take a look at the Element UI project
  • Self-built VUE component AIR-UI (3) – CSS development specification
  • Air-ui (4) — Air-UI environment setup and directory structure
  • Air-ui (5) — Create the first vUE component, Button
  • Self-built VUE component AIR-UI (6) – Creates built-in service components
  • Build vUE component AIR-UI (7) – Create command component
  • Self-built VUE component AIR-UI (8) — Implementation part introduces components
  • Build your own VUE component air-UI (9) — document with Vuepress
  • Air-ui (10) — Vuepress Documentation (Advanced version)
  • Vue Component Air-UI (11) — Vuepress Documentation (Crawl version)
  • Self-built VUE component AIR-UI (12) — Internationalization mechanism
  • Self-built VUE Component AIR-UI (13) — Internationalization Mechanism (Advanced Version)
  • Self-built VUE component AIR-UI (14) — Packaged Build (Dev and Dist)
  • Self-built VUE component AIR-UI (15) — Theme customization
  • Self-built VUE component AIR-UI (16) – Packages to build pub tasks
  • Build your own VUE component AIR-UI (17) – Develop a pit crawl and summary