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

Upgrade to prettier 3, run prettier separately, remove eslint-plugin-prettier #138

Closed
wants to merge 9 commits into from

Conversation

NullVoxPopuli
Copy link
Collaborator

@NullVoxPopuli NullVoxPopuli commented Jul 4, 2023

I haven't explained anything well in this PR, so I'm going to split it out:

previous description
previous blockers

Blocked by: #136
(due to the babel plugin rest spread issue #133 )

Blocked by : ember-cli/ember-cli#10334

This is no longer blocked because we can.. just emit files with no problems

Most of this PR is formatting / lint changes as a result of running :fix
Also lockfile,
image

tl;dr:

  • update prettier to v3 (otherwise prettier deletes gts files)
  • update prettier-plugin-ember-template-tag to 1.0.2
  • update the lint meta-package for compat with prettier v3 / prettier-as-a-separate-command
  • rename .prettierrc.js to .prettierrc.cjs (required by prettier v3)
  • format all tests/fixtures to match prettier expectations (because ember addon doesn't run lint:fix for us)
  • fix formatting in files/*/tsconfig.json
  • fix formatting in files/*/rollup.config.mjs
    • when TS is not present, the changes are no-ops -- it's just simpler for us to maintain this way.

We already have prettier config in the right place: https://github.com/embroider-build/addon-blueprint/blob/main/files/__addonLocation__/.prettierrc.cjs
But eslint-plugin-prettier doesn't work with eslint-plugin-ember until this is merged and released: ember-cli/eslint-plugin-ember#1920

Running prettier via eslint is way slower than running prettier separately, so I'd like to propose running it as a separate command for the addon.
(which we do via switching from eslint-plugin-prettier to eslint-config-prettier, which only disables the formatting rules in eslint that prettier is concerned with)

OF NOTE: To have things working with gjs/gts, I had to upgrade to prettier 3, the prettier-plugin-ember-template-tag plugin (post 1.0) is not compat with prettier < 3.

Also, I formatted all the fixtures so that prettier -c would pass during our lint checks in the tests.

I've been testing with

EMBER_CLI_PNPM=true npx ember-cli@beta addon test-addon -b ../OpenSource/emberjs/addon-blueprint/ --pnpm

history

When reviewing: #136 (comment)
I found out we don't run prettier anywhere in the default blueprint 😅

When running prettier in the addon,

  • we have a working prettier situation when using --addon-only
  • we have a working prettier situation when using the default / monorepo setup
  • if someone wants to run prettier from the root of their monorepo, nested configs do get picked up by prettier but my editor (neovim) doesn't respect nested configs -- vscode does tho -- so I need to figure out what's going on with my neovim setup

I think this approach to configuring prettier for the addon is good because:

  • we defer to the app blueprint for everything about the app, we (as a composite blueprint), don't know how it will want to lint itself, so deferring to each workspace via pnpm --filter '*' lint feels like a good thing.

If anyone has ideas about better options, I'm open to that, too
(in part, the approach in this PR is "what I'm used to", so I could be biased)


The first commit here is an error, which shows that adding lint:prettier and lint:prettier:fix are now running, showing that the addon did not pass prettier on a fresh addon/monorepo setup

The second commit sets up an ignore file so we don't run prettier on the compiled output / dist / etc

@NullVoxPopuli NullVoxPopuli changed the title Try prettier in the addon Run prettier separately, in the addon, without eslint-plugin-prettier Aug 8, 2023
files/.prettierignore Outdated Show resolved Hide resolved
@NullVoxPopuli NullVoxPopuli force-pushed the prettier-in-addon branch 2 times, most recently from 862b43b to 9ae5849 Compare August 10, 2023 11:49
@@ -15,7 +15,11 @@ export default {
plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
addon.publicEntrypoints(['components/**/*.js', 'index.js'<% if (typescript) {%>, 'template-registry.js'<% } %>]),
addon.publicEntrypoints([
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

important change -- no more typescript branches in rollup. there is no downside to having this stuff here

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure I agree with this change...

First, seems unrelated to the PR's primary purpose?

Then, I would find it confusing to see a file referenced that does not exist, and that does not even have any use (in a JS addon). Would be different if it were reference implicitly through some glob like *.js, but here we have an explicit reference to this specific file.

I'd rather have a bit of complexity on our side, than cause confusion to the user...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it's related in that we emit a prettier error in TS projects, but I think I can just wrap the whole line rather than have the typescript condition inline

@NullVoxPopuli NullVoxPopuli marked this pull request as ready for review August 14, 2023 13:52
@@ -0,0 +1,2 @@
/.eslintrc.cjs
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is needed because eslint-plugin-n warns us when we require from a dependency in a file that we ship to npm and that dependency is not declared in "dependencies".

@@ -1 +1,8 @@
tests/fixtures/
# Blueprint files
# We want the blueprint to run lint:fix on these
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The beginning of this is here: ember-cli/ember-cli#10334

For now, and what this PR mostly does is, we emit only already correct files. This is brittle over time (as is proven by the reason lint:fix got added to the app blueprint), but it'll get us unblocked in the short term.

@@ -0,0 +1,19 @@
'use strict';
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

file renamed from 'js' -- should not be "new"

@@ -38,7 +38,7 @@ module.exports = {
if (!options.addonOnly) {
if (fs.existsSync(path.join('..', 'package.json'))) {
options.ui.writeInfoLine(
"Existing monorepo detected! The blueprint will only create the addon and test-app folders, and omit any other files in the repo's root folder."
"Existing monorepo detected! The blueprint will only create the addon and test-app folders, and omit any other files in the repo's root folder.",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

in prettier 3, these trailing commas are default

import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import { execa, type Options } from 'execa';
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the lint meta-package groups all the node imports together, separate from external deps

Copy link
Collaborator

Choose a reason for hiding this comment

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

What exactly are you referring to as the "lint meta-package"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It'll be easier to see here (I just extracted this, in response to your comments): #175 (comment)

@NullVoxPopuli NullVoxPopuli changed the title Run prettier separately, in the addon, without eslint-plugin-prettier Upgrade to prettier 3, run prettier separately, remove eslint-plugin-prettier Aug 14, 2023
Copy link
Collaborator

@simonihmig simonihmig left a comment

Choose a reason for hiding this comment

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

Although you have a lot of text in your description (maybe due to this? 🙃), I am not quite getting what the primary intent of this PR is?

Is it "just" regular maintenance (upgrading prettier)? Or is upgrading the means to fix a real problem? Like what label are we going to apply to this PR (for the lerna-changelog), bug or enhancement? 😏

To have things working with gjs/gts, I had to upgrade to prettier 3, the prettier-plugin-ember-template-tag plugin (post 1.0) is not compat with prettier < 3.

This seems to refer to a problem we have. So do we have a problem? We already used prettier-plugin-ember-template-tag v1.0.0, which did work with prettier v2, didn't it? (e.g. like in https://github.com/CrowdStrike/ember-headless-form)

Running prettier via eslint is way slower than running prettier separately, so I'd like to propose running it as a separate command for the addon.

This is something I am a bit concerned, or need clarification...

First, on the performance issue, is this when letting prettier format things (which happens very frequently, but usually using prettier directly in your IDE rather then through eslint), or when "style-linting"? In the latter case, is the performance penalty really relevant (given you don't do this very frequently)? Any numbers?

Then, is splitting prettier from eslint a stop-gap solution which we will revert later (when ember-cli/eslint-plugin-ember#1920 is merged), or is this the way to go anyway? If the latter, is this aligned to what is happening in other blueprints (v1 addon and app)? Should we align? (I think we should)

@@ -15,7 +15,11 @@ export default {
plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
addon.publicEntrypoints(['components/**/*.js', 'index.js'<% if (typescript) {%>, 'template-registry.js'<% } %>]),
addon.publicEntrypoints([
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure I agree with this change...

First, seems unrelated to the PR's primary purpose?

Then, I would find it confusing to see a file referenced that does not exist, and that does not even have any use (in a JS addon). Would be different if it were reference implicitly through some glob like *.js, but here we have an explicit reference to this specific file.

I'd rather have a bit of complexity on our side, than cause confusion to the user...

@@ -34,7 +38,7 @@ export default {
// By default, this will load the actual babel config from the file
// babel.config.json.
babel({
extensions: ['.js', '.gjs'<% if (typescript) { %>, '.ts', '.gts'<% } %>],
extensions: ['.js', '.gjs', '.ts', '.gts'],
Copy link
Collaborator

Choose a reason for hiding this comment

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

similar to the above, but to a lesser degree. Still: what do we gain here?

@@ -3,12 +3,12 @@ import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('Rendering | template-only', function(hooks) {
module('Rendering | template-only', function (hooks) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Uh, having used JS for what? 25 years?, I will need to get used to this style change... 😅

import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

import { execa, type Options } from 'execa';
Copy link
Collaborator

Choose a reason for hiding this comment

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

What exactly are you referring to as the "lint meta-package"?

@NullVoxPopuli NullVoxPopuli mentioned this pull request Aug 16, 2023
@NullVoxPopuli
Copy link
Collaborator Author

I updated this PR's description with how I'm going to attempt to break things up in this PR: #138 (comment)

@NullVoxPopuli
Copy link
Collaborator Author

evidence here: https://github.com/embroider-build/addon-blueprint/actions/runs/5890531482/job/15975827606?pr=180#step:5:1475
From: #180

[fix:js] ESLint: 8.47.0
[fix:js] 
[fix:js] TypeError: prettier.resolveConfig.sync is not a function
[fix:js] Occurred while linting /tmp/v2-addon-blueprint--iOTzcu/my-addon/test-app/.eslintrc.js:1
[fix:js] Rule: \"prettier/prettier\"
[fix:js]     at Program (/tmp/v2-addon-blueprint--iOTzcu/my-addon/node_modules/eslint-plugin-prettier/eslint-plugin-prettier.js:138:40)
[fix:js]     at ruleErrorHandler (/tmp/v2-addon-blueprint--iOTzcu/my-addon/node_modules/eslint/lib/linter/linter.js:1050:28)
[fix:js]     at /tmp/v2-addon-blueprint--iOTzcu/my-addon/node_modules/eslint/lib/linter/safe-emitter.js:45:58

will try upgrading more prettier-related dependencies to see if that helps

@NullVoxPopuli
Copy link
Collaborator Author

First, on the performance issue, is this when letting prettier format things (which happens very frequently, but usually using prettier directly in your IDE rather then through eslint), or when "style-linting"? In the latter case, is the performance penalty really relevant (given you don't do this very frequently)? Any numbers?

It's only when ran through eslint -- eslint is significantly slower when it also runs prettier. A lot of people have their editors set up to format on save, or lint:fix/check their enitre monorepos, which can take more than a minute, and multiple minutes when prettier is integrated in to eslint.

@NullVoxPopuli
Copy link
Collaborator Author

Looks like upgrading dependencies fixed that error for yarn and pnpm, but npm -- #180 (comment)

@patricklx
Copy link

patricklx commented Aug 17, 2023

I like having prettier with eslint, as it reports the actual issues instead of just giving me the did you forget to run prettier?...
and I also sometimes do not want to checkout a project to make small changed. I like to edit code in the github editor :) and there I need to actual issues reported

@NullVoxPopuli
Copy link
Collaborator Author

NullVoxPopuli commented Aug 17, 2023

as it reports the actual issues instead of just giving me the did you forget to run prettier?

why do you need to know the issues?

I like to edit code in the github editor :) and there I need to actual issues reported

github editor integrates with linters?

in any case, if you know how to fix the problem with the npm tests in #180 that would be most helpful, because then we don't need to (or can delay) explore(ing) splitting out the commands

@NullVoxPopuli
Copy link
Collaborator Author

NullVoxPopuli commented Aug 17, 2023

I just witnessed another project using prettier 2 get their gts files deleted 😬

@simonihmig
Copy link
Collaborator

I just witnessed another project using prettier 2 get their gts files deleted

Do we have an explanation why this actually happens? Like I could understand that something makes prettier cause unwanted content changes, but delete the whole file?

@NullVoxPopuli
Copy link
Collaborator Author

NullVoxPopuli commented Aug 19, 2023

@patricklx could probably explain it better (but it's the trifecta of eslint-plugin-prettier, prettier 2, and prettier-plugin-ember-template-tag > 1.0.0)

The fix for prettier 2 (downgrading prettier-plugin-ember-template-tag to < v1) has been merged and released, and I have a separate set of PRs that upgrades to prettier 3 and removes eslint-plugin-prettier.

I think I want to discuss setting up turbo (no cache) tho... because the main downside to splitting up prettier from eslint is that eslint could run after prettier, and mess up prettier's formatting, so prettier needs to run after eslint, and that's best orchestrated via turbo.

Gonna close this PR for now

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

4 participants