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

Autoformat duplicates import line on saving #360

Closed
4 tasks done
zamrokk opened this issue Dec 6, 2023 · 22 comments
Closed
4 tasks done

Autoformat duplicates import line on saving #360

zamrokk opened this issue Dec 6, 2023 · 22 comments
Labels
🗄 area/interface This affects the public interface 💪 phase/solved Post is done 👶 semver/patch This is a backwards-compatible fix 🐛 type/bug This is a problem

Comments

@zamrokk
Copy link

zamrokk commented Dec 6, 2023

Initial checklist

Affected packages and versions

@mdx-js/[email protected]

Link to runnable example

No response

Steps to reproduce

  1. use Vscode with Format on Save feature
  2. Save any file with some imports at the beginning
  3. It duplicates an import and break the CI I have with vercel later

image

Expected behavior

Do not duplicate the import

Actual behavior

it duplicates it

Runtime

No response

Package manager

No response

OS

No response

Build and bundle tools

No response

@zamrokk
Copy link
Author

zamrokk commented Dec 6, 2023

I noticed that the bug is coming from the extension

image

@ChristianMurphy ChristianMurphy transferred this issue from mdx-js/mdx Dec 6, 2023
@github-actions github-actions bot added 👋 phase/new Post is being triaged automatically 🤞 phase/open Post is being triaged manually and removed 👋 phase/new Post is being triaged automatically labels Dec 6, 2023
@remcohaszing
Copy link
Member

Can you post contents of an MDX file where this issue occurs?

@zamrokk
Copy link
Author

zamrokk commented Dec 6, 2023

`---
title: Tutorials

These tutorials can help you get started developing different kinds of applications on Tezos in as little as 15 minutes.

import TutorialCard from "@site/src/components/TutorialCard";
import TutorialCardContainer from "@site/src/components/TutorialCardContainer";

Beginner

These tutorials are intended for developers who are starting work with Tezos:

Intermediate

These tutorials contain multiple parts and are intended for developers with some application development experience:

Advanced

These tutorials are intended for developers who are familiar with Tezos and want to get into more powerful applications:

`

@zamrokk
Copy link
Author

zamrokk commented Dec 6, 2023

.mdx file extension is not allowed for upload :'(

Do you prefer on .txt ?

@zamrokk
Copy link
Author

zamrokk commented Dec 6, 2023

You can try with maybe a simpler case

Here is the JSX component as example

image

@wooorm
Copy link
Member

wooorm commented Dec 6, 2023

Please put the smallest reproduction in a code block. Thanks!

@remcohaszing
Copy link
Member

You can post code blocks on GitHub using tripe backticks as a code fence, like so:

```mdx
import 'hello'

# Hello from MDX
```

@remcohaszing
Copy link
Member

Based on your example, I am unable to reproduce the issue you’re describing. Are you sure it’s related to vscode-mdx, and not for example the ESLint integration?

@zamrokk
Copy link
Author

zamrokk commented Dec 7, 2023

If I use the MDX extension in VsCode + ```mdx at the beginning of the mdx file, it is ok

If I do not use the MDX extension , it is ok

If I use the MDX extension but not ```mdx it is ko

@zamrokk
Copy link
Author

zamrokk commented Dec 7, 2023

if I do manually Format with :

  • prettier : no issue
  • MDX : no issue

It is when I save the file ... I have autoformatting on save . I don't know who cause the import duplication on the chain of execution o.O

@zamrokk
Copy link
Author

zamrokk commented Dec 7, 2023

