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

Transpile theia to ES2017 #9436

Merged
merged 1 commit into from
Aug 25, 2021

Conversation

sgraband
Copy link
Contributor

@sgraband sgraband commented May 5, 2021

What it does

This is is a PR for transpiling Theia to ES2017. To continue supporting es5 based VSCode extensions, the @es5ClassCompat tag was used.

The tag was also applied to be used with Theia es5 plugins.

We would like to gather feedback while tackling the remaining issues, so feel free to comment on this PR!

Open issues:

  • The @es5ClassCompat tag is not working for all of the classes in types-impl.ts.
    The tag is failing on Location and DiagnosticRelatedInformation because of an Cannot access Location before its initialization error
    Applying the tag to CodeLens, TreeItem, ProgressExecution, ShellExecution and DebugAdapterExecutable will result in a Can't resolve @theia/plugin ERROR.
  • Test support for es5 Theia plugins.
  • In targeting es6 as a base (without transpiling to es5) #5902 it was mentioned that there could be issues with phosphorjs and inversifyjs, however we could not find any regressions while testing. This may need some further research.

Contributed on behalf of STMicroelectronics
Signed-off-by: Simon Graband sgraband@eclipsesource.com

How to test

To test the support for es5 VSCode extensions, you can try out one of the extensions described here: microsoft/vscode#68698.

Review checklist

Reminder for reviewers

@paul-marechal paul-marechal self-requested a review May 6, 2021 16:43
@paul-marechal
Copy link
Member

@sgraband feel free to use the following commit to address the issues you were mentioning with es5ClassCompat.

The Cannot access Location before its initialization error was due to how code generation works for decorators and bad ordering.

The Can't resolve @theia/plugin error was due to TypeScript thinking it needed to emit a require call when it did not.

@paul-marechal
Copy link
Member

Also, what about the following configuration?

{
test: /\\.js$/,
// include only es6 dependencies to transpile them to es5 classes
include: /vscode-ws-jsonrpc|vscode-jsonrpc|vscode-languageserver-protocol|vscode-languageserver-types/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
// reuse runtime babel lib instead of generating it in each js file
'@babel/plugin-transform-runtime',
// ensure that classes are transpiled
'@babel/plugin-transform-classes'
],
// see https://github.com/babel/babel/issues/8900#issuecomment-431240426
sourceType: 'unambiguous',
cacheDirectory: true
}
}
}

It transpiles some ES6 dependencies down to ES5, but those should no longer be required right?

@sgraband
Copy link
Contributor Author

I tested the support for es5 theia plugins. It is working as intended. I noticed that it is enough to apply the @es5ClassCompat tag in types-impl.ts, so i removed it from theia.d.ts.

@paul-marechal could you do a final review please? I will set this PR as ready for review.

@sgraband sgraband marked this pull request as ready for review June 21, 2021 13:41
@paul-marechal
Copy link
Member

I noticed a couple of classes not decorated by es5ClassCompat, is this intended? When should we use the decorator?

export class FileDecoration {

export class ProgressOptions {

export class Progress<T> {

export class CustomExecution {

export class CallHierarchyItem {

export class CallHierarchyIncomingCall {

export class CallHierarchyOutgoingCall {

export class SemanticTokensLegend {

}
export class SemanticTokensBuilder {

export class SemanticTokens {

export class SemanticTokensEdit {

export class SemanticTokensEdits {

@sgraband
Copy link
Contributor Author

Good Catch! They were missing because these classes are not part of the vscode API, which i looked at first. However, it is probably a good idea to decorate all the classes to ensure compatibility with plugins, that use the theia specific classes. I pushed my changes (which should also solve the build issues).

@sgraband
Copy link
Contributor Author

sgraband commented Jul 1, 2021

Rebased to master and added entry to changelog.

@paul-marechal
Copy link
Member

paul-marechal commented Jul 6, 2021

CI is red, please fix :)

@sgraband sgraband force-pushed the es6-migration branch 2 times, most recently from 776b81b to 200b7e4 Compare July 6, 2021 07:27
@paul-marechal
Copy link
Member

CI is still failing. Feel free to ask a committer that would be in your timezone to approve and run the CI for you in order to make the feedback loop shorter, or run the tests locally before pushing.

@sgraband sgraband force-pushed the es6-migration branch 2 times, most recently from b64ecb9 to 5e5f6e1 Compare July 7, 2021 10:15
@sgraband
Copy link
Contributor Author

sgraband commented Jul 7, 2021

I fixed the error in the CI. The error that is currently happening seems to be unrelated to my changes, as the master build has the same error.

@paul-marechal
Copy link
Member

I've been looking at the generated ES6 code and it looks mostly good!

I am only slightly bothered by the output for async functions. When targeting ES6, TypeScript will output things like:

// source
async function test() {
    await 1
}
// generated ES6 (ES2015)
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
function test() {
    return __awaiter(this, void 0, void 0, function* () {
        yield 1;
    });
}

We currently target Node 12.14.1 which supports at least ES2017 and native async/await notation. Since we share the same configuration between backend and frontend it means outputting native async/await would have to be supported in browsers to.

Using ES2017 gives:

// generated ES2017
"use-strict";
async function test() {
    await 1;
}

Thankfully it looks like most browsers/users support this: https://caniuse.com/async-functions

We also already expect the browser to support WebAssembly which is supposedly "newer" than async/await support:

I think we should at least target ES2017. The biggest breaking change happened when new style classes got introduced. Since then most things look backward-compatible.

Copy link
Member

@paul-marechal paul-marechal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! @eclipse-theia/core?

Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as well. Couldn't notice any regression on browser or electron (Ubuntu+Windows).

CHANGELOG.md Outdated
@@ -15,6 +15,7 @@
- [core] added support for `resourceDirName` and `resourcePath` context keys [#9499](https://github.com/eclipse-theia/theia/pull/9499)
- [core] added support for a unique id for non-command toolbar items [#9586](https://github.com/eclipse-theia/theia/pull/9586)
- [core] fixed incorrectly wrapped disposable [#9376](https://github.com/eclipse-theia/theia/pull/9376)
- [core] transpile theia to es6 [#9436](https://github.com/eclipse-theia/theia/pull/9436) - Contributed on behalf of STMicroelectronics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: As 1.15 was released last month, this should probably be removed.

@tsmaeder
Copy link
Contributor

I'm just wondering what the impact of the change on adopters will be. Will they have to update their build story as well? Maybe a good topic for the community call.

@sgraband
Copy link
Contributor Author

@tsmaeder we tested this with a theia template from the yeoman generator and there is no need for adopters to change their build story. If for some reason they still need an es5 codebase they should be able to transpile back to es5 using webpack. I am not quite sure if this is really a use case and if we should add this to the breaking changes section in the changelog?

@paul-marechal
Copy link
Member

if we should add this to the breaking changes section in the changelog?

Yes. As I mentioned in the dev meeting last week, we use some es5ClassCompat decorator for plugin classes but not for Theia API classes. So we should at least mention that we moved from ES5 to ES2017 as a (potential) breaking change.

CHANGELOG.md Outdated
@@ -56,6 +56,7 @@
<a name="breaking_changes_1.16.0">[Breaking Changes:](#breaking_changes_1.16.0)</a>

- [callhierarchy] `CurrentEditorAccess` is deprecated. Use the version implemented in the `editor` package instead. The services in `call-hierarchy` that previously used the local `CurrentEditorAccess` no longer do [#9681](https://github.com/eclipse-theia/theia/pull/9681)
- [core] moved from ES5 to ES2017 [#9436](https://github.com/eclipse-theia/theia/pull/9436) - Contributed on behalf of STMicroelectronics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be placed under 1.17.0 breaking changes now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have a migration guide, how about adding a section on what adopters will have to do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I placed the changelog entry in the 1.17.0 breaking changes. However, i am not sure what you mean with the migration guide? Should i add more information to the changelog? If yes, what information would you expect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tsmaeder @sgraband the migration guide is not yet merged, we can update it after if necessary:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sgraband you forgot to remove the old entry under 1.16.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the old changelog entry.

@sgraband sgraband changed the title Transpile theia to es6 Transpile theia to ES2017 Aug 3, 2021
@sgraband sgraband force-pushed the es6-migration branch 3 times, most recently from 4d283b8 to d036518 Compare August 9, 2021 11:14
@sgraband
Copy link
Contributor Author

sgraband commented Aug 9, 2021

I added an entry to the migration guide and rebased to master.

Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes look good to me, I did not notice any regressions when testing (verified inversify and phosphor as well) 👍

doc/Migration.md Outdated Show resolved Hide resolved
@sgraband
Copy link
Contributor Author

Is there anything else to do? Or can this be merged?

@paul-marechal
Copy link
Member

Let's bring that up during the dev meeting tomorrow and merge after that if there's no objections.

@paul-marechal
Copy link
Member

@sgraband can you rebase? If CI is green after that and you don't notice anything while running then I think it is fine to merge!

Transpiles theia to ES2017. To keep support of es5 based vscode extensions, the @es5ClassCompat tag was used. The tag was also applied to be used with theia es5 plugins.

Contributed on behalf of STMicroelectronics
Signed-off-by: Simon Graband <sgraband@eclipsesource.com>

Co-authored-by: Paul Maréchal <paul.marechal@ericsson.com>
@sgraband
Copy link
Contributor Author

I rebased and could not find any regressions. Could someone approve the workflow?

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

Successfully merging this pull request may close these issues.

5 participants