Skip to content

Commit d039af0

Browse files
author
Guillaume Chau
committed
refactor(ui): locales system improvements
1 parent 2927095 commit d039af0

File tree

16 files changed

+139
-483
lines changed

16 files changed

+139
-483
lines changed

packages/@vue/cli-plugin-eslint/locales/en.json

-13
This file was deleted.

packages/@vue/cli-plugin-eslint/locales/fr.json

-13
This file was deleted.

packages/@vue/cli-service/locales/en.json

-18
This file was deleted.

packages/@vue/cli-service/locales/fr.json

-18
This file was deleted.

packages/@vue/cli-ui-addon-webpack/src/components/TestView.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="test-view">
3-
<h1>I'm a custom view</h1>
3+
<h1>{{ $t('vue-webpack.test-view') }}</h1>
44
<p>A vue-cli plugin created me! I am a dynamically loaded component paired with a custom route.</p>
55
<div>
66
<VueButton @click="testPluginAction()">Test plugin action</VueButton>
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,5 @@
11
{
22
"vue-webpack": {
3-
"dashboard": {
4-
"open-app": "Open app",
5-
"webpack-status": {
6-
"Success": "Success",
7-
"Failed": "Failed",
8-
"Compiling": "Compiling",
9-
"Invalidated": "Invalidated",
10-
"Idle": "Idle"
11-
},
12-
"build-status": {
13-
"labels": {
14-
"status": "Status",
15-
"errors": "Errors",
16-
"warnings": "Warnings",
17-
"assets": "Assets",
18-
"modules": "Modules",
19-
"deps": "Dependencies"
20-
}
21-
},
22-
"speed-stats": {
23-
"title": "Speed stats"
24-
},
25-
"module-list": {
26-
"title": "Dependencies"
27-
},
28-
"asset-list": {
29-
"title": "Assets",
30-
"size-warning": "This asset is big, consider using Code splitting to create smaller assets."
31-
}
32-
},
33-
"analyzer": {
34-
"go-up": "Go up",
35-
"go-home": "Go to home",
36-
"chunk": "Chunk"
37-
},
38-
"sizes": {
39-
"stats": "Stats",
40-
"parsed": "Parsed",
41-
"gzip": "Gzip",
42-
"help": "<b>Stats:</b> size from webpack stats data.<br><b>Parsed:</b> size from extracted source (after minification plugins). More accurate.<br><b>Gzip:</b> size of gzipped extracted source."
43-
}
3+
"test-view": "I'm a custom view"
444
}
455
}

packages/@vue/cli-ui-addon-webpack/src/locales/fr.json

-45
This file was deleted.

packages/@vue/cli-ui/src/App.vue

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<template>
22
<div id="app" class="app">
3-
<div class="content">
3+
<div v-if="ready" class="content">
44
<router-view/>
55
</div>
6+
<VueLoadingIndicator v-else class="overlay big accent"/>
67

78
<StatusBar/>
89
<ClientAddonLoader/>
@@ -11,9 +12,17 @@
1112
</template>
1213

1314
<script>
15+
import i18n from './i18n'
16+
1417
export default {
1518
metaInfo: {
1619
titleTemplate: chunk => chunk ? `[Beta] ${chunk} - Vue CLI` : '[Beta] Vue CLI'
20+
},
21+
22+
computed: {
23+
ready () {
24+
return Object.keys(i18n.getLocaleMessage('en')).length
25+
}
1726
}
1827
}
1928
</script>

packages/@vue/cli-ui/src/components/TaskItem.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<ListItemInfo
2020
:name="task.name"
21-
:description="(task.status === 'idle' && task.description) || status"
21+
:description="(task.status === 'idle' && $t(task.description)) || status"
2222
:selected="selected"
2323
/>
2424
</div>

packages/@vue/cli-ui/src/graphql-api/connectors/locales.js

+30-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1+
const path = require('path')
2+
const fs = require('fs')
3+
const globby = require('globby')
4+
// Connectors
5+
const cwd = require('./cwd')
16
// Subs
27
const channels = require('../channels')
8+
// Context
9+
const getContext = require('../context')
10+
// Utils
11+
const { resolveModule } = require('@vue/cli/lib/util/module')
12+
const { resolveModuleRoot } = require('../utils/resolve-path')
313

4-
let locales = []
14+
let locales
515

616
function list (context) {
717
return locales
@@ -15,12 +25,29 @@ function add ({ lang, strings }, context) {
1525
})
1626
}
1727

18-
function clear (context) {
28+
function reset (context) {
1929
locales = []
30+
// Load builtin locales
31+
const modulePath = resolveModule('@vue/cli/bin/vue', cwd.get())
32+
const folder = resolveModuleRoot(modulePath, '@vue/cli')
33+
loadFolder(folder, context)
2034
}
2135

36+
function loadFolder (root, context) {
37+
const paths = globby.sync([path.join(root, './locales/*.json')])
38+
paths.forEach(file => {
39+
const basename = path.basename(file)
40+
const lang = basename.substr(0, basename.indexOf('.'))
41+
const strings = JSON.parse(fs.readFileSync(file, { encoding: 'utf8' }))
42+
add({ lang, strings }, context)
43+
})
44+
}
45+
46+
reset(getContext())
47+
2248
module.exports = {
2349
list,
2450
add,
25-
clear
51+
reset,
52+
loadFolder
2653
}

packages/@vue/cli-ui/src/graphql-api/connectors/plugins.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const {
1717
} = require('@vue/cli/lib/util/installDeps')
1818
const invoke = require('@vue/cli/lib/invoke')
1919
const notifier = require('node-notifier')
20-
const globby = require('globby')
2120
// Subs
2221
const channels = require('../channels')
2322
// Connectors
@@ -127,13 +126,7 @@ function runPluginApi (id, context, fileName = 'ui') {
127126
// Locales
128127
try {
129128
const folder = fs.existsSync(id) ? id : getPath(id)
130-
const paths = globby.sync([path.join(folder, './locales/*.json')])
131-
paths.forEach(file => {
132-
const basename = path.basename(file)
133-
const lang = basename.substr(0, basename.indexOf('.'))
134-
const strings = JSON.parse(fs.readFileSync(file, { encoding: 'utf8' }))
135-
locales.add({ lang, strings }, context)
136-
})
129+
locales.loadFolder(folder, context)
137130
} catch (e) {}
138131
}
139132

packages/@vue/cli-ui/src/graphql-api/connectors/projects.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ async function open (id, context) {
318318
currentProject = project
319319
cwd.set(project.path, context)
320320
// Reset locales
321-
locales.clear()
321+
locales.reset(context)
322322
// Load plugins
323323
plugins.list(project.path, context)
324324

packages/@vue/cli-ui/src/i18n.js

+30-12
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ import deepmerge from 'deepmerge'
44

55
Vue.use(VueI18n)
66

7-
function loadLocaleMessages () {
8-
const locales = require.context('./locales', true, /[a-z0-9]+\.json$/i)
9-
const messages = {}
10-
locales.keys().forEach(key => {
11-
const locale = key.match(/([a-z0-9]+)\./i)[1]
12-
messages[locale] = locales(key)
13-
})
14-
return messages
15-
}
16-
177
function detectLanguage () {
188
try {
199
const lang = (window.navigator.languages && window.navigator.languages[0]) ||
@@ -25,12 +15,40 @@ function detectLanguage () {
2515
}
2616
}
2717

18+
async function autoInstallLocale (lang) {
19+
try {
20+
let response = await fetch(`https://unpkg.com/vue-cli-locale-${lang}`)
21+
if (response.ok) {
22+
// Redirect
23+
const location = response.headers.get('location')
24+
if (location) {
25+
response = await fetch(`https://unpkg.com${location}`)
26+
}
27+
const data = await response.json()
28+
mergeLocale(lang, data)
29+
}
30+
} catch (e) {}
31+
}
32+
33+
async function autoDetect () {
34+
const lang = detectLanguage()
35+
if (lang !== 'en') {
36+
await autoInstallLocale(lang)
37+
i18n.locale = lang
38+
}
39+
}
40+
2841
const i18n = new VueI18n({
29-
locale: detectLanguage() || 'en',
42+
locale: 'en',
3043
fallbackLocale: 'en',
31-
messages: loadLocaleMessages()
44+
messages: {
45+
en: {}
46+
},
47+
silentTranslationWarn: process.env.NODE_ENV !== 'production'
3248
})
3349

50+
autoDetect()
51+
3452
export function mergeLocale (lang, messages) {
3553
const newData = deepmerge(i18n.getLocaleMessage(lang), messages)
3654
i18n.setLocaleMessage(lang, newData)

0 commit comments

Comments
 (0)