Is it a good practice to prefix all mdx files with ```mdx ?

@zamrokk
Copy link
Author

zamrokk commented Dec 7, 2023

This is the output log when I save the file (if it helps)

["INFO" - 4:22:02 PM] Formatting file:///home/zamrokk/tezos-developer-docs/docs/tutorials.mdx
["INFO" - 4:22:02 PM] PrettierInstance:
{
  "doc": {
    "builders": {
      "line": {
        "type": "line"
      },
      "softline": {
        "type": "line",
        "soft": true
      },
      "hardline": {
        "type": "concat",
        "parts": [
          {
            "type": "line",
            "hard": true
          },
          {
            "type": "break-parent"
          }
        ]
      },
      "literalline": {
        "type": "concat",
        "parts": [
          {
            "type": "line",
            "hard": true,
            "literal": true
          },
          {
            "type": "break-parent"
          }
        ]
      },
      "lineSuffixBoundary": {
        "type": "line-suffix-boundary"
      },
      "cursor": {
        "type": "cursor"
      },
      "breakParent": {
        "type": "break-parent"
      },
      "trim": {
        "type": "trim"
      },
      "hardlineWithoutBreakParent": {
        "type": "line",
        "hard": true
      },
      "literallineWithoutBreakParent": {
        "type": "line",
        "hard": true,
        "literal": true
      }
    },
    "printer": {},
    "utils": {},
    "debug": {}
  },
  "version": "2.8.8",
  "util": {},
  "__internal": {
    "errors": {},
    "coreOptions": {
      "CATEGORY_CONFIG": "Config",
      "CATEGORY_EDITOR": "Editor",
      "CATEGORY_FORMAT": "Format",
      "CATEGORY_OTHER": "Other",
      "CATEGORY_OUTPUT": "Output",
      "CATEGORY_GLOBAL": "Global",
      "CATEGORY_SPECIAL": "Special",
      "options": {
        "cursorOffset": {
          "since": "1.4.0",
          "category": "Special",
          "type": "int",
          "default": -1,
          "range": {
            "start": -1,
            "end": null,
            "step": 1
          },
          "description": "Print (to stderr) where a cursor at the given position would move to after formatting.\nThis option cannot be used with --range-start and --range-end.",
          "cliCategory": "Editor"
        },
        "endOfLine": {
          "since": "1.15.0",
          "category": "Global",
          "type": "choice",
          "default": [
            {
              "since": "1.15.0",
              "value": "auto"
            },
            {
              "since": "2.0.0",
              "value": "lf"
            }
          ],
          "description": "Which end of line characters to apply.",
          "choices": [
            {
              "value": "lf",
              "description": "Line Feed only (\\n), common on Linux and macOS as well as inside git repos"
            },
            {
              "value": "crlf",
              "description": "Carriage Return + Line Feed characters (\\r\\n), common on Windows"
            },
            {
              "value": "cr",
              "description": "Carriage Return character only (\\r), used very rarely"
            },
            {
              "value": "auto",
              "description": "Maintain existing\n(mixed values within one file are normalised by looking at what's used after the first line)"
            }
          ]
        },
        "filepath": {
          "since": "1.4.0",
          "category": "Special",
          "type": "path",
          "description": "Specify the input filepath. This will be used to do parser inference.",
          "cliName": "stdin-filepath",
          "cliCategory": "Other",
          "cliDescription": "Path to the file to pretend that stdin comes from."
        },
        "insertPragma": {
          "since": "1.8.0",
          "category": "Special",
          "type": "boolean",
          "default": false,
          "description": "Insert @format pragma into file's first docblock comment.",
          "cliCategory": "Other"
        },
        "parser": {
          "since": "0.0.10",
          "category": "Global",
          "type": "choice",
          "default": [
            {
              "since": "0.0.10",
              "value": "babylon"
            },
            {
              "since": "1.13.0"
            }
          ],
          "description": "Which parser to use.",
          "choices": [
            {
              "value": "flow",
              "description": "Flow"
            },
            {
              "value": "babel",
              "since": "1.16.0",
              "description": "JavaScript"
            },
            {
              "value": "babel-flow",
              "since": "1.16.0",
              "description": "Flow"
            },
            {
              "value": "babel-ts",
              "since": "2.0.0",
              "description": "TypeScript"
            },
            {
              "value": "typescript",
              "since": "1.4.0",
              "description": "TypeScript"
            },
            {
              "value": "acorn",
              "since": "2.6.0",
              "description": "JavaScript"
            },
            {
              "value": "espree",
              "since": "2.2.0",
              "description": "JavaScript"
            },
            {
              "value": "meriyah",
              "since": "2.2.0",
              "description": "JavaScript"
            },
            {
              "value": "css",
              "since": "1.7.1",
              "description": "CSS"
            },
            {
              "value": "less",
              "since": "1.7.1",
              "description": "Less"
            },
            {
              "value": "scss",
              "since": "1.7.1",
              "description": "SCSS"
            },
            {
              "value": "json",
              "since": "1.5.0",
              "description": "JSON"
            },
            {
              "value": "json5",
              "since": "1.13.0",
              "description": "JSON5"
            },
            {
              "value": "json-stringify",
              "since": "1.13.0",
              "description": "JSON.stringify"
            },
            {
              "value": "graphql",
              "since": "1.5.0",
              "description": "GraphQL"
            },
            {
              "value": "markdown",
              "since": "1.8.0",
              "description": "Markdown"
            },
            {
              "value": "mdx",
              "since": "1.15.0",
              "description": "MDX"
            },
            {
              "value": "vue",
              "since": "1.10.0",
              "description": "Vue"
            },
            {
              "value": "yaml",
              "since": "1.14.0",
              "description": "YAML"
            },
            {
              "value": "glimmer",
              "since": "2.3.0",
              "description": "Ember / Handlebars"
            },
            {
              "value": "html",
              "since": "1.15.0",
              "description": "HTML"
            },
            {
              "value": "angular",
              "since": "1.15.0",
              "description": "Angular"
            },
            {
              "value": "lwc",
              "since": "1.17.0",
              "description": "Lightning Web Components"
            }
          ]
        },
        "plugins": {
          "since": "1.10.0",
          "type": "path",
          "array": true,
          "default": [
            {
              "value": []
            }
          ],
          "category": "Global",
          "description": "Add a plugin. Multiple plugins can be passed as separate `--plugin`s.",
          "cliName": "plugin",
          "cliCategory": "Config"
        },
        "pluginSearchDirs": {
          "since": "1.13.0",
          "type": "path",
          "array": true,
          "default": [
            {
              "value": []
            }
          ],
          "category": "Global",
          "description": "Custom directory that contains prettier plugins in node_modules subdirectory.\nOverrides default behavior when plugins are searched relatively to the location of Prettier.\nMultiple values are accepted.",
          "cliName": "plugin-search-dir",
          "cliCategory": "Config"
        },
        "printWidth": {
          "since": "0.0.0",
          "category": "Global",
          "type": "int",
          "default": 80,
          "description": "The line length where Prettier will try wrap.",
          "range": {
            "start": 0,
            "end": null,
            "step": 1
          }
        },
        "rangeEnd": {
          "since": "1.4.0",
          "category": "Special",
          "type": "int",
          "default": null,
          "range": {
            "start": 0,
            "end": null,
            "step": 1
          },
          "description": "Format code ending at a given character offset (exclusive).\nThe range will extend forwards to the end of the selected statement.\nThis option cannot be used with --cursor-offset.",
          "cliCategory": "Editor"
        },
        "rangeStart": {
          "since": "1.4.0",
          "category": "Special",
          "type": "int",
          "default": 0,
          "range": {
            "start": 0,
            "end": null,
            "step": 1
          },
          "description": "Format code starting at a given character offset.\nThe range will extend backwards to the start of the first line containing the selected statement.\nThis option cannot be used with --cursor-offset.",
          "cliCategory": "Editor"
        },
        "requirePragma": {
          "since": "1.7.0",
          "category": "Special",
          "type": "boolean",
          "default": false,
          "description": "Require either '@prettier' or '@format' to be present in the file's first docblock comment\nin order for it to be formatted.",
          "cliCategory": "Other"
        },
        "tabWidth": {
          "type": "int",
          "category": "Global",
          "default": 2,
          "description": "Number of spaces per indentation level.",
          "range": {
            "start": 0,
            "end": null,
            "step": 1
          }
        },
        "useTabs": {
          "since": "1.0.0",
          "category": "Global",
          "type": "boolean",
          "default": false,
          "description": "Indent with tabs instead of spaces."
        },
        "embeddedLanguageFormatting": {
          "since": "2.1.0",
          "category": "Global",
          "type": "choice",
          "default": [
            {
              "since": "2.1.0",
              "value": "auto"
            }
          ],
          "description": "Control how Prettier formats quoted code embedded in the file.",
          "choices": [
            {
              "value": "auto",
              "description": "Format embedded code if Prettier can automatically identify it."
            },
            {
              "value": "off",
              "description": "Never automatically format embedded code."
            }
          ]
        }
      }
    },
    "optionsModule": {
      "hiddenDefaults": {
        "astFormat": "estree",
        "printer": {},
        "locStart": null,
        "locEnd": null
      }
    },
    "optionsNormalizer": {},
    "utils": {}
  },
  "__debug": {}
}
["INFO" - 4:22:02 PM] Using ignore file (if present) at /home/zamrokk/tezos-developer-docs/.prettierignore
["INFO" - 4:22:02 PM] File Info:
{
  "ignored": false,
  "inferredParser": "mdx"
}
["INFO" - 4:22:02 PM] No local configuration (i.e. .prettierrc or .editorconfig) detected, falling back to VS Code configuration
["INFO" - 4:22:02 PM] Prettier Options:
{
  "arrowParens": "always",
  "bracketSpacing": true,
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "singleAttributePerLine": false,
  "bracketSameLine": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "preserve",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "useTabs": false,
  "embeddedLanguageFormatting": "auto",
  "vueIndentScriptAndStyle": false,
  "filepath": "/home/zamrokk/tezos-developer-docs/docs/tutorials.mdx",
  "parser": "mdx"
}
["INFO" - 4:22:02 PM] Formatting completed in 43ms.

@RobbyRabbitman

This comment was marked as spam.

@coryetzkorn
Copy link

This is also happening to me.

<PostVideo> is getting duplicated when format-on-save runs (via the VSCode MDX extension).

I'm also using frontmatter, so that might be part of it. Other MDX files in my project work tho. Something weird about this file.

---
title: Building Products People Love
subtitle: A look into product and design thinking at Notion.
date: 2020-05-19
tags: design, speaking, video
thumbnail: building-products-people-love.png
---

import PostImage from "@components/PostImage"
import PostVideo from "@components/PostVideo"
import PostVideo from "@components/PostVideo"

<PostImage
  src="building-products-people-love.png"
  alt="Build products people love"
/>

Building a product people love requires more than simply shipping features. It’s important to have a mission people believe in, an original brand, and an approach to product that always puts user needs first.

Thanks so much to the folks at Samsung NEXT for inviting me to speak in these crazy COVID-19 times!

<PostVideo id="EDRRwnwxMwU" />

@mathias-falkenberg
Copy link

Same issue here, even if I switch off ESLint and Prettier. However, if I set "mdx.server.enable": false, the issue disappears.

Could this issue have something to do with that setting now being true by default?

@remcohaszing
Copy link
Member

This isn’t related to formatting. I managed to reproduce this issue using the following VS Code settings:

{
  "[mdx]": {
    "editor.codeActionsOnSave": {
      "source.organizeImports": "always"
    }
  }
}

The issue is gone when using the latest unreleased changes. I’m not sure what fixed this, but it’s fixed in the next release.

This comment has been minimized.

@remcohaszing remcohaszing added 🐛 type/bug This is a problem 🗄 area/interface This affects the public interface 👶 semver/patch This is a backwards-compatible fix 💪 phase/solved Post is done labels Dec 14, 2023
@github-actions github-actions bot removed the 🤞 phase/open Post is being triaged manually label Dec 14, 2023
@mathias-falkenberg
Copy link

I'm still seeing this issue even with version 1.7.0 of the VScode MDX extension.

Toggling organize imports off will remove the error, but must be considered a workaround

"[mdx]": {
  "editor.codeActionsOnSave": {
    "source.organizeImports": "never"
  }
}

@vicary
Copy link

vicary commented Apr 8, 2024

I am using v1.8.3 and the issue still exists. The codebase is tailwind's Protocol template, you may test with the attached source file page.mdx.

Choosing Organize Imports from the command palette triggers the bug, appending all imports at the end of file.

@remcohaszing sorry to bother, but shall we open a new issue or reopen this one?

@remcohaszing
Copy link
Member

@vicary I’m not seeing this with the file you provided. Please provide an example repository with steps to reproduce.

@nikitaeverywhere
Copy link

nikitaeverywhere commented Jul 18, 2024

Encountered this problem and @remcohaszing's workaround solved it for my case.

It happens when you import multiple things from something, like

import { PageSection } from '@my/ui';

works, but

import { PageSection, LinkExternal } from '@my/ui';

not and begins to insert the same imports at the end of the file on save.

@Merieli
Copy link

Merieli commented Oct 31, 2024

The same thing happened to me, @mathias-falkenberg solution solved it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗄 area/interface This affects the public interface 💪 phase/solved Post is done 👶 semver/patch This is a backwards-compatible fix 🐛 type/bug This is a problem
Development

No branches or pull requests

9 participants