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

As of 3.0.0, optional chaining in variables causes fatal errors. #205

Closed
justrealmilk opened this issue Nov 12, 2020 · 19 comments
Closed

As of 3.0.0, optional chaining in variables causes fatal errors. #205

justrealmilk opened this issue Nov 12, 2020 · 19 comments

Comments

@justrealmilk
Copy link

{t('String {{string}}', { string: something.thing?.maybe })}

It won't process this while 2.11.0 would

@genesiscz
Copy link

any updates?

@joshuaja
Copy link

joshuaja commented Nov 24, 2020

I wasn't able to get this to work in 2.11.0 or 3.0.0 Any workarounds? I tried processing against the built dist directory but I got even more errors doing that.

@6uliver
Copy link

6uliver commented Feb 26, 2021

It's a duplicate of this one: #178
You have to use at least 3.0.0 and should set "ecmaVersion" to 11 in the config.

@ShenHongFei
Copy link

@6uliver
The problem still exists because parser.parseFuncFromString use esprima rather than acorn to parse code while esprima still lack the support of optional chaining !!
jquery/esprima#2023
For a temporary solution, you may try

parser.parseFuncFromString(code.replace(/\?\.\[/g, '[').replace(/\?\.\(/g, '(').replace(/\?\./g, '.'), on_scanned)

@justrealmilk
Copy link
Author

It's a duplicate of this one: #178
You have to use at least 3.0.0 and should set "ecmaVersion" to 11 in the config.

Could you pretty please post an example?

@6uliver
Copy link

6uliver commented Mar 17, 2021

It's a duplicate of this one: #178
You have to use at least 3.0.0 and should set "ecmaVersion" to 11 in the config.

Could you pretty please post an example?

Sure, I'm using this config for acorn in my i18next-scanner.config.js:

module.exports = {
  // ...
  options: {
    // ...
    trans: {
      // ...
      acorn: {
        ecmaVersion: 11,
        sourceType: 'module',
      },
    },
  },
}

@justrealmilk
Copy link
Author

justrealmilk commented Mar 17, 2021

acorn: {
ecmaVersion: 11,
sourceType: 'module',
},

Well I was hopeful I could just slide that into this

scanner({
  func: {
    list: ['t'],
    extensions: ['.js', '.ts', '.tsx'],
  },
  trans: {
    acorn: {
      ecmaVersion: 11,
      sourceType: 'module',
    },
  },
  nsSeparator: false,
  keySeparator: false,
  removeUnusedKeys: true,
  sort: true,
  lngs: ['de', 'en', 'es', 'es-MX', 'fr', 'it', 'ja', 'ko', 'pl', 'pt-BR', 'ru', 'zh-CHS', 'zh-CHT'],
  defaultLng: 'en',
  defaultValue: function (lng, ns, key) {
    if (lng === 'en') {
      return key;
    } else if (en[key]) {
      return `🦘 ${en[key]}`;
    } else {
      return '🦘';
    }
  },
  resource: {
    loadPath: 'src/locales/{{lng}}/{{ns}}.json',
    savePath: 'src/locales/{{lng}}/{{ns}}.json',
  },
})

Alas, same error. I guess it's the wrong property at wrong level or something

@6uliver
Copy link

6uliver commented Mar 17, 2021

acorn: {
ecmaVersion: 11,
sourceType: 'module',
},

Well I was hopeful I could just slide that into this

scanner({
  func: {
    list: ['t'],
    extensions: ['.js', '.ts', '.tsx'],
  },
  trans: {
    acorn: {
      ecmaVersion: 11,
      sourceType: 'module',
    },
  },
  nsSeparator: false,
  keySeparator: false,
  removeUnusedKeys: true,
  sort: true,
  lngs: ['de', 'en', 'es', 'es-MX', 'fr', 'it', 'ja', 'ko', 'pl', 'pt-BR', 'ru', 'zh-CHS', 'zh-CHT'],
  defaultLng: 'en',
  defaultValue: function (lng, ns, key) {
    if (lng === 'en') {
      return key;
    } else if (en[key]) {
      return `🦘 ${en[key]}`;
    } else {
      return '🦘';
    }
  },
  resource: {
    loadPath: 'src/locales/{{lng}}/{{ns}}.json',
    savePath: 'src/locales/{{lng}}/{{ns}}.json',
  },
})

Alas, same error. I guess it's the wrong property at wrong level or something

I'm sorry, it works for me. By the way I'm not using Typescript.
Could you post your error message? I think it would be helpful for the maintainer.

@justrealmilk
Copy link
Author

acorn: {
ecmaVersion: 11,
sourceType: 'module',
},

Well I was hopeful I could just slide that into this

scanner({
  func: {
    list: ['t'],
    extensions: ['.js', '.ts', '.tsx'],
  },
  trans: {
    acorn: {
      ecmaVersion: 11,
      sourceType: 'module',
    },
  },
  nsSeparator: false,
  keySeparator: false,
  removeUnusedKeys: true,
  sort: true,
  lngs: ['de', 'en', 'es', 'es-MX', 'fr', 'it', 'ja', 'ko', 'pl', 'pt-BR', 'ru', 'zh-CHS', 'zh-CHT'],
  defaultLng: 'en',
  defaultValue: function (lng, ns, key) {
    if (lng === 'en') {
      return key;
    } else if (en[key]) {
      return `🦘 ${en[key]}`;
    } else {
      return '🦘';
    }
  },
  resource: {
    loadPath: 'src/locales/{{lng}}/{{ns}}.json',
    savePath: 'src/locales/{{lng}}/{{ns}}.json',
  },
})

Alas, same error. I guess it's the wrong property at wrong level or something

I'm sorry, it works for me. By the way I'm not using Typescript.
Could you post your error message? I think it would be helpful for the maintainer.

i18next-scanner: Unable to parse code "{ number: clan.members.filter(member => member.data?.profile).length }"
i18next-scanner: Error: Line 1: Unexpected token .
    at ErrorHandler.constructError (G:\braytech.org\node_modules\esprima\dist\esprima.js:5012:22)
    at ErrorHandler.createError (G:\braytech.org\node_modules\esprima\dist\esprima.js:5028:27)
    at Parser.unexpectedTokenError (G:\braytech.org\node_modules\esprima\dist\esprima.js:1985:39)
    at Parser.throwUnexpectedToken (G:\braytech.org\node_modules\esprima\dist\esprima.js:1995:21)
    at Parser.parsePrimaryExpression (G:\braytech.org\node_modules\esprima\dist\esprima.js:2366:38)
    at Parser.inheritCoverGrammar (G:\braytech.org\node_modules\esprima\dist\esprima.js:2285:37)
    at Parser.parseLeftHandSideExpressionAllowCall (G:\braytech.org\node_modules\esprima\dist\esprima.js:2899:26)
    at Parser.inheritCoverGrammar (G:\braytech.org\node_modules\esprima\dist\esprima.js:2285:37)
    at Parser.parseUpdateExpression (G:\braytech.org\node_modules\esprima\dist\esprima.js:3004:26)
    at Parser.parseUnaryExpression (G:\braytech.org\node_modules\esprima\dist\esprima.js:3048:26) {
  index: 53,
  lineNumber: 1,
  description: 'Unexpected token .'
}

@6uliver
Copy link

6uliver commented Apr 7, 2021

In the meantime I'm facing the same issue on another project which is using TypeScript. I've found a workaround which is not so ugly: transform the source files with TypeScript before processing it with the scanner. In the scanner config I'm using the i18next-scanner-typescript package (https://www.npmjs.com/package/i18next-scanner-typescript) the following way:

const typescriptTransform = require('i18next-scanner-typescript')

module.exports = {
  input: ['src/**/*.{js,jsx,ts,tsx}'],
  output: './',
  options: {
    // ...
    func: {
      // ...
      extensions: ['.js', '.jsx'], // it's important to not include TS files like .ts and .tsx
    },
    trans: {
      // ...
      extensions: ['.js', '.jsx'], // it's important to not include TS files like .ts and .tsx
    },
  },
  // transformer exported by i18next-scanner-typescript which is processing TS files before parsing
  transform: typescriptTransform({
    extensions: ['.ts', '.tsx'],
  }),
};

@jgoncalv
Copy link

jgoncalv commented Oct 15, 2021

@6uliver The problem still exists because parser.parseFuncFromString use esprima rather than acorn to parse code while esprima still lack the support of optional chaining !! jquery/esprima#2023 For a temporary solution, you may try

parser.parseFuncFromString(code.replace(/\?\.\[/g, '[').replace(/\?\.\(/g, '(').replace(/\?\./g, '.'), on_scanned)

Yep I still have the problem. Will replacing esprima by acorn solved this ?
Self answer: I tried and yes it solved it. @cheton

@cheton
Copy link
Member

cheton commented Oct 15, 2021

It seems the esprima-next fork contains all the latest ESM features from esprima and has frequent updates on NPM. I will move to esprima-next in PR #221 and publish a new release.

@cheton
Copy link
Member

cheton commented Oct 15, 2021

A new version just published, this issue shall be resolved in v3.1.0

See https://www.npmjs.com/package/i18next-scanner for new versions

cc @justrealmilk @genesiscz @joshuaja @ShenHongFei @6uliver @jgoncalv

@cheton cheton closed this as completed Oct 15, 2021
@justrealmilk
Copy link
Author

Haha uhhhh

i18next-scanner: Unable to parse code "{ number: data.object!.number }"
i18next-scanner: Error: Line 1: Unexpected token !
    at e.constructError (G:\braytech.org\node_modules\esprima-next\dist\esprima.js:1:20546)

@cheton
Copy link
Member

cheton commented Oct 15, 2021

I think { number: data.object!.number } is supposed to be { number: data.object?.number }

@justrealmilk
Copy link
Author

I think { number: data.object!.number } is supposed to be { number: data.object?.number }

No, it's not - it's a non-null assertion operator

@cheton
Copy link
Member

cheton commented Oct 15, 2021

So far i18next-scanner does not have native support for TypeScript. You have to use TypeScript transpiler to transpile .ts files before passing content to the scanner.

@genesiscz
Copy link

@cheton @justrealmilk I use i18next-scanner-typescript and it works quite well.

@justrealmilk
Copy link
Author

i18next-scanner-typescript

Awesome! Thanks.

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

7 participants