Skip to content

Refactoring: better boundaries for different parts of the project#4364

Merged
duailibe merged 22 commits intoprettier:masterfrom
duailibe:refactor
Apr 25, 2018
Merged

Refactoring: better boundaries for different parts of the project#4364
duailibe merged 22 commits intoprettier:masterfrom
duailibe:refactor

Conversation

@duailibe
Copy link
Copy Markdown
Collaborator

@duailibe duailibe commented Apr 24, 2018

Analyzing our current build of the bin-prettier.js we distribute on NPM and after several tries of having a better build for web I've noticed our current graph of dependencies is quite a mess.

I've started a bit of refactoring here, gonna try summarize my rationale and what changed here:

  • we need to have core functionality independent of infrastructure. My rationale is: we can build another "entry" for prettier that knows how to load plugins (like in a web context, via importScripts) that would simply pass the loaded plugins to the core parts. So I've removed loadPlugins calls from main folder

  • our bin-prettier.js is basically index.js + stuff for CLI, but it also requires index.js meaning users end up loading a lot of code twice. ideally the CLI would always use the public API as well (in index.js) so I've removed some direct calls to getSupportInfo to go through prettier.getSupportInfo.

I need help from people (cc @ikatyang and @azz) to understand a few things we have I found a bit complicated:

  • what is the difference between main/options.js's normalize function and the normalizers in main/options-normalizers.js. Do we need 3 normalizers? How can we make this simpler? We could rename them too, because we have way too much normalizers in the code base 😂
  • I've noticed we have duplicated logic to log unknown options and suggest another option with leven in two different places (one for API and one for CLI) but one ends up also including the other in the final build. Is there a way to reuse them? Should make sense to extract the core.

This is still WIP, you guys think this is worth pursuing? I can also share my views for the web build if all of this don't make sense.

@ikatyang
Copy link
Copy Markdown
Member

  • what is the difference between main/options.js's normalize function and the normalizers in options-normalizer. How can we make them simpler?
  • options.js is a prettier-specific normalizer which uses options-*.js.
  • options-*.js could be a standalone package, I originally thought it'd be better there for maintainability reason, but now it seems extracting it would be better(?), what do you think?
  • I've noticed we have duplicated logic to log unknown options and suggest another option with leven in two different places (one for API and one for CLI) but one ends up also including the other in the final build. Is there a way to reuse them? Should make sense to extract the core.

There're actually 3 places (api options, cli options, and cli --help) where the first two are from options-normalizer, and the core is just a few lines:

const suggestedOptionInfo = optionInfos.find(
optionInfo => leven(optionInfo.name, key) < 3
);
if (suggestedOptionInfo) {
messages.push(`Did you mean ${JSON.stringify(suggestedOptionInfo.name)}?`);
}

This is still WIP, you guys think this is worth pursuing?

I guess this is what you mean:

  • core (no fs, web compatible, including format(), formatWithCursor())
  • api (require core and fs)
  • cli (require api and fs)
  • plugins (independent, web compatible)

👍

@duailibe
Copy link
Copy Markdown
Collaborator Author

@ikatyang yeah I think you explained it better than me 😂

  • options.js is a prettier-specific normalizer which uses options-*.js.
  • options-*.js could be a standalone package, I originally thought it'd be better there for maintainability reason, but now it seems extracting it would be better(?), what do you think?

Thank you for this! It helped me understand it better, but I'm still confused about what is options-normalizer.js responsibility.

@ikatyang
Copy link
Copy Markdown
Member

validate options, redirect deprecated options and apply default value.

@ikatyang
Copy link
Copy Markdown
Member

And yes, I'm not good at naming, so I just named it normalizer. 😂

Comment thread index.js Outdated
const printDocToDebug = doc.debug.printDocToDebug;

function withPlugins(opts) {
opts = Object.assign({}, opts);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This line is unnecessary.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It was not but I removed it anyway :)

@duailibe duailibe added the status:wip Pull requests that are a work in progress and should not be merged label Apr 24, 2018
Comment thread tests_config/run_spec.js Outdated
key === "parent" ||
key === "prev"
key === "prev" ||
key === "__location"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What do you think about replacing this with ["loc", "range", "raw", "comments", "parent", "prev", "__location"].indexOf(key) !== -1?

@duailibe
Copy link
Copy Markdown
Collaborator Author

duailibe commented Apr 24, 2018

@ikatyang I think there's still some complexity that could be simplified but I think this is already good enough to have a web entry point which is what I want to achieve =)

@duailibe duailibe removed the status:wip Pull requests that are a work in progress and should not be merged label Apr 24, 2018
@duailibe duailibe changed the title [RFC] Refactoring: better boundaries for different parts of the project Refactoring: better boundaries for different parts of the project Apr 24, 2018
Comment thread index.js
doc,

resolveConfig: config.resolveConfig,
resolveConfigFile: config.resolveConfigFile,
Copy link
Copy Markdown
Member

@ikatyang ikatyang Apr 25, 2018

Choose a reason for hiding this comment

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

We should also update api.md. (bf68797)

Comment thread jest.config.js Outdated
"<rootDir>/src/deprecated.js"
"<rootDir>/src/doc/doc-debug.js",
"<rootDir>/src/main/massage-ast.js",
"<rootDir>/src/main/deprecated.js"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

deprecated.js is removed.

Comment thread src/language-css/options.js Outdated
const jsOptions = require("../language-js/options");

// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
// format based on https://github.com/prettier/prettier/blob/master/src/core/options.js
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

core/options.js -> core/core-options.js

(I'm not sure why there's only one file in core/ but I guess that's just your first step.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I was hoping to find a better place for it actually.. gonna move it to main/

Comment thread src/language-graphql/options.js Outdated
const jsOptions = require("../language-js/options");

// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
// format based on https://github.com/prettier/prettier/blob/master/src/core/options.js
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

core-options.js

Comment thread src/language-js/options.js Outdated
const CATEGORY_JAVASCRIPT = "JavaScript";

// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
// format based on https://github.com/prettier/prettier/blob/master/src/core/options.js
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

core-options.js

Comment thread src/language-markdown/options.js Outdated
const CATEGORY_MARKDOWN = "Markdown";

// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
// format based on https://github.com/prettier/prettier/blob/master/src/core/options.js
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

core-options.js

@duailibe duailibe merged commit 67f1c48 into prettier:master Apr 25, 2018
@duailibe duailibe deleted the refactor branch April 25, 2018 16:29
@duailibe
Copy link
Copy Markdown
Collaborator Author

Let's hope for the best 🙏 😂

@lydell
Copy link
Copy Markdown
Member

lydell commented Apr 25, 2018

Thanks @duailibe ! 🎉

@lipis lipis added this to the 1.13 milestone May 9, 2018
@lock lock Bot added the locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting. label Aug 7, 2018
@lock lock Bot locked as resolved and limited conversation to collaborators Aug 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

locked-due-to-inactivity Please open a new issue and fill out the template instead of commenting.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants