Git Product home page Git Product logo

eslint-plugin-vue-i18n's Introduction

ESLint plugin for Vue I18n logo

@intlify/eslint-plugin-vue-i18n

Test Status

NPM

ESLint plugin for Vue I18n

Supporting Intlify Project

Intlify Project is an open source project that is included Vue I18n and i18n tooling and libraries with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:

📔 Documentation

See here

📜 Changelog

Details changes for each release are documented in the CHANGELOG.md.

❗ Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

💪 Contribution

Please make sure to read the Contributing Guide before making a pull request.

©️ License

MIT

eslint-plugin-vue-i18n's People

Contributors

advisciglio avatar azu avatar codiini avatar dargmuesli avatar dependabot-preview[bot] avatar dependabot[bot] avatar floedelmann avatar github-actions[bot] avatar ismailarilik avatar itmaga avatar jlebar avatar kazupon avatar lukashass avatar mfmfuyu avatar oikalyptus avatar ota-meshi avatar piktur avatar renovate-bot avatar renovate[bot] avatar roman3349 avatar stevelacey avatar trinketmage avatar vintagesucks avatar williamchong avatar willmendesneto avatar wolfgangwalther avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eslint-plugin-vue-i18n's Issues

ignoring raw text '-' doesn't work

I got a warning for warning raw text '-' is used vue-i18n/no-raw-text
my code is {{ props.from_hour && props.to_hour ? `${props.from_hour} - ${props.to_hour}` : '-' }}
my eslint rule is

'vue-i18n/no-raw-text': ['warn', {
      'ignorePattern': '^ - |[-#:()&]+$',
      'ignoreText': ['404']
}]

but still i have this issue.
@kazupon

Rule Proposal: no-duplicate-keys-in-locale

Please describe what the rule should do:

This rule reports duplicate keys within the same locale.

What category of rule is this? (place an "X" next to just one item)

[ ] Enforces code style (layout)
[X] Warns about a potential error (problem)
[ ] Suggests an alternate way of doing something (suggestion)
[ ] Other (please specify:)

Provide 2-3 code examples that this rule will warn about:

  • en.for-module1.json
{
  "dupe-key1": "foo", // <- dupe-key1 are duplicates.
  "dupe-key1": "bar", // <- dupe-key1 are duplicates.
  "dupe-key2": "baz", // <- dupe-key2 duplicates the same locale key in another file.
}
  • en.for-module2.json
{
  "dupe-key2": "qux", // <- dupe-key2 duplicates the same locale key in another file.
}

Additional context

I found in #79 that some users have multiple resources for the same locale.

I thought that if you split into multiple files, you will not be able to check for duplicate keys or missing keys, but I realized that this plugin mechanism can implement rules to check for duplicate keys and missing keys.

If we add this rule, we need to change the no-missing-keys rule to not report if you have at least one hit in the same locale.

I also considered whether a rule was needed to report keys that were existing in one locale and missing in another.
In my opinion, this rule is not needed as the reporting of the no-missing-keys rule meets this.

in-JSON reused keys are treated as unused

When you reuse keys in a JSON files and never use it in code, they're treated as never used. This is an example of my keys being reused, common keys are reused with the sintax @: in validationFields:

"common": {
        "name": "Nombre",
        "yes": "Si",
        "no": "No",
        "email": "Correo",
        "password": "Contraseña"
    },

    "validationFields": {
        "email": "@:common.email",
        "password": "@:common.password",
        "name": "@:common.name",
        "confirmPassword": "Confirmar contraseña"
    }

Seems like you need to use the keys specifically with vue-i18n functions, cause this also happens when you integrate with another library. For example, in my JSON, the object validationFields is used in a validation library, never use with vue-i18n functions and because of that is always treated as unused keys.

With this behaivour it's hard to know when you have unused keys.

Support Component based localization

Tell us about your environment

  • **ESLint version:**6.7.2
  • eslint-plugin-vue version: 6.2.2
  • eslint-plugin-vue-i18n version: 0.9.0
  • Node version: 10.16.3

The problem you want to solve.

I want to use Component based localization, which allows for specifying the messages for each country code within the component itself so it's easier to keep track of which component is using which translations. However; since there is no way to configure this to look for translation keys within the components, I can't use the @intlify/vue-i18n/no-missing-keys rule without it throwing warnings.

Your take on the correct solution to problem.

By default, it should look at the components to see if there are any translation keys specified in either messages or sharedMessages.

key-format-style allowing incorrect format in locale file

Tell us about your environment

"eslint": "^7.17.0",
"eslint-plugin-nuxt": "^2.0.0",
"@intlify/eslint-plugin-vue-i18n": "^0.9.0",
Node version: v10.15.3

Please show your full configuration:

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: ['@nuxtjs', 'prettier', 'prettier/vue', 'plugin:prettier/recommended', 'plugin:nuxt/recommended'],
  plugins: ['prettier', '@intlify/vue-i18n'],
  // add your custom rules here
  rules: {
    'nuxt/no-cjs-in-config': 'off',
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    // https://eslint.org/docs/rules/padding-line-between-statements
    'padding-line-between-statements': [
      'error',
      { blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
      { blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
      { blankLine: 'always', prev: ['case', 'default'], next: '*' },
      { blankLine: 'always', prev: 'directive', next: '*' },
      { blankLine: 'always', prev: 'function', next: '*' },
      { blankLine: 'always', prev: '*', next: 'function' },
      { blankLine: 'always', prev: 'if', next: '*' },
      { blankLine: 'always', prev: '*', next: 'if' },
      { blankLine: 'any', prev: 'directive', next: 'directive' }
    ],
    'lines-between-class-members': ['error', 'always'],
    'prefer-template': 'error',
    'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: true }],
    'vue/new-line-between-multi-line-property': [
      'error',
      {
        minLineOfMultilineProperty: 2
      }
    ],
    'vue/require-name-property': 'error',
    'vue/object-curly-spacing': ['error', 'always'],
    'vue/padding-line-between-blocks': ['error', 'always'],
    // https://eslint-plugin-vue-i18n.intlify.dev/rules/#recommended
    '@intlify/vue-i18n/no-html-messages': ['error'],
    '@intlify/vue-i18n/no-missing-keys': ['error'],
    '@intlify/vue-i18n/no-raw-text': 'off',
    '@intlify/vue-i18n/no-v-html': 'error',
    '@intlify/vue-i18n/key-format-style': ['error', 'snake_case'],
    '@intlify/vue-i18n/no-duplicate-keys-in-locale': [
      'error',
      {
        ignoreI18nBlock: false
      }
    ],
    '@intlify/vue-i18n/no-dynamic-keys': 'error',
    '@intlify/vue-i18n/no-unused-keys': [
      'off',
      {
        extensions: ['.js', '.vue']
      }
    ]
  },
  settings: {
    'vue-i18n': {
      localeDir: 'locales/*.json'
    }
  }
}

What did you do?

en-GB.json

{
  "WELCOME": "Welcome",
  "LOCALE_TEST_STRING": "This is a sentence in english",
  "thisShouldError": "if you see this eslint is not working as expected"
}

What did you expect to happen?
Eslint to error on the thisShouldError key because of '@intlify/vue-i18n/key-format-style': ['error', 'snake_case'] is set to snake_case and the key is camelCase

What actually happened?
No error reported

Add rule `enforce-interpolation-with-parenthesis`

Please describe what the rule should do:

This rule would force people to use the @:(interpolation.path) syntax with the parenthesis.

This rule should prevent errors where we need to add a period (dot in the end of a sentence) right after an interpolation.

What category should the rule belong to?

  • Enforces code style (layout)
  • Warns about a potential error (problem)
  • Suggests an alternate way of doing something (suggestion)
  • Other (please specify:)

Provide 2-3 code examples that this rule should warn about:

{
  "foo": "bar",
  "baz": "I want @:foo" // <- this should get an error
}
{
  "foo": "bar",
  "baz": "I want @:foo. My popcorn is gonna melt :thinking:" // <- this should get an error
}

Additional context

No-unused-keys not working

To be honest, I'm not sure if this is an issue or if I'm not configuring stuff right. I'm trying to find unused keys in my json files. However, linting gives me no errors at all even though I'm sure I have unused keys :)

This is my eslint config:

"eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "@vue/standard",
      "plugin:vue-i18n/recommended"
    ],
    "rules": {
      "vue-i18n/no-unused-keys": [
        "error",
        {
          "src": [
            "./src"
          ],
          "extensions": [
            ".js",
            ".vue",
            ".json"
          ]
        }
      ]
    },
    "parserOptions": {
      "parser": "babel-eslint",
      "sourceType": "module",
      "allowImportExportEverywhere": false
    },
    "settings": {
      "vue-i18n": {
        "localeDir": "./src/locales/*.json"
      }
    }
  }

Running vue-cli-service lint shows me no-raw-text and no-missing-keys warnings, but no no-unused-keys whatsoever.

Any thoughts?

disable eslint-plugin-vue-i18n on a single component

For one particular component, I don't want to activate i18n, so I did the following:

<script>
export default {
  nuxtI18n: false
}
</script>

But then eslint-plugin-vue-i18n is still complaining I have raw text in that component.
I have added /* eslint-disable vue-i18n/no-raw-text */ inside the script tags, but it's not working and is still giving me warnings about the raw text

<script>
/* eslint-disable vue-i18n/no-raw-text */
export default {
  nuxtI18n: false
}
</script>

Is this a bug or a known issue?

SFC: Opening angle bracket in yaml value makes all rules pass

When using an opening angle bracket followed by at least one character in a yaml SFC component, failures are not reported anymore. The following reports DONE No lint errors found!:

<i18n lang="yaml" locale="en">
unused: "<i"
</i18n>

<template>
  <div>
    {{ $t('missing') }}
  </div>
</template>

When changing this the value to "<" or "i", the two expected errors are thrown (error: unused 'unused' key (@intlify/vue-i18n/no-unused-keys) and error: 'missing' does not exist in 'en' (@intlify/vue-i18n/no-missing-keys))

Add `SCREAMING_SNAKE_CASE` to `key-format-style` rule

What rule do you want to change?
@intlify/vue-i18n/key-format-style

Does this change cause the rule to produce more or fewer warnings?
Depends.

How will the change be implemented? (New option, new default behavior, etc.)?
New option, slightly changed behaviour (snake_case would stop matching SCREAMING_SNAKE_CASE).

Please provide some example code that this change will affect:
Allow SCREAMING_SNAKE_CASE as an allowed option.

<i18n>
{
  "en": {
    "states": {
      "RUNNING": "Your process is still running.",
      "COMPLETED": "The process has been completed successfully.",
      "FAILED": "The process has failed."
    }
  }
}
</i18n>

What does the rule currently do for this code?
There is no option that differentiates SCREAMING_SNAKE_CASE from common snake_case right now.

What will the rule do after it's changed?
SCREAMING_SNAKE_CASE naming pattern is pretty common for enumerations and other similar constants in JavaScript. By making it different from normal snake_case and allowing independent setting, this pattern can be supported.

Additional context
Google's JavaScript naming conventions

Error: Value src should be string

Version 0.6.0

Based on the example from #21 (comment)

rules: {
		'@intlify/vue-i18n/no-unused-keys': ['error', {
			"src": [ "./src" ],
			extensions: [ '.ts', '.js', '.vue', '.json' ]
		}]
	},

Error:

Module build failed (from ./node_modules/eslint-loader/index.js):
Error: .eslintrc.js:
        Configuration for rule "@intlify/vue-i18n/no-unused-keys" is invalid:
        Value ["./src"] should be string.

SFC: `no-unused-keys` without <template> not working

Currently you need at least an empty <template> tag in a SFC to make the no-unused-keys rule work.

The following results in DONE No lint errors found!:

<i18n lang="yaml" locale="en">
test: Test
</i18n>

<script>
export default {
  render (createElement) {
    return createElement('div')
  }
}
</script>

While the following correctly throws error: unused 'test' key (@intlify/vue-i18n/no-unused-keys) at [...]:

<i18n lang="yaml" locale="en">
test: Test
</i18n>

<template>
  <div/>
</template>

I expect the first example to throw the same error.

No support for multi-locale JSON files

It seems that the plugin only supports separate JSON file for each locale - but can not work with a single JSON file which contains all the locales.

A naive solution would be something like this (which probably handles only the vue/no-missing-keys rule) - but maybe there is a better way ?

Index: \eslint-plugin-vue-i18n\lib\utils\index.js
===================================================================
--- \eslint-plugin-vue-i18n\lib\utils\index.js
+++ \eslint-plugin-vue-i18n\lib\utils\index.js
@@ -58,15 +58,33 @@
   const paths = key.split('.')
   localeMessages.forEach(localeMessage => {
     const length = paths.length
     let last = localeMessage.messages
+    let locales = (last && Object.keys(last)) || []
     let i = 0
     while (i < length) {
       const value = last && last[paths[i]]
       if (value === undefined) {
-        missings.push({
-          message: `'${key}' does not exist`
+        
+        const missing = locales.every(language => {
+          let last2 = localeMessage.messages[language]
+          let j = 0
+          while (j < length) {
+            const value2 = last2 && last2[paths[j]]
+            if (value2 === undefined) return true
+            last2 = value2
+            j++
+          }
+          return false
         })
+        
+        if (missing)
+        {
+          missings.push({
+            message: `'${key}' does not exist`
+          })
+          break
+        }
       }
       last = value
       i++
     } 

The same warning message occurs many times

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>

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Support for js based locales

I switched my locale files from js to json to get the benefits of this package, there are still gaps though, for example, I build some translations dynamically out of the main set, which means I am now seeing erroneous no-missing-keys warnings, it'd be great to be able to use js-based locales

Cannot find module

Hi, I've installed "@intlify/eslint-plugin-vue-i18n": "0.4.1" as described on NPM and uninstalled the older package, but now I get this error on console:

image

Is the documentation outdated?

eslint targeting `<i18n/>` blocks

I have some really long translation copy:

<i18n>
  "en": {
    "translation-key": "A realllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllly long string"
  }
</i18n>

I've got everything all set up. But eslint-plugin-vue seems to be linting my <i18n/> blocks:

  5:1  error  Line 5 exceeds the maximum line length of 100  max-len

I'm guessing this is because the type is javascript/auto:

      {
        resourceQuery: /blockType=i18n/,
        type: 'javascript/auto',
        loader: '@kazupon/vue-i18n-loader'
      },

Is there any way to tell webpack that it's JSON, not javascript?

Alternatively, it would be nice if the <i18n/> block could BE javascript, so that I could break up my long lines, etc.

Thank you.

No hot-reloading support

After you run npm run dev and start working on your Vue application, if you add a new localization string in the JSON locale file and then try to use it in your template - it is not catched by this plugin and it continues to produce warnings for the rule vue/no-missing-keys until you restart the Webpack-dev-server.

Even if I change the function loadLocaleMessages in file /lib/utils/index.js to watch the filesystem there is still some race condition and I have to save my Vue components twice before the plugin catches the changed JSON file:

function loadLocaleMessages (pattern) {
  const files = glob.sync(pattern)
  return files.map((file,index) => {
    const path = resolve(process.cwd(), file)
    const filename = file.replace(/^.*(\\|\/|:)/, '')
    const messages = require(path)
    const result = { fullpath: path, path: file, filename, messages }

    // we only watch the existing files - so we can not catch the adding of new files to the directory
    fs.watch(path, (event, filename) => {
      if (filename) {
        delete require.cache[require.resolve(path)] // invalidate the cache
        result.messages = require(path) // does not handle deleting/renaming a file
      }
    })
    return result
  })
}

Misspelled UNEXPETECD_ERROR_LOCATION

The constant UNEXPETECD_ERROR_LOCATION is spelled wrongly - it should be UNEXPECTED_ERROR_LOCATION and the error message is missing the word set before localeDir:

 if (!settings['vue-i18n'] || !settings['vue-i18n'].localeDir) {
    context.report({
      loc: UNEXPETECD_ERROR_LOCATION, // wrong spelling
      message: `You need to 'localeDir' at 'settings. See the 'eslint-plugin-vue-i18n documentation`
      //                                  ^-- need to add the missing word "set"
    })

Another misspelling - // detect used lodalization keys with linter should be localization

no-message-keys warns when using <i18n> components and <i18n> blocks.

I'm using version v0.7.0 of eslint-plugin-vue-i18n (which includes PR #80) and I'm getting an error that the message keys are not used when they are present for the path prop of an <i18n> component.

Simplified Test.vue:

<template>
  <i18n path="message_key" tag="p" />
</template>

<i18n>
{
  "en": {
    "message_key": "hi"
  }
}
</i18n>

.eslintrc.js:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/prettier',
    'plugin:@intlify/vue-i18n/recommended'
  ],
  parserOptions: {
    parser: 'babel-eslint'
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'prettier/prettier': [
      'warn',
      {
        singleQuote: true,
        trailingCommas: 'none',
        vueIndentScriptAndStyle: true
      }
    ],
    '@intlify/vue-i18n/no-html-messages': 'error',
    '@intlify/vue-i18n/no-missing-keys': 'error',
    '@intlify/vue-i18n/no-raw-text': 'error',
    '@intlify/vue-i18n/no-v-html': 'error',
    '@intlify/vue-i18n/no-dynamic-keys': 'error',
    '@intlify/vue-i18n/no-unused-keys': 'error'
  },
  overrides: [
    {
      files: [
        '**/__tests__/*.{j,t}s?(x)',
        '**/tests/unit/**/*.spec.{j,t}s?(x)'
      ],
      env: {
        jest: true
      }
    }
  ],
  settings: {
    'vue-i18n': {
      localeDir: {
        pattern: './*.vue',
        localeKey: 'key'
      }
    }
  }
};

Error when running lint:

error: unused 'en.message_key' key (@intlify/vue-i18n/no-unused-keys) at src/components/Test.vue:8:5:
   6 | {
   7 |   "en": {
>  8 |     "message_key": "hi"
     |     ^
   9 |   }
  10 | }
  11 | </i18n>

Dependencies:


  "dependencies": {
    "axios": "^0.18.0",
    "core-js": "^3.6.5",
    "moment": "^2.27.0",
    "v-mask": "^2.2.3",
    "vue": "^2.6.11",
    "vue-i18n": "^8.20.0",
    "vue-router": "^3.2.0",
    "vuejs-logger": "^1.5.3",
    "vuelidate": "^0.7.5",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@intlify/eslint-plugin-vue-i18n": "^0.7.0",
    "@intlify/vue-i18n-loader": "^1.0.0",
    "@kazupon/vue-i18n-loader": "^0.5.0",
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-e2e-cypress": "~4.4.0",
    "@vue/cli-plugin-eslint": "~4.4.0",
    "@vue/cli-plugin-pwa": "^4.4.6",
    "@vue/cli-plugin-router": "~4.4.0",
    "@vue/cli-plugin-unit-jest": "~4.4.0",
    "@vue/cli-plugin-vuex": "~4.4.0",
    "@vue/cli-service": "~4.4.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/test-utils": "^1.0.3",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.8.0",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-vue": "^6.2.2",
    "lint-staged": "^9.5.0",
    "node-sass": "^4.12.0",
    "npm-force-resolutions": "0.0.3",
    "prettier": "^1.19.1",
    "register-service-worker": "^1.7.1",
    "sass-loader": "^8.0.2",
    "vue-cli-plugin-i18n": "~1.0.1",
    "vue-template-compiler": "^2.6.11",
    "workbox-webpack-plugin": "^5.1.3"
  },

Originally posted by @mandragorn in #70 (comment)

[No-missing-keys] not working correctly

Hi, I'm facing this problem you can see on the image below.
The key is receiving a warning that the key is missing, but it is working on the UI

image

image

Anyone knows what is the problem?

Btw, if I reload VSCode, stops showing the warning, but, if I change the label, it starts warning again
Thank you

v-icon and raw text

Hey @kazupon,

first i'd like to thank you for your great work. 🎉

I've just added vue-i18n linting to our vuetify project and noticed several warnings about raw-text within our v-icon slots.

warning: raw text 'mdi-car' is used (vue-i18n/no-raw-text) at 
src/views/systems/Systems.vue:11:38:
  10 |           <v-list-tile-avatar>
> 11 |             <v-icon slot="activator">mdi-car</v-icon>
     |                                      ^
  12 |           </v-list-tile-avatar>
  13 |           <v-list-tile-content @click="goToDashboard(system)">

What would be your approach to deal with that kind of warnings? In our project those icons have no need to be localised.

[Rule] No-missing-keys - Not working correctly

I'm using the nested messages in a JSON file. And this error happening for every line like that:

warning: 'materials.notice.text' does not exist (vue-i18n/no-missing-keys)

But my page working perfectly. How can i fix this console warnings?

📢 Notice: transfer of repository

eslint-plugin-vue-i18n will soon be transferred to intlify organaization. After that, it will be developed and maintained on intlify.

The eslint-plugin-vue-i18n that has been released on npm will be released as @intlify/eslint-plugin-vue-i18n in near future.

Intlify is a new i18n project kickoff by @kazupon. 😉

Unexpected token export

When running ESLint with vue-cli-service lint I get the following error:

SyntaxError: Error while loading rule 'vue-i18n/no-missing-keys': Unexpected token export
Occurred while linting xxx\src\App.vue
xxx\src\internationalization\languages\de.js:1
(function (exports, require, module, __filename, __dirname) { export default {
                                                              ^^^^^^

SyntaxError: Unexpected token export
    at new Script (vm.js:79:7)
    at createScript (vm.js:251:10)
    at Object.runInThisContext (vm.js:303:10)
    at Module._compile (internal/modules/cjs/loader.js:656:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
    at Module.require (internal/modules/cjs/loader.js:636:17)
    at require (internal/modules/cjs/helpers.js:20:18)

The message file de.js (and all others) look like this:

// de.js
export default {
  message: {
    navigation: {
      foo: 'bar'
    }
  }
}   

Can you help me with this? Did I configured something wrong?

Other project files

// eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true
  },
  'extends': [
    'plugin:vue/essential',
    'plugin:vue/strongly-recommended',
    'plugin:vue/recommended',
    'plugin:vue-i18n/recommended',
    '@vue/standard'
  ],
  rules: {
    ...
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  settings: {
    'vue-i18n': {
      localeDir: './src/internationalization/languages/*.js'
    }
  }
}
// package.json
{
  ...
  "devDependencies": {
    "@vue/cli-plugin-babel": "3.5.5",
    "@vue/cli-plugin-eslint": "3.5.1",
    "@vue/cli-service": "3.5.3",
    "@vue/eslint-config-standard": "^4.0.0",
    "babel-eslint": "^10.0.1",
    "cross-env": "^5.2.0",
    "eslint": "5.16.0",
    "eslint-plugin-vue": "5.2.2",
    "eslint-plugin-vue-i18n": "^0.1.0",
    "node-sass": "^4.11.0",
    "sass-loader": "^7.1.0",
    "stylelint": "^9.10.1",
    "stylelint-config-recommended-scss": "^3.2.0",
    "stylelint-scss": "^3.5.4",
    "vue-template-compiler": "2.6.10"
  }
}

no-missing-keys warns when using <i18n> blocks

Thanks for the eslint plugin, it helps a lot !

On my project, I use a combination of global translation files and component-local <i18n> blocks.
I still get lint warnings eslint(vue-i18n/no-missing-keys) on translation strings defined in <i18n> blocks, and I don't understand why (everything work OK in the app).

Here our eslint config :

  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "@vue/standard",
      "plugin:vue-i18n/recommended",
      "plugin:chai-friendly/recommended"
    ],
    "rules": {
      "no-console": [
        "error",
        {
          "allow": [
            "warn",
            "error"
          ]
        }
      ]
    },
    "settings": {
      "vue-i18n": {
        "localeDir": "./src/locales/*.json"
      }
    },
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/unit/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  }

Here, the dependencies (we used vue-cli) :

  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.10",
    "vue-i18n": "^8.18.2",
    "vue-router": "^3.3.4"
  },
  "devDependencies": {
    "@intlify/vue-i18n-loader": "^1.0.0",
    "@tailwindcss/ui": "^0.3.0",
    "@vue/cli-plugin-babel": "^4.4.6",
    "@vue/cli-plugin-e2e-cypress": "^4.4.6",
    "@vue/cli-plugin-eslint": "^4.4.6",
    "@vue/cli-plugin-router": "^4.4.6",
    "@vue/cli-plugin-unit-jest": "^4.4.6",
    "@vue/cli-service": "^4.4.6",
    "@vue/eslint-config-standard": "^5.1.2",
    "@vue/test-utils": "1.0.0-beta.29",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.8.0",
    "eslint-plugin-chai-friendly": "^0.6.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^6.2.2",
    "eslint-plugin-vue-i18n": "^0.3.0",
    "vue-cli-plugin-i18n": "^1.0.1",
    "vue-cli-plugin-tailwind": "^1.4.1",
    "vue-template-compiler": "^2.6.10"
  }

Conditional expressions don't use ignore pattern and nodes

Ternary operators do not use ignoreNodes and or Pattern. For example if I have this code:
<v-icon>{{ item.esPerdido ? 'mdi-thumb-down' : 'mdi-trophy'}}</v-icon>

and this ignorePattern:

ignorePattern: /^[-#:()&%.,0123456789\s]+|(mdi-.*)$/,

The linting warns me that there are two texts that are wrong.

The problem is that the function checkVExpressionContainerText isn't using the ignorePattern rules as checkRawText

Add ignore pattern option to no-raw-text rule

The no-raw-text rule can be great to detect where I forgot to add a translatable string because I used a plain string instead. But sometimes I like to add spaces as a separator for inline content.

See below for an example. This creates a table cell with a person's name prefix and sortable last name. Naturally this should be separated by a space. The no-raw-text rule complains "raw text ' ' used".

                <b-table-column
                    :label="$t('lastName')"
                    field="sortableLastName"
                    sortable
                >
                    {{ column.row.prefix }} {{ column.row.sortableLastName }}
                </b-table-column>

I would like to propose an ignore pattern option for the no-raw-text rule:

"vue-i18n/no-row-text: [ "warn", {
  "ignorePattern": "^\s+$"
}]

or alternatively, since I suspect this is a common case:

"vue-i18n/no-row-text: [ "warn", {
  "ignoreWhitespace": true
}]

SFC: Support `mixins` and `extends`

Currently the following still throws error: unused 'test' key (@intlify/vue-i18n/no-unused-keys) - even if either OtherComponent or Mixin do use the test translation key:

<i18n lang="yaml" locale="en">
test: Test
</i18n>

<template>
  <div />
</template>

<script>
import OtherComponent from 'OtherComponent'
import Mixin from 'Mixin'

export default {
  extends: OtherComponent,
  mixins: [Mixin]
}
</script>

I would expect this to pass if the key is used in any inherited component/mixin.

It would be cool if that worked the other way around as well (so the <i18n> block in the OtherComponent or Mixin - and the usage of the translation keys in this component) for the no-missing-keys rule. (I don't know whether that actually works right now with vue-i18n at all. I have a custom merge strategy in place, that merges i18n blocks with those extends/mixin components, so it does for me quite well.)

Support linting yaml i18n blocks in SFC

Now that linting <i18n> blocks in SFC is possible (#80), it would be great if yaml would be supported as well.

Using yaml for i18n blocks is suggested in the vue-i18n docs at https://kazupon.github.io/vue-i18n/guide/sfc.html#yaml-loading, so I guess it would make sense to support it here as well.

Maybe it's possible to just load the <i18n> blocks through vue-loader as suggested in #80 (comment) instead of loading the json manually? That might take care of all that automatically.

intlify/vue-i18n/no-unused-keys does not work with TS/TSX

I have tried to integrate this rule for an hour but can't make this work for my project. I'm using Vue with Typescript and my Component are all .tsx
Other rule were working just fine but this rule didn't work as my expected. Here are my rule config & setting, I'm using plugin:@intlify/vue-i18n/recommended btw:

'@intlify/vue-i18n/no-unused-keys': ["error", {
      "src": "./src",
      "extensions": [".tsx", ".ts"],
      "enableFix": true,
    }],
  settings: {
    'vue-i18n': {
      localeDir: './src/locales/*.{json,json5,yaml,yml}',
    }
  }

SFC: `no-html-messages` not working

The following passes with DONE No lint errors found!:

<i18n lang="yaml" locale="en">
html: "<i>test</i>"
</i18n>

<template>
  <div>
    {{ $t('html') }}
  </div>
</template>

I would expect it to throw an error for no-html-messages.

Looking at the tests I found this:

.replace(/</g, '&lt;')}</i18n>

I don't think the tests are currently testing correctly with this replace. I guess this replace has been added because of #107.

In fact, using the following in my SFC throws the correct error (error: used HTML localization message (@intlify/vue-i18n/no-html-messages):

<i18n lang="yaml" locale="en">
html: "&lt;i>test&lt;/i>"
</i18n>

<template>
  <div>
    {{ $t('html') }}
  </div>
</template>

This is surely not what is to be expected?

docs site redirection

Why?

Before transfer to intlify, we need to transfer the docs site to ensure that existing URLs do not dead link

Current Doc Site

New Doc Site

New doc site use netlify. The docs of eslint-plugin-vue-i18n uses vuepress, maybe I think migration is easy. 😉

related info

https://help.github.com/en/enterprise/2.14/user/articles/redirects-on-github-pages

[no-missing-keys] option for default locale

What rule do you want to change?
no-missing-keys

Does this change cause the rule to produce more or fewer warnings?
Fewer

How will the change be implemented? (New option, new default behavior, etc.)?
New option to specify the default locale file

Additional context
Often, and especially during development, I will setup all my keys for en-GB.json but other locales will only have a few or a lot of gaps until they are completed (this is done via an external programme that automates the creation of the missing keys). With the behaviour of vue-i18n being that it falls back to the default locale if a key is missing.

It would be great if we could specify a single file to check instead of it looking in all locales for missing keys.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.