Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The same warning message occurs many times #79

Closed
fairking opened this issue Jul 19, 2020 · 8 comments
Closed

The same warning message occurs many times #79

fairking opened this issue Jul 19, 2020 · 8 comments

Comments

@fairking
Copy link

fairking commented Jul 19, 2020

Version: 0.5.0

The same error with the same code line occurs 18 times:
image

Related only to no-missing-keys rule.

if I fix Core.Strings.Login2 to existing Core.Strings.Login the all 18 messages are gone.

config:

module.exports = {
	root: true,
	env: {
		node: true,
	},
	extends: ["eslint:recommended", "plugin:vue/recommended", "prettier", "prettier/vue", "@vue/typescript", "plugin:@intlify/vue-i18n/recommended"],
	rules: {
		"no-console": "off",
		"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
		"no-unused-vars": "off",
		"vue/no-v-html": "off",
		//"@typescript-eslint/no-unused-vars-experimental": "warn",
		'@intlify/vue-i18n/no-dynamic-keys': 'error',
		'@intlify/vue-i18n/no-unused-keys': ['error', {
			extensions: ['.ts', '.js', '.vue']
		}]
	},
	parserOptions: {
		parser: "@typescript-eslint/parser"
	},
	plugins: ["vue"],
	overrides: [
		{
			files: ["**/__tests__/*.{j,t}s?(x)"],
			env: {
				jest: true,
			}
		}
	],
	settings: {
		'vue-i18n': {
			localeDir: 'src/i18n/*.json' // json localization resources
		}
	}
};

my src/i18n/ folder:
image

the loader i18n.ts:

import Vue from 'vue'
import VueI18n, { LocaleMessages } from 'vue-i18n'

Vue.use(VueI18n)

function loadLocaleMessages(): LocaleMessages {
	const locales = require.context('./i18n', true, /[A-Za-z0-9-_,\s]+\.json$/i);
	const messages: LocaleMessages = {};
	locales.keys().forEach(key => {
		// Files '/i18n/{module}.{name}.{lang}.json'
		const matched = key.match(/([A-Za-z0-9-_]+)\.([A-Za-z0-9-_]+)\.([A-Za-z0-9-_]+)\./i) || key.match(/([A-Za-z0-9-_]+)\.([A-Za-z0-9-_]+)\./i);
		if (matched && matched.length >= 3) {
			const module = matched[1];
			const name = matched[2];
			const locale = matched.length == 4 ? matched[3] : 'en';
			if (!messages[locale])
				messages[locale] = {};
			if (!messages[locale][module])
				messages[locale][module] = {};
			if (!messages[locale][module][name])
				messages[locale][module][name] = {};
			messages[locale][module][name] = locales(key)[locale][module][name];
		}
	});
	return messages;
}

export default new VueI18n({
	locale: document["CONFIG_I18N"] || process.env.VUE_APP_I18N_LOCALE || 'en',
	fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
	messages: loadLocaleMessages()
})

.json:

{
    "en":{
        "Core":{
            "Enums":{
                "MyEnum":"Some enum title",
                "...":"...",
                "...":"...",
                "...":"..."
            }
        }
    }
}

Usage Login.vue:

<span class="title">{{$t('Core.Strings.Login')}}</span>
@fairking
Copy link
Author

fairking commented Jul 19, 2020

if I fix Core.Strings.Login2 to existing Core.Strings.Login the all 18 messages are gone.

It is actually not true. The messages are still there after changing to Core.Strings.Login.

@fairking
Copy link
Author

fairking commented Jul 19, 2020

Upgraded to 0.6.0

If I have an incorrect key I got the following message:

\src\views\pages\Login.vue
   9:30  warning  'Core.Strings' does not exist in 'pl'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'en'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings.Login2' does not exist in 'en'                             @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'pl'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'en'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings.Login2' does not exist in 'pl'                             @intlify/vue-i18n/no-missing-keys

Please note all those messages are related to the same line

<span class="title">{{$t('Core.Strings.Login2')}}</span>

If I fix the resource path with the correct one 'Core.Strings.Login' the output is follows:

\src\views\pages\Login.vue
   9:30  warning  'Core.Strings' does not exist in 'en'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'en'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'pl'                                    @intlify/vue-i18n/no-missing-keys
   9:30  warning  'Core.Strings' does not exist in 'pl'                                    @intlify/vue-i18n/no-missing-keys

My file 'Core.Strings.json' looks like that:

{
    "en":{
        "Core":{
            "Strings":{
                "Login":"Some text",
                "...":"...",
                "...":"...",
                "...":"..."
            }
        }
    }
}

The settings:

settings: {
		'vue-i18n': {
			localeDir: {
				pattern: 'src/i18n/*.json',
				localeKey: 'key'
			}
		}
	}

All files in the folder:
image

@fairking
Copy link
Author

fairking commented Jul 19, 2020

I am not sure about the i18n syntax but I think it would be nice to have a json in the following format (and it could be optional):
Core.Strings.json

{
  "locale": "en",
  "prefix": "Core.Strings.",
  "Resources": [
    "Login": "Some text",
    "...": "...",
    "...": "..."
  ]
}

It is actually the same like:

{
  "locale": "en",
  "Resources": [
    "Core.Strings.Login": "Some text",
    "Core.Strings....": "...",
    "Core.Strings....": "..."
  ]
}

Why do I have many files for the same language,

  1. Those dictionaries maintained from different modules
  2. Even if I'm still able to merge them together into 1 file I prefer have them separated to reduce the amount of git conflicts.

@ota-meshi
Copy link
Member

ota-meshi commented Jul 20, 2020

Thank you for this issue!

Currently this plugin's locale message resources analysis is based on using the defaults of vue-cli-plugin-i18n, and the format give to the VueI18n constructor.

The reference source code is as follows:
https://github.com/kazupon/vue-cli-plugin-i18n/blob/67c9f003fb162f1893b78a32b4ec7a68dfb56a0a/generator/templates/js/src/i18n.js#L13
https://github.com/kazupon/vue-i18n/blob/1fd4833fe2db1100fd3fa8e77f029f8fcd27b7a9/decls/i18n.js#L8

If we accept various formats, it will be impossible to analyze with the @intlify/vue-i18n/no-unused-keys rule, so I think it is difficult to solve with the new option.
I think your merge strategy makes sense, but we probably can't add new options to the rules for this plugin.

But even now, you might be able to solve your problem by writing a .js to resolve the locale message resources.
Could you try the following?

  1. You create a js file that returns the result of merging resources.

e.g.

let result = {};
result = merge(result, require('../path/to/resource01.json'));
result = merge(result, require('../path/to/resource02.json'));
result = merge(result, require('../path/to/resource03.json'));
// ... 
module.exports = result;
  1. You change settings to refer to the created js file.
settings: {
  'vue-i18n': {
    localeDir: {
      pattern: 'path/to/merging-resources.js',
      localeKey: 'key' // or 'file'
    }
  }
}

Notes: rules that validate JSON files, such as @intlify/vue-i18n/no-unused-keys, will not work.

@ota-meshi
Copy link
Member

If PR #35 is merged and released, I think it's smarter to use the settings added by that PR.

@fairking
Copy link
Author

fairking commented Jul 21, 2020

Ok, looks like I solved the issue:
image

_merge.js:

let result = {};
const path = require('path')
const fs = require('fs')

const getAllFiles = dir =>
	fs.readdirSync(dir).reduce((files, file) => {
		const name = path.join(dir, file);
		const isDirectory = fs.statSync(name).isDirectory();
		return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
	}, []);

getAllFiles('./src/i18n').forEach(jFile => {
	const matched = jFile.match(/[A-Za-z0-9-_.]+\.json$/i);
	if (matched) {
		result = Object.assign(result, require('./../../' + jFile));
	}
});

module.exports = result;

.eslintrc.js

settings: {
		'vue-i18n': {
			localeDir: {
				pattern: './src/i18n/_merge.js',
				localeKey: 'key'
			}
		}
	}

The implementation of eslint-plugin-vue-i18n was very complicated. 3 days spent. All this code scares me and lack of documentation (no docs how to load json).
Other developers working with my project will be struggling with the implementation or improvements.
Thinking about implementing something more simple like typescript static resources.

Feel free to close the ticket. Thanks guys anyway.

@ota-meshi
Copy link
Member

If #35 was merged and released, you may need to change the settings, but now that the your problem seems to be resolved, so I close this issue.
If you have any new problems, please open a new issue.

@fairking
Copy link
Author

Seems all issues are gone after upgrading to 0.9.0. Thank you guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants