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

"Unexpected token" error - Drop Esprima dependency? #354

Closed
1 of 6 tasks
Kritten opened this issue Sep 11, 2020 · 11 comments · Fixed by SAP/ui5-builder#615
Closed
1 of 6 tasks

"Unexpected token" error - Drop Esprima dependency? #354

Kritten opened this issue Sep 11, 2020 · 11 comments · Fixed by SAP/ui5-builder#615
Labels
enhancement New feature or request module/ui5-builder Related to the UI5 Builder module

Comments

@Kritten
Copy link

Kritten commented Sep 11, 2020

Technically this is an Esprima bug, but I do report this here because Esprima seems to be outdated in general and does not support modern JavaScript.
I've heard about the Fork Espree, but thats just a suggestion.

Expected Behavior

ui5 build should compile modern JavaScript code.

Current Behavior

The build fails if it encounters a spread operator.

Steps to reproduce the issue

  1. Copy the following snippet in any UI5 project
const foo = {
  1: 1, 2: 2, 3: 3
}
const bar = {
  ...foo
}
  1. run ui5 build
  2. It fails with the log below. The process returns 0 and states "Build succeeded", but the parsing error happens and the WebIDE cancels the build process.

Context

  • UI5 Module Version (output of ui5 --version when using the CLI): 2.4.2
  • Node.js Version: v12.10.0
  • npm Version: 6.13.4
  • OS/Platform: Windows and WebIDE

Affected components (if known)

Log Output / Stack Trace

info normalizer:translators:ui5Framework Using OpenUI5 version: 1.81.2
info builder:builder Building project openui5-sample-app not including dependencies...
info builder:builder �   (1/1) Building project openui5-sample-app
info builder:builder application openui5-sample-app � (1/8) Running task escapeNonAsciiCharacters...
info builder:builder application openui5-sample-app � (2/8) Running task replaceCopyright...
info builder:builder application openui5-sample-app � (3/8) Running task replaceVersion...
info builder:builder application openui5-sample-app � (4/8) Running task generateFlexChangesBundle...
info builder:builder application openui5-sample-app � (5/8) Running task generateComponentPreload...
ERR! lbt:resources:ResourcePool Error: Line 17: Unexpected token ...
ERR! lbt:resources:ResourcePool     at ErrorHandler.constructError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:5012:22)
ERR! lbt:resources:ResourcePool     at ErrorHandler.createError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:5028:27)
ERR! lbt:resources:ResourcePool     at Parser.unexpectedTokenError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:1985:39)
ERR! lbt:resources:ResourcePool     at Parser.throwUnexpectedToken (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:1995:21)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectPropertyKey (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2499:33)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectProperty (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2534:25)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectInitializer (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2602:35)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parsePrimaryExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2354:38)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseLeftHandSideExpressionAllowCall (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2899:26)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseUpdateExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3004:26)
ERR! lbt:resources:ResourcePool     at Parser.parseUnaryExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3048:26)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseExponentiationExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3054:26)
ERR! lbt:resources:ResourcePool  failed to parse or analyze %s: sap/ui/demo/todo/controller/App.controller.js Error: Line 17: Unexpected token ...
ERR! lbt:resources:ResourcePool     at ErrorHandler.constructError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:5012:22)
ERR! lbt:resources:ResourcePool     at ErrorHandler.createError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:5028:27)
ERR! lbt:resources:ResourcePool     at Parser.unexpectedTokenError (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:1985:39)
ERR! lbt:resources:ResourcePool     at Parser.throwUnexpectedToken (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:1995:21)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectPropertyKey (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2499:33)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectProperty (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2534:25)
ERR! lbt:resources:ResourcePool     at Parser.parseObjectInitializer (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2602:35)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parsePrimaryExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2354:38)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseLeftHandSideExpressionAllowCall (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2899:26)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseUpdateExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3004:26)
ERR! lbt:resources:ResourcePool     at Parser.parseUnaryExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3048:26)
ERR! lbt:resources:ResourcePool     at Parser.inheritCoverGrammar (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:2285:37)
ERR! lbt:resources:ResourcePool     at Parser.parseExponentiationExpression (xxxnode_modules\@ui5\cli\node_modules\esprima\dist\esprima.js:3054:26) {
ERR! lbt:resources:ResourcePool   index: 372,
ERR! lbt:resources:ResourcePool   lineNumber: 17,
ERR! lbt:resources:ResourcePool   description: 'Unexpected token ...',
ERR! lbt:resources:ResourcePool   stack: 'Error: Line 17: Unexpected token ...\n' +
ERR! lbt:resources:ResourcePool     '    at ErrorHandler.constructError (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:5012:22)\n' +
ERR! lbt:resources:ResourcePool     '    at ErrorHandler.createError (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:5028:27)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.unexpectedTokenError (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:1985:39)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.throwUnexpectedToken (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:1995:21)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseObjectPropertyKey (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2499:33)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseObjectProperty (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2534:25)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseObjectInitializer (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2602:35)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.inheritCoverGrammar (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2285:37)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parsePrimaryExpression (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2354:38)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.inheritCoverGrammar (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2285:37)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseLeftHandSideExpressionAllowCall (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2899:26)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.inheritCoverGrammar (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2285:37)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseUpdateExpression (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:3004:26)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseUnaryExpression (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:3048:26)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.inheritCoverGrammar (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:2285:37)\n' +
ERR! lbt:resources:ResourcePool     '    at Parser.parseExponentiationExpression (xxxnode_modules\\@ui5\\cli\\node_modules\\esprima\\dist\\esprima.js:3054:26)'
ERR! lbt:resources:ResourcePool }
info builder:builder application openui5-sample-app � (6/8) Running task createDebugFiles...
info builder:builder application openui5-sample-app � (7/8) Running task uglify...
info builder:builder application openui5-sample-app � (8/8) Running task generateVersionInfo...
info builder:builder Build succeeded in 748 ms
info builder:builder Executing cleanup tasks...

Process finished with exit code 0
@RandomByte
Copy link
Member

RandomByte commented Sep 11, 2020

Thanks for reporting. Yes, with the recent terser upgrade, Esprima (used in our preload generation) is currently the only piece that is still lacking ES6 support.

A switch to Espree seems reasonable. We'll discuss this in the team. I would be surprised if @codeworrior hasn't already looked into the differences between Esprima and Espree and the possible issues these could cause in our current implementation 😉

@RandomByte
Copy link
Member

We discussed this in a small round and think switching to Espree makes sense. However our bundler also needs to understand the new ES6 language features, which needs some more effort.

Related issues:

We added this topic to our internal backlog and keep you posted here.

@codeworrior
Copy link
Member

We should also consider to align with other parsers that we implicitly use. E.g. JSDoc now internally uses Babylon.

@matz3
Copy link
Member

matz3 commented Sep 16, 2020

We should also consider to align with other parsers that we implicitly use. E.g. JSDoc now internally uses Babylon.

babylon is now @babel/parser (see https://github.com/babel/babylon).

Terser does its own parsing, but supports input as SpiderMonkey AST.

@codeworrior
Copy link
Member

As far as I remember, the path via SpiderMonkey AST didn't work for all ES6ff features. That was the reason why we finally had to serialize modified ASTs again before handing them over as a string to Uglify. Whether Terser has improved here and the SpiderMonkey AST is fully functional again, I can't say.

During the work on PR SAP/ui5-builder#282, it was discussed whether we could switch to the Terser API, which unfortunately has a different representation of nodes. But I would prefer to stay with the SpiderMonkey AST format as it is more common.
(before you waste time with searching: the discussion did not happen in the PR itself, but on some other channel. As far as I can see, only the rewriting of sap.ui.define to sap.ui.predefine has been switched to the Terser AST APIs).

@RandomByte RandomByte transferred this issue from SAP/ui5-builder Nov 20, 2020
@RandomByte RandomByte added enhancement New feature or request module/ui5-builder Related to the UI5 Builder module labels Nov 20, 2020
@BenReim
Copy link

BenReim commented Nov 26, 2020

Very much looking forward to use optional chaining with future versions of the ui5-tooling. 🚀

@AbhijeetKankan
Copy link

any update on this, how to resolve this issue.

@EdwinBoos
Copy link

Im facing the same issues, are there any news to this problem?

codeworrior added a commit to SAP/ui5-builder that referenced this issue Jun 13, 2021
This is work in progress and can't be submitted as the used espree
version (8.0.0-beta) is not a release version and it requires a newer
NodeJS min version than the tooling.

espree 8.0.0-beta was chosen as it switches the default for the
ecmaVersion option from 5 (7.3.1) to latest.

Before submitting, it also should be decided whether all parsing code
should be routed through some helper utility, to simplify future updates
/ changes of the parser. At the same time, we should decide about the
use of the sourceType and the ecmaVersion options. Should we expose them
in ui5.yaml? Or should we rather leave that to the linting step?

Fixes SAP/ui5-tooling#354 .
codeworrior added a commit to SAP/ui5-builder that referenced this issue Jun 13, 2021
This is work in progress and can't be submitted as the used espree
version (8.0.0-beta) is not a release version and it requires a newer
NodeJS min version than the tooling.

espree 8.0.0-beta was chosen as it switches the default for the
ecmaVersion option from 5 (7.3.1) to latest.

Before submitting, it also should be decided whether all parsing code
should be routed through some helper utility, to simplify future updates
/ changes of the parser. At the same time, we should decide about the
use of the sourceType and the ecmaVersion options. Should we expose them
in ui5.yaml? Or should we rather leave that to the linting step?

Fixes SAP/ui5-tooling#354 .
@gregorwolf
Copy link
Contributor

Until there is a solution for this issue you can apply the workaround that @lemaiwo pointed me to: Use ui5-task-transpile. You can find a sample configuration at ui5-deploy.yaml.

codeworrior added a commit to SAP/ui5-builder that referenced this issue Jun 15, 2021
A new module lib/lbt/utils/parseJS is introduced that exposes a parseJS
function and a Syntax object with all AST node types. The new module is
used in all places where JavaSCript code is parsed (incl. tests).

The module uses espree v6 for parsing instead of esprima. This is the
maximum version that can be used without introducing breaking changes to
the tooling (higher versions of espree require higher node versions than
documented in our package.json).

The set of allowed parser options is limited to ease a later migration
to another parser.

Fixes SAP/ui5-tooling#354 .
RandomByte added a commit to SAP/ui5-builder that referenced this issue Jun 16, 2021
A new module lib/lbt/utils/parseUtils is introduced that exposes a parseJS
function and a Syntax object with all AST node types. The new module is
used in all places where JavaScript code is parsed (incl. tests).

The module uses espree v6 for parsing instead of esprima. This is the
maximum version that can be used without introducing breaking changes to
the tooling (higher versions of espree require higher node versions than
documented in our package.json).

The set of allowed parser options is limited to ease a later migration
to another parser.

Fixes SAP/ui5-tooling#354

Co-authored-by: Merlin Beutlberger <[email protected]>
@RandomByte
Copy link
Member

Reopening until a new release has been done. Probably tomorrow afternoon

@RandomByte RandomByte reopened this Jun 16, 2021
@RandomByte
Copy link
Member

We have switched parsers to Espree v6. We can't use any newer versions, because they require a higher version of Node.js than what UI5 Tooling currently supports.

This means some ES6 features are still not supported:

  • 75e80bc Update: support ?? operator, import.meta, and export * as ns
  • 872645c Update: support optional chaining
  • bd0a405 Update: support logical assignment and numeric separators

We will probably add support for those by upgrading Espree with the UI5 Tooling 3.0 release.

However, the "Unexpected token" error for spread operators reported in this issue is now resolved with UI5 CLI v2.11.2 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request module/ui5-builder Related to the UI5 Builder module
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants