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

Prettier rules gives Unexpected token #40

Closed
azuken opened this issue Apr 20, 2021 · 10 comments
Closed

Prettier rules gives Unexpected token #40

azuken opened this issue Apr 20, 2021 · 10 comments

Comments

@azuken
Copy link

azuken commented Apr 20, 2021

Hello,

I've installed this plugin for a React Native project, and everything is working so far, but one error by translation file remains, and I don't know what is wrong.

eslint --fix --format node_modules/eslint-plugin-i18n-json/formatter.js --ext .json src/locales

is reporting me

src/locales/de/translation.json

✖  ERROR  (prettier/prettier)
  Parsing error: Unexpected token

src/locales/en/translation.json

✖  ERROR  (prettier/prettier)
  Parsing error: Unexpected token

src/locales/es/translation.json

✖  ERROR  (prettier/prettier)
  Parsing error: Unexpected token

src/locales/fr/translation.json

✖  ERROR  (prettier/prettier)
  Parsing error: Unexpected token

> ✖ 4 ERRORS
> ⚠ 0 WARNINGS
error Command failed with exit code 1.

I've checked file format, line ending, invisible characters, error still appears.

Here is my .eslintrc.js config file :

module.exports = {
  env: {
    node: true,
    es6: true,
    jest: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
    'plugin:i18n-json/recommended',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 2018,
    project: './tsconfig.json',
    sourceType: 'module',
  },
  plugins: ['react', 'react-hooks', '@typescript-eslint', 'prettier'],
  rules: {
    indent: [
      'error',
      2,
      {
        SwitchCase: 1,
        ignoredNodes: ['CallExpression > ObjectExpression, ConditionalExpression'],
      },
    ],
    'linebreak-style': ['error', 'unix'],
    quotes: ['error', 'single', { avoidEscape: true }],
    semi: ['error', 'never'],
    'no-empty-function': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    '@typescript-eslint/no-unsafe-assignment': 'off',
    '@typescript-eslint/restrict-template-expressions': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-unsafe-return': 'off',
    '@typescript-eslint/no-unsafe-member-access': 'off',
    '@typescript-eslint/no-unsafe-call': 'off',
    '@typescript-eslint/restrict-plus-operands': 'off',
    '@typescript-eslint/ban-ts-comment': 'off',
    '@typescript-eslint/no-floating-promises': 'warn',
    '@typescript-eslint/no-var-requires': 'warn',
    '@typescript-eslint/no-implied-eval': 'warn',
    '@typescript-eslint/ban-types': 'warn',
    '@typescript-eslint/unbound-method': 'warn',
    '@typescript-eslint/require-await': 'warn',
    'prefer-rest-params': 'warn',
    'no-prototype-builtins': 'off',
    'react/display-name': 'off',
    'react/prop-types': 'off',
    'prettier/prettier': 'error',
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
}

and my .prettierrc.js file :

module.exports = {
  jsxBracketSameLine: true,
  singleQuote: true,
  trailingComma: 'all',
  printWidth: 120,
  semi: false,
  arrowParens: 'always',
}
@azuken
Copy link
Author

azuken commented Apr 29, 2021

I think linter is parsing files with wrong format, because I have other errors which indicate parser is not considering json values with parameters correctly :

✖  ERROR  (no-irregular-whitespace)
  Irregular whitespace not allowed.
✖  ERROR  (i18n-json/valid-message-syntax)

  - Expected
  + Received

    Object {
  -     "forThe": "ValidMessage<String>",
  +     "forThe": "String('Pour le {{date}}') ===> Expected argNameOrNumber but '{' found.",
      },

@Siggnja
Copy link

Siggnja commented Apr 29, 2021

@azuken I'm actually facing the exact same issue, have you manage to resolve this somehow?

@azuken
Copy link
Author

azuken commented Apr 29, 2021

@Siggnja No, I have tried to search for invisible chars, special chars, file format, line endings, and the result is the same. So I hope that authors will have an answer !

@Siggnja
Copy link

Siggnja commented Apr 29, 2021

@azuken I added the folder that includes my i18n json files to .prettierIgnore, that at least removes the errors. Not happy about this though but at least I can continue with my day.

@apawson
Copy link

apawson commented May 12, 2021

@azuken @Siggnja You are seeing errors from additional eslint rules/plugins because, although you've specified that JSON files should be linted (--ext .json), ALL the rules/plugins in your .eslintrc.js config still apply (including prettier). I'd suggest the following:

  1. Create a new eslint config file – .eslintrc.i18n-json.js – and save it in the same location as your .eslintrc.js. It should contain just the following:
module.exports = {
  extends: ["plugin:i18n-json/recommended"]
}
  1. Then specify this config (and disable the default .eslintrc.js one) with eslint --no-eslintrc --config .eslintrc.i18n-json.json --fix --ext .json --format node_modules/eslint-plugin-i18n-json/formatter.js src/locales

@azuken
Copy link
Author

azuken commented May 17, 2021

@apawson I've just tested your solution with another eslintrc file, and syntax errors still appears.

✖  ERROR  (i18n-json/valid-message-syntax)
  +     "forThe": "String('For the {{date}}') ===> Expected argNameOrNumber but '{' found.",

But prettier errors are gone !

@apawson
Copy link

apawson commented May 17, 2021

@apawson I've just tested your solution with another eslintrc file, and syntax errors still appears.

✖  ERROR  (i18n-json/valid-message-syntax)
  +     "forThe": "String('For the {{date}}') ===> Expected argNameOrNumber but '{' found.",

But prettier errors are gone !

@azuken Based on the error message, I'd guess that somewhere in your code you are referencing the translation without passing the value for date.

- t('forThe')
+ t('forThe', { date: '17th of May' })

@azuken
Copy link
Author

azuken commented May 17, 2021

@apawson

I've verified in my code and I use this translation only once, and I have my parameter passed :

<Text>
    {t('cart.forThe', {
        date: moment(myDate, "YYYY-MM-DD'T'HH:mm:ssZ", ).format('Do MMMM HH:mm'),
    })}
</Text>

All other translations with errors are correctly implemented. It seems that the plugin does not recognize parameter with double brackets. If i set only one pair of brackets, linter is ok, but translation does not insert parameter...

@apawson
Copy link

apawson commented May 17, 2021

@azuken https://github.com/godaddy/eslint-plugin-i18n-json doesn't, by default, support the i18next translation syntax.

See: #7 (comment)

As noted ☝️ , you can write a custom validator like this: https://github.com/godaddy/eslint-plugin-i18n-json/tree/master/examples/custom-message-syntax

Feel free to steal this one which I wrote for my own i18next use...

const validate = (message = '') => {
  if (!(message || '').trim()) {
    throw new SyntaxError('Message is Empty.');
  }
  if (typeof message !== 'string') {
    throw new TypeError('Message must be a String.');
  }
  if (
    (message.includes('{') || message.includes('}')) &&
    !/{{ ?(?:- |\w+?)(, ?)?\w+? ?}}/g.test(message)
  ) {
    throw new SyntaxError(
      'Interpolation error. See: https://www.i18next.com/misc/json-format',
    );
  }
  if (message.includes('$t(') && !/\$t\([\w]+:\w+(?:\.\w+)*\)/g.test(message)) {
    throw new SyntaxError(
      'Nesting error. See: https://www.i18next.com/misc/json-format',
    );
  }
};

module.exports = validate;

#7 (comment)

@azuken
Copy link
Author

azuken commented May 18, 2021

@apawson Okay I didn't saw that i18next was not compatible.

Works like a charm now, thank you !

For future readers, add sample code ⬆️ into a file named custom-message-syntax.js at root project, and add this in the .eslintrc.i18n-json.js :

const path = require('path')

module.exports = {
  extends: ['plugin:i18n-json/recommended'],
  rules: {
    'i18n-json/valid-message-syntax': [
      2,
      {
        syntax: path.resolve('./custom-message-syntax'),
      },
    ],
  },
}

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

3 participants