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

Adopt ES6 class syntax #979

Merged
merged 15 commits into from
Jan 30, 2020
Merged

Adopt ES6 class syntax #979

merged 15 commits into from
Jan 30, 2020

Conversation

le0tan
Copy link
Contributor

@le0tan le0tan commented Jan 14, 2020

What is the purpose of this pull request? (put "X" next to an item, remove the rest)

• [X] Enhancement to an existing feature

What is the rationale for this request?

ES6 class syntax is more beginner-friendly, and clearer to read.

What changes did you make? (Give an overview)

  • Refactor Site.js, Page.js and parser.js with class keyword.
  • Extract out utility functions into separate files for better consistency.
  • Re-structure some part of the class for better data encapsulation.

Provide some example code that this change will affect:

na

Is there anything you'd like reviewers to focus on?

na

Testing instructions:

npm run test

Proposed commit message: (wrap lines at 72 characters)

Adopt ES6 class syntax for Site, Page and Parser

Refactor Site.js, Page.js and parser.js with class keyword.
Extract out utility functions into separate files for better
consistency.
Re-structure some part of the class for better data encapsulation.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 14, 2020

@yamgent help wanted: could you please explain a bit on what delay does and why can't we use setTimeout instead? I added TODOs in Site.js to indicate places where I removed delay to stop ESLint from complaining.

@acjh
Copy link
Contributor

acjh commented Jan 14, 2020

could you please explain a bit on what delay does and why can't we use setTimeout instead?

From the jsdoc of delay:

/**
* Creates a function that delays invoking `func` until after `wait` milliseconds have elapsed
* and the running `func` has resolved/rejected.

What delay does, which differs from setTimeout and debounce:

  • if func is not running, it accumulates the arguments of multiple calls of func into a single call that will be triggered wait milliseconds after the first call, and
  • if func is running, it accumulates the arguments of subsequent calls of func and queues a single call that will be triggered after the running call.

I find that quite powerful; it solves #155.

The original PR MarkBind/markbind-cli#31 contains the initial discussion.

I removed delay to stop ESLint from complaining.

What was ESLint complaining about?

@le0tan
Copy link
Contributor Author

le0tan commented Jan 14, 2020

Thanks for the explanation! That makes a lot of sense now.

What was ESLint complaining about?

If I write like rebuildAffectedSourceFiles = delay(this._rebuildAffectedSourceFiles, 1000);, ESLint will show

ESLint: Parsing error: Unexpected token =

as it expects the method to be a function.

@ang-zeyu
Copy link
Contributor

If I write like rebuildAffectedSourceFiles = delay(this._rebuildAffectedSourceFiles, 1000);, ESLint will show

ESLint: Parsing error: Unexpected token =

If this line was directly within the Site class, you could wrap it around, something like this

rebuildAffectedSourceFiles(arg) {
  const delayedFunc = delay(this._rebuildAffectedSourceFiles, 1000);

  return delayedFunc(arg);
}

ES6 classes don't allow 'assignments' inside the class template, I think

@openorclose
Copy link
Contributor

If I write like rebuildAffectedSourceFiles = delay(this._rebuildAffectedSourceFiles, 1000);, ESLint will show

ESLint: Parsing error: Unexpected token =

If this line was directly within the Site class, you could wrap it around, something like this

rebuildAffectedSourceFiles(arg) {
  const delayedFunc = delay(this._rebuildAffectedSourceFiles, 1000);

  return delayedFunc(arg);
}

ES6 classes don't allow 'assignments' inside the class template, I think

Well this is quite different as a new delayedFunc is created at each call of rebuildAffectedSourceFiles which is not we want.

Just retain the original

Site.prototype.rebuildAffectedSourceFiles	
  = delay(Site.prototype._rebuildAffectedSourceFiles, 1000);

after the class declaration for now?

Some time after this proposal is merged https://github.com/tc39/proposal-class-fields we can revisit this.

@ang-zeyu
Copy link
Contributor

Well this is quite different as a new delayedFunc is created at each call of rebuildAffectedSourceFiles which is not we want.

Just retain the original

Site.prototype.rebuildAffectedSourceFiles	
  = delay(Site.prototype._rebuildAffectedSourceFiles, 1000);

after the class declaration for now?

Some time after this proposal is merged https://github.com/tc39/proposal-class-fields we can revisit this.

My bad 😅 , good catch

Sounds good

@le0tan
Copy link
Contributor Author

le0tan commented Jan 14, 2020

It's also possible to use this solution, but it may complicate things, so I might as well stick to the prototype version for delay related functions?

@openorclose
Copy link
Contributor

Nah, that's not a solution since we're targeting ES6 which does not allow class properties.

Class properties aren't in any ES specification yet, so even though it works on node 12 it's possible that they take it out in a future version.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 15, 2020

If there's no rejection on adopting the ES6 class syntax I'll start working on refactoring other classes then =)

@yamgent
Copy link
Member

yamgent commented Jan 15, 2020

If there's no rejection on adopting the ES6 class syntax I'll start working on refactoring other classes then =)

Ok please go ahead. 👍

@le0tan le0tan changed the title [WIP] Adopt ES6 class syntax Adopt ES6 class syntax Jan 16, 2020
Copy link
Member

@yamgent yamgent left a comment

Choose a reason for hiding this comment

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

These comments applies to all the files:

src/lib/markbind/src/parser.js Outdated Show resolved Hide resolved
src/lib/markbind/src/parser.js Outdated Show resolved Hide resolved
src/lib/markbind/src/parser.js Outdated Show resolved Hide resolved
src/lib/markbind/src/parser.js Show resolved Hide resolved
@le0tan le0tan requested a review from yamgent January 16, 2020 14:20
Copy link
Contributor

@openorclose openorclose left a comment

Choose a reason for hiding this comment

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

Looks mostly okay, just minor syntax changes to ES6 classes and not much code changes.

src/Page.js Outdated Show resolved Hide resolved
src/Site.js Outdated Show resolved Hide resolved
- adopt ES6 syntax for unique(array)
- remove redundant Site method
Copy link
Member

@yamgent yamgent left a comment

Choose a reason for hiding this comment

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

I do realize that the blank lines are being removed as well. Were all the blank lines removed, or was it manually done to clean up unnecessary blank lines? Just wondering as functions in MarkBind are quite long, so those blank lines may aid in easier reading of the code.

const Promise = require('bluebird');
const url = require('url');
const pathIsInside = require('path-is-inside');
Copy link
Member

Choose a reason for hiding this comment

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

The imports should be in alphabetical order.

IMPORTED_VARIABLE_PREFIX,
BOILERPLATE_FOLDER_NAME,
Copy link
Member

Choose a reason for hiding this comment

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

Ideal to have the constants in alphabetical order too.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 18, 2020

I do realize that the blank lines are being removed as well. Were all the blank lines removed, or was it manually done to clean up unnecessary blank lines? Just wondering as functions in MarkBind are quite long, so those blank lines may aid in easier reading of the code.

ESLint will complain if there are more blank lines:

ESLint: More than 2 blank lines not allowed.(no-multiple-empty-lines)

I will try to document all functions for better readability in a future PR.

@yamgent
Copy link
Member

yamgent commented Jan 18, 2020

Btw GitHub is complaining about conflicting files, you will have to resolve it.

You can also squash the commits for this PR, we won't need the separate commits for now.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 21, 2020

@openorclose I reverted the global variables in parser.js. Can you take a look? I tested live reloading and it should work now.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 22, 2020

Btw GitHub is complaining about conflicting files, you will have to resolve it.

@ang-zeyu @yamgent I made my best effort to resolve the merge conflicts mostly introduced by #974, can you take a look if I broke anything? Thanks!

@le0tan le0tan requested a review from yamgent January 22, 2020 09:48
@ang-zeyu
Copy link
Contributor

@ang-zeyu @yamgent I made my best effort to resolve the merge conflicts mostly introduced by #974, can you take a look if I broke anything? Thanks!

LGTM, it shouldn't cause any issues with plugin live reloading if live reload already works. There's a few pumls at the bottom of the test site you can try editing to test plugin live reloading though

On another note I noticed you made quite a few style changes to existing method calls ( newlines between chained method calls ). Was this due to a conflict with an eslint rule from using classes? It might be better to make such changes in a seperate PR to make the diff easier to compare otherwise!

@yamgent
Copy link
Member

yamgent commented Jan 28, 2020

Sorry there's another merge conflict due to a recent merge of the big feature #944. Would need you to rebase again.

Once your PR is rebased and in order, I will prioritize your PR to be merged next.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 28, 2020

Sorry there's another merge conflict due to a recent merge of the big feature #944. Would need you to rebase again.

Once your PR is rebased and in order, I will prioritize your PR to be merged next.

@yamgent I (again) tried my best effort to merge this conflict... can @crphang do some quality assurance on this merge?

Copy link
Contributor

@crphang crphang left a comment

Choose a reason for hiding this comment

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

Very good work on the migration 🎉. LGTM in general, don't see any issues with resolution of merge conflicts.

const filePath = element.attribs[ATTRIB_INCLUDE_PATH];
const fileBase = calculateNewBaseUrls(filePath, config.rootPath, config.baseUrlMap);
if (!fileBase.relative) {
return pa
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't think it should be resolved in this PR, but can this be declared in the constructor?

What do you think @yamgent?

Copy link
Member

Choose a reason for hiding this comment

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

It will probably take a bit of work to move it to the constructor, since it is likely that the original author intentionally makes it globally scoped.

Copy link
Member

Choose a reason for hiding this comment

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

So yes let's leave it to another PR.

@yamgent yamgent force-pushed the es6-site-class branch 3 times, most recently from eb5d71e to ab17775 Compare January 30, 2020 02:29
@yamgent yamgent added this to the v2.10.0 milestone Jan 30, 2020
@yamgent yamgent merged commit af47ed0 into MarkBind:master Jan 30, 2020
Copy link
Contributor

@ang-zeyu ang-zeyu left a comment

Choose a reason for hiding this comment

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

A little late, but, I noticed there are quite a few strange newlines-after calls to $(...) that makes the code harder to read. Subjective in some cases, but rather awkward in others.

Should we keep to a minimum of three method calls before indenting with newlines? a().b().c()

this.keywords = {};
// Collect headings and keywords
this.collectHeadingsAndKeywordsInContent($(`#${CONTENT_WRAPPER_ID}`)
.html(), null, false, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

.

$('modal')
.remove();
$('panel')
.remove();
Copy link
Contributor

Choose a reason for hiding this comment

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

.

*/
linkKeywordToHeading($, keyword, heading) {
const headingId = $(heading)
.attr('id');
Copy link
Contributor

Choose a reason for hiding this comment

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

.

this.keywords[headingId] = [];
}
this.keywords[headingId].push($(keyword)
.text());
Copy link
Contributor

Choose a reason for hiding this comment

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

.

@le0tan
Copy link
Contributor Author

le0tan commented Jan 30, 2020 via email

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.

None yet

6 participants