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

feat!: experimentally support remark-mdx@2 #284

Merged
merged 6 commits into from Mar 28, 2022
Merged

feat!: experimentally support remark-mdx@2 #284

merged 6 commits into from Mar 28, 2022

Conversation

JounQin
Copy link
Member

@JounQin JounQin commented Mar 15, 2021

Thanks to synckit, we can use ESM before ESLint

close #204, close #338, close #366, close #356, close #367, close #371

@JounQin JounQin requested a review from wooorm March 15, 2021 18:05
@JounQin
Copy link
Member Author

JounQin commented Mar 15, 2021

@wooorm All standard es features are working as expected, but jsx nodes are not passed as estree like format, it that possible to parse it by enabling acorn-jsx? This makes all jsx related rules unusable.

@wooorm
Copy link
Member

wooorm commented Mar 15, 2021

I'm on a phone right now (sorry, can't release, will soon)

But you need something along the lines of https://github.com/wooorm/xdm/blob/main/lib/core.js#L67, up until (including) rehype-recma, if you want an estree. That's what you want, right?!

@JounQin
Copy link
Member Author

JounQin commented Mar 15, 2021

@wooorm I tried like following, but it seems not working.

export const mdProcessor = unified().use(remarkParse).freeze()

export const getEsLintMdxProcessor = (tokens: AST.Token[]) =>
  mdProcessor()
    .use(
      remarkMdx,
      // FIXME: wrong typing of `remark-mdx`
      // @ts-ignore
      {
        acornOptions: {
          locations: true,
          ranges: true,
          onToken: tokens,
        },
      },
    )
    .use(remarkMarkAndUnravel)
    .use(remarkRehype, {
      allowDangerousHtml: true,
      passThrough: MDX_NODE_TYPES as any,
    })
    .use(() => toEstree)
    .freeze()
import { Basic } from './basic'

<Basic></Basic>
[
  {
    "type": "ImportDeclaration",
    "start": 0,
    "end": 31,
    "loc": {
      "start": {
        "line": 1,
        "column": 0
      },
      "end": {
        "line": 1,
        "column": 31
      }
    },
    "range": [
      0,
      31
    ],
    "specifiers": [
      {
        "type": "ImportSpecifier",
        "start": 9,
        "end": 14,
        "loc": {
          "start": {
            "line": 1,
            "column": 9
          },
          "end": {
            "line": 1,
            "column": 14
          }
        },
        "range": [
          9,
          14
        ],
        "imported": {
          "type": "Identifier",
          "start": 9,
          "end": 14,
          "loc": {
            "start": {
              "line": 1,
              "column": 9
            },
            "end": {
              "line": 1,
              "column": 14
            }
          },
          "range": [
            9,
            14
          ],
          "name": "Basic"
        },
        "local": {
          "type": "Identifier",
          "start": 9,
          "end": 14,
          "loc": {
            "start": {
              "line": 1,
              "column": 9
            },
            "end": {
              "line": 1,
              "column": 14
            }
          },
          "range": [
            9,
            14
          ],
          "name": "Basic"
        }
      }
    ],
    "source": {
      "type": "Literal",
      "start": 22,
      "end": 31,
      "loc": {
        "start": {
          "line": 1,
          "column": 22
        },
        "end": {
          "line": 1,
          "column": 31
        }
      },
      "range": [
        22,
        31
      ],
      "value": "./basic",
      "raw": "'./basic'"
    }
  }
]

@JounQin
Copy link
Member Author

JounQin commented Mar 15, 2021

And it seems remarkRehype is used to transform markdown to html, but I just want jsx to be parsed as final estree. Maybe I need to use handlers.

@wooorm
Copy link
Member

wooorm commented Mar 15, 2021

Here's an explanation of the steps: https://github.com/wooorm/xdm#architecture. You first need to go from mdast -> hast, before being able to go hast -> estree

@JounQin
Copy link
Member Author

JounQin commented Mar 15, 2021

Here's an explanation of the steps: wooorm/xdm#architecture. You first need to go from mdast -> hast, before being able to go hast -> estree

Maybe I understand it, but is there any wrong thing at #284 (comment)?

  
{
  "type": "root",
  "children": [
    {
      "type": "mdxjsEsm",
      "value": "import { Basic } from './basic'",
      "position": {
        "start": {
          "line": 1,
          "column": 1,
          "offset": 0
        },
        "end": {
          "line": 1,
          "column": 32,
          "offset": 31
        }
      },
      "data": {
        "estree": {
          "type": "Program",
          "start": 0,
          "end": 31,
          "loc": {
            "start": {
              "line": 1,
              "column": 0
            },
            "end": {
              "line": 1,
              "column": 31
            }
          },
          "range": [
            0,
            31
          ],
          "body": [
            {
              "type": "ImportDeclaration",
              "start": 0,
              "end": 31,
              "loc": {
                "start": {
                  "line": 1,
                  "column": 0
                },
                "end": {
                  "line": 1,
                  "column": 31
                }
              },
              "range": [
                0,
                31
              ],
              "specifiers": [
                {
                  "type": "ImportSpecifier",
                  "start": 9,
                  "end": 14,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 9
                    },
                    "end": {
                      "line": 1,
                      "column": 14
                    }
                  },
                  "range": [
                    9,
                    14
                  ],
                  "imported": {
                    "type": "Identifier",
                    "start": 9,
                    "end": 14,
                    "loc": {
                      "start": {
                        "line": 1,
                        "column": 9
                      },
                      "end": {
                        "line": 1,
                        "column": 14
                      }
                    },
                    "range": [
                      9,
                      14
                    ],
                    "name": "Basic"
                  },
                  "local": {
                    "type": "Identifier",
                    "start": 9,
                    "end": 14,
                    "loc": {
                      "start": {
                        "line": 1,
                        "column": 9
                      },
                      "end": {
                        "line": 1,
                        "column": 14
                      }
                    },
                    "range": [
                      9,
                      14
                    ],
                    "name": "Basic"
                  }
                }
              ],
              "source": {
                "type": "Literal",
                "start": 22,
                "end": 31,
                "loc": {
                  "start": {
                    "line": 1,
                    "column": 22
                  },
                  "end": {
                    "line": 1,
                    "column": 31
                  }
                },
                "range": [
                  22,
                  31
                ],
                "value": "./basic",
                "raw": "'./basic'"
              }
            }
          ],
          "sourceType": "module",
          "comments": []
        }
      }
    },
    {
      "type": "mdxJsxFlowElement",
      "name": "Basic",
      "attributes": [],
      "children": [],
      "position": {
        "start": {
          "line": 3,
          "column": 1,
          "offset": 33
        },
        "end": {
          "line": 3,
          "column": 16,
          "offset": 48
        }
      }
    }
  ],
  "position": {
    "start": {
      "line": 1,
      "column": 1,
      "offset": 0
    },
    "end": {
      "line": 4,
      "column": 1,
      "offset": 49
    }
  }
}
  

mdxJsxFlowElement is not transformed.


OK, it is passThroughed in remarkRehype, so maybe I need recma-jsx-rewrite as well, will try it. Not working

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

I don't know why, but transform in remarkMarkAndUnravel is not even called in my case...

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

@JounQin I’m guessing it’s this: https://github.com/unifiedjs/unified#description.
You’re probably using .parse, which only parses the original document. But the other plugins work on the syntax tree, and are applied with .run:

await pipeline.run(pipeline.parse(tree, file), file)

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

@wooorm Thank you for clarify, and I got the following this time


{
  "type": "Program",
  "body": [
    {
      "type": "ImportDeclaration",
      "start": 0,
      "end": 31,
      "loc": {
        "start": {
          "line": 1,
          "column": 0
        },
        "end": {
          "line": 1,
          "column": 31
        }
      },
      "range": [
        0,
        31
      ],
      "specifiers": [
        {
          "type": "ImportSpecifier",
          "start": 9,
          "end": 14,
          "loc": {
            "start": {
              "line": 1,
              "column": 9
            },
            "end": {
              "line": 1,
              "column": 14
            }
          },
          "range": [
            9,
            14
          ],
          "imported": {
            "type": "Identifier",
            "start": 9,
            "end": 14,
            "loc": {
              "start": {
                "line": 1,
                "column": 9
              },
              "end": {
                "line": 1,
                "column": 14
              }
            },
            "range": [
              9,
              14
            ],
            "name": "Basic"
          },
          "local": {
            "type": "Identifier",
            "start": 9,
            "end": 14,
            "loc": {
              "start": {
                "line": 1,
                "column": 9
              },
              "end": {
                "line": 1,
                "column": 14
              }
            },
            "range": [
              9,
              14
            ],
            "name": "Basic"
          }
        }
      ],
      "source": {
        "type": "Literal",
        "start": 22,
        "end": 31,
        "loc": {
          "start": {
            "line": 1,
            "column": 22
          },
          "end": {
            "line": 1,
            "column": 31
          }
        },
        "range": [
          22,
          31
        ],
        "value": "./basic",
        "raw": "'./basic'"
      }
    },
    {
      "type": "FunctionDeclaration",
      "id": {
        "type": "Identifier",
        "name": "MDXContent"
      },
      "params": [
        {
          "type": "Identifier",
          "name": "_props"
        }
      ],
      "body": {
        "type": "BlockStatement",
        "body": [
          {
            "type": "VariableDeclaration",
            "kind": "const",
            "declarations": [
              {
                "type": "VariableDeclarator",
                "id": {
                  "type": "Identifier",
                  "name": "_components"
                },
                "init": {
                  "type": "CallExpression",
                  "callee": {
                    "type": "MemberExpression",
                    "object": {
                      "type": "Identifier",
                      "name": "Object"
                    },
                    "property": {
                      "type": "Identifier",
                      "name": "assign"
                    }
                  },
                  "arguments": [
                    {
                      "type": "ObjectExpression",
                      "properties": [
                        {
                          "type": "Property",
                          "kind": "init",
                          "key": {
                            "type": "Identifier",
                            "name": "h1"
                          },
                          "value": {
                            "type": "Literal",
                            "value": "h1"
                          }
                        }
                      ]
                    },
                    {
                      "type": "MemberExpression",
                      "object": {
                        "type": "Identifier",
                        "name": "_props"
                      },
                      "property": {
                        "type": "Identifier",
                        "name": "components"
                      }
                    }
                  ]
                }
              },
              {
                "type": "VariableDeclarator",
                "id": {
                  "type": "ObjectPattern",
                  "properties": [
                    {
                      "type": "Property",
                      "kind": "init",
                      "shorthand": false,
                      "key": {
                        "type": "Identifier",
                        "name": "wrapper"
                      },
                      "value": {
                        "type": "Identifier",
                        "name": "MDXLayout"
                      }
                    }
                  ]
                },
                "init": {
                  "type": "Identifier",
                  "name": "_components"
                }
              }
            ]
          },
          {
            "type": "VariableDeclaration",
            "kind": "const",
            "declarations": [
              {
                "type": "VariableDeclarator",
                "id": {
                  "type": "Identifier",
                  "name": "_content"
                },
                "init": {
                  "type": "JSXFragment",
                  "openingFragment": {
                    "type": "JSXOpeningFragment",
                    "attributes": [],
                    "selfClosing": false
                  },
                  "closingFragment": {
                    "type": "JSXClosingFragment"
                  },
                  "children": [
                    {
                      "type": "JSXElement",
                      "openingElement": {
                        "type": "JSXOpeningElement",
                        "attributes": [],
                        "name": {
                          "type": "JSXIdentifier",
                          "name": "Basic"
                        },
                        "selfClosing": false
                      },
                      "closingElement": {
                        "type": "JSXClosingElement",
                        "name": {
                          "type": "JSXIdentifier",
                          "name": "Basic"
                        }
                      },
                      "children": [
                        {
                          "type": "JSXElement",
                          "openingElement": {
                            "type": "JSXOpeningElement",
                            "attributes": [],
                            "name": {
                              "type": "JSXMemberExpression",
                              "object": {
                                "type": "JSXIdentifier",
                                "name": "_components"
                              },
                              "property": {
                                "type": "JSXIdentifier",
                                "name": "h1"
                              }
                            },
                            "selfClosing": false
                          },
                          "closingElement": {
                            "type": "JSXClosingElement",
                            "name": {
                              "type": "JSXMemberExpression",
                              "object": {
                                "type": "JSXIdentifier",
                                "name": "_components"
                              },
                              "property": {
                                "type": "JSXIdentifier",
                                "name": "h1"
                              }
                            }
                          },
                          "children": [
                            {
                              "type": "JSXExpressionContainer",
                              "expression": {
                                "type": "Literal",
                                "value": "abc",
                                "start": 43,
                                "end": 46,
                                "loc": {
                                  "start": {
                                    "line": 4,
                                    "column": 2
                                  },
                                  "end": {
                                    "line": 4,
                                    "column": 5
                                  }
                                },
                                "range": [
                                  43,
                                  46
                                ]
                              },
                              "start": 43,
                              "end": 46,
                              "loc": {
                                "start": {
                                  "line": 4,
                                  "column": 2
                                },
                                "end": {
                                  "line": 4,
                                  "column": 5
                                }
                              },
                              "range": [
                                43,
                                46
                              ]
                            }
                          ],
                          "start": 41,
                          "end": 46,
                          "loc": {
                            "start": {
                              "line": 4,
                              "column": 0
                            },
                            "end": {
                              "line": 4,
                              "column": 5
                            }
                          },
                          "range": [
                            41,
                            46
                          ]
                        }
                      ],
                      "start": 33,
                      "end": 55,
                      "loc": {
                        "start": {
                          "line": 3,
                          "column": 0
                        },
                        "end": {
                          "line": 5,
                          "column": 8
                        }
                      },
                      "range": [
                        33,
                        55
                      ],
                      "data": {
                        "_xdmExplicitJsx": true
                      }
                    }
                  ],
                  "start": 0,
                  "end": 56,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 0
                    },
                    "end": {
                      "line": 6,
                      "column": 0
                    }
                  },
                  "range": [
                    0,
                    56
                  ]
                }
              }
            ]
          },
          {
            "type": "ReturnStatement",
            "argument": {
              "type": "ConditionalExpression",
              "test": {
                "type": "Identifier",
                "name": "MDXLayout"
              },
              "consequent": {
                "type": "JSXElement",
                "openingElement": {
                  "type": "JSXOpeningElement",
                  "name": {
                    "type": "JSXIdentifier",
                    "name": "MDXLayout"
                  },
                  "attributes": [
                    {
                      "type": "JSXSpreadAttribute",
                      "argument": {
                        "type": "Identifier",
                        "name": "_props"
                      }
                    }
                  ]
                },
                "closingElement": {
                  "type": "JSXClosingElement",
                  "name": {
                    "type": "JSXIdentifier",
                    "name": "MDXLayout"
                  }
                },
                "children": [
                  {
                    "type": "JSXExpressionContainer",
                    "expression": {
                      "type": "Identifier",
                      "name": "_content"
                    }
                  }
                ]
              },
              "alternate": {
                "type": "Identifier",
                "name": "_content"
              }
            }
          }
        ]
      }
    },
    {
      "type": "ExportDefaultDeclaration",
      "declaration": {
        "type": "Identifier",
        "name": "MDXContent"
      }
    }
  ],
  "sourceType": "module",
  "comments": [
    {
      "type": "Block",
      "value": "@jsxRuntime automatic @jsxImportSource react"
    }
  ],
  "start": 0,
  "end": 56,
  "loc": {
    "start": {
      "line": 1,
      "column": 0
    },
    "end": {
      "line": 6,
      "column": 0
    }
  },
  "range": [
    0,
    56
  ]
}

loc/range is missing at BlockStatement. And as I can see, the transformation iss beyond what I need, I want original jsx content, not transformed, is there any argument to achieve this.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

Can you post the code you’re using?

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

Can you post the code you’re using?

86ee6ae

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

recmaJsxRewrite rewrites JSX to function calls. Don’t use it.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

recmaDocument wraps all the ESM and the JSX expression (all “content”) in a bunch of functions. You don‘t need it either.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

OK, next problems:

  1. raw property is missing is Literal estree node, although it's not standard for now, related to .raw property of literal nodes, or something similar estree/estree#14
  2. markdown in jsx is transformed into jsx node, I'd like to treat it as Literal

So maybe I need to rewrite hast-util-to-estree, or is that possible to add options to support them?

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

raw property is missing is Literal estree node, although it's not standard for now, related to

Where isn’t it added? Please explain in more detail.

markdown in jsx is transformed into jsx node, I'd like to treat it as Literal

This sounds wrong. That’s not what MDX is. It’s not a literal.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

Where isn’t it added? Please explain in more detail.

hast-util-to-estree https://github.com/syntax-tree/hast-util-to-estree/blob/main/index.js#L167

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

This sounds wrong. That’s not what MDX is. It’s not a literal.

OK. I don't know if it would be a problem for other jsx rules, let's handle it in the future.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

How does that interfere with ESLint? What breaks?

The bigg problem with .raw is that it’s going to be wrong.
Take this example: https://github.com/syntax-tree/hast-util-to-estree/blob/f381bc45a33a7ad0e6b0b136bece824b652421f6/index.js#L382.
The actual raw would be a &copy; b if a user wrote that as text, and the value would be a © b.
However, ESLint will fail on that. For one, because there are no quotes. For another, because of the character reference.

It’s impossible: we can either add the actual raw but break ESLint, or we can add a fake raw, probably preventing ESLint from working.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

You know more about ESLint that I do, but quickly going through the ESLint rules, I’m not seeing raw being used a lot.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

You know more about ESLint that I do, but quickly going through the ESLint rules, I’m not seeing raw being used a lot.

https://github.com/eslint/eslint/search?q=node.raw&type=

It's used in many rules, and it breaks on my tests.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

It's used in many rules, and it breaks on my tests.

V2 of the MDX format is a breaking change.


You glossed over my explanation.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

V2 of the MDX format is a breaking change.

I understand it is a breaking change, I'm just asking for raw support in hast-util-to-estree because it breaks many eslint core rules.

The actual raw would be a © b if a user wrote that as text, and the value would be a © b.
However, ESLint will fail on that. For one, because there are no quotes. For another, because of the character reference.

I'm not quite sure to understand, can you provide some codes so that I can change it locally at https://github.com/mdx-js/eslint-mdx/blob/next-debug/packages/eslint-mdx/src/plugins/hast-util-to-estree.js to make sure if it is working.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

Maybe this’ll help. Here’s an explanation for JSX: acornjs/acorn-jsx#105.
But with MDX, we don’t just have JSX, we also have markdown, which is even more complex.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

Maybe this’ll help. Here’s an explanation for JSX: acornjs/acorn-jsx#105.
But with MDX, we don’t just have JSX, we also have markdown, which is even more complex.

How could I get this raw input at https://github.com/syntax-tree/hast-util-to-estree/blob/f381bc45a33a7ad0e6b0b136bece824b652421f6/index.js#L382?

I change it to expression: inherit(node, { type: 'Literal', value: value, raw: value === 'a © b' ? 'a &copy; b' : value }), for testing, ESLint does not complain here.

So I want to get raw first, if there are problems we can fix it in the future.

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

Another problem, I can't get all tokens from hast-util-to-estree.

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

That’s similar. To illustrate: what tokens and raw fields do you expect ## Heading to result in?

@JounQin
Copy link
Member Author

JounQin commented Mar 16, 2021

That’s similar. To illustrate: what tokens and raw fields do you expect ## Heading to result in?

No, it's markdown, not es. I don't think eslint-mdx should care. But it's children like # Header <div></div> should recognize the div part.

That's why I want markdown in jsx to be Literal at #284 (comment)

@wooorm
Copy link
Member

wooorm commented Mar 16, 2021

So how does ESLint work with partial tokens? As in, “holes”? For lots of things, it can’t have tokens. Such as <tag>*markdown*</tag>. Right? If we’d have support for tokens, then It’d have a couple tokens for the tag, then it’ll have a “gap”, then it’ll have some more tokens?

Regardless, tokens is nonstandard. And incredibly hard to get for JSX. And those gaps. I’m guessing that even if we had them, it wouldn’t work?

@JounQin
Copy link
Member Author

JounQin commented Mar 27, 2022

@wooorm I think it's time to go ahead, you can try to release a next tag version via yarn release-next after merging.

@wooorm
Copy link
Member

wooorm commented Mar 27, 2022

You mean that this is ready for release?
Or ready for trying out?
Or does it need a review?


anyway, really cool that you’ve made this work :)

@JounQin
Copy link
Member Author

JounQin commented Mar 28, 2022

You mean that this is ready for release? Or ready for trying out? Or does it need a review?

anyway, really cool that you’ve made this work :)

@wooorm Ready for a beta next release by yarn release-next for users to try out.

@JounQin
Copy link
Member Author

JounQin commented Mar 28, 2022

The current implementation is heavily depending on synckit, because ESLint itself doesn't support ESM plugin for now, but the unified ecosystem has moved to ESM only.

With synckit, we're using cjs + dynamic import to load ESM synchronously in worker at https://github.com/mdx-js/eslint-mdx/blob/next/packages/eslint-mdx/src/worker.ts#L155.

Copy link
Member

@wooorm wooorm left a comment

Choose a reason for hiding this comment

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

Nice! Really cool that a bunch of hacky code could be removed.
I do have a couple questions!

One more “soft” change in MDX 2, that I wanted to check with you, is that now, .mdx more strongly should be used for MDX and .md for normal markdown. I wanted to make sure you are aware of that. Perhaps there could be rules for this, or you know other things that need to change here?

(for more info, see the big purple box here: https://mdxjs.com/docs/what-is-mdx/#mdx-syntax)

* @returns A Promise that resolves to the dynamically imported module.
*/
/* istanbul ignore next */
export const loadEsmModule = <T>(modulePath: URL | string): Promise<T> =>
Copy link
Member

Choose a reason for hiding this comment

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

Can you replace all of this with https://github.com/wooorm/import-meta-resolve?

Copy link
Member Author

@JounQin JounQin Mar 28, 2022

Choose a reason for hiding this comment

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

@wooorm I don't think so, this function is used to hack TypeScript and call import() in cjs (TypeScript transforms import() into Promise.resolve(require()) by default and have no way to disable this behavior as the comments), I'm not sure how import-meta-resolve will resolve this problem.

Notice, the ESLint plugin package is still cjs only due to ESLint itself.

Copy link
Member

Choose a reason for hiding this comment

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

import-meta-resolve will not solve that problem. It is also itself ESM, so that would be a problem here.
But, it’s much better at loading ESM/CJS because it supports export maps and other modern resolving features.

Copy link
Member Author

Choose a reason for hiding this comment

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

So, is there anything you are proposing to change? I'm still confusing what import-meta-resolve will help with in this project. I believe native import() will handle export maps and other modern resolving features already. We're loading the module instead of resolving its absolute path here.

Copy link
Member

@wooorm wooorm Mar 28, 2022

Choose a reason for hiding this comment

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

If it is possible to use import-meta-resolve, I recommend doing so.

import() resolves from eslint-mdx/src/helpers.ts and imports the resolved path. (and: in your code you first try to require them. That works okay but isn’t perfect.)

import-meta-resolve resolves modules from a given URL. It is like import.meta.resolve, which is experimental in Node behind a flag.

Copy link
Member Author

@JounQin JounQin Mar 28, 2022

Choose a reason for hiding this comment

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

We're always in commonjs context here, so I believe import.meta.url is not available.

Copy link
Member

@wooorm wooorm Mar 28, 2022

Choose a reason for hiding this comment

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

URL is still available. In Node.js, in both ESM and CJS, you can create URLs from file paths, and file paths from URLs. import-meta-resolve/import.meta.resolve does not depend on import.meta.url.

But again: import-meta-resolve is ESM only. So if you are not in ESM here, you can’t easily use it. Though, you can create a small bundle of it:

npx esbuild import-meta-resolve --bundle --platform=node --outfile=vendor/import-meta-resolve.cjs`

packages/eslint-plugin-mdx/README.md Outdated Show resolved Hide resolved
test/fixtures/basic.mdx Show resolved Hide resolved
test/helpers.test.ts Show resolved Hide resolved
@JounQin
Copy link
Member Author

JounQin commented Mar 28, 2022

Nice! Really cool that a bunch of hacky code could be removed. I do have a couple questions!

One more “soft” change in MDX 2, that I wanted to check with you, is that now, .mdx more strongly should be used for MDX and .md for normal markdown. I wanted to make sure you are aware of that. Perhaps there could be rules for this, or you know other things that need to change here?

(for more info, see the big purple box here: mdxjs.com/docs/what-is-mdx/#mdx-syntax)

Yeah, we have separated them in v1 already, and we have a flag isMdx to determine whether to enable remark-mdx.

@wooorm
Copy link
Member

wooorm commented Mar 28, 2022

looks good to me :)

@JounQin JounQin merged commit ec1d9b4 into master Mar 28, 2022
@JounQin JounQin deleted the next branch March 28, 2022 15:25
@JounQin
Copy link
Member Author

JounQin commented Mar 28, 2022

@wooorm Please help to release a next version via yarn release-next or do you think is it OK to publish a latest version?

@wooorm
Copy link
Member

wooorm commented Mar 28, 2022

As a major, I believe, right?

I guess it’s good to try it out for a bit instead of just cutting 2.0.0 immediately!

@JounQin
Copy link
Member Author

JounQin commented Mar 28, 2022

As a major, I believe, right?

I guess it’s good to try it out for a bit instead of just cutting 2.0.0 immediately!

@wooorm Yeah, of course.

You'll need to check whether is my script "release-next": "lerna publish --conventional-prerelease --preid next --pre-dist-tag next --yes" correct.

@wooorm
Copy link
Member

wooorm commented Mar 29, 2022

Released! I manually had to select premajor, rest was automated!

...
lerna info auto-confirmed 
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna info publish Publishing packages to npm...
lerna info Verifying npm credentials
...

I guess it doesn’t create a release for a prerelease 🤷‍♂️ Want me to add anything?

@JounQin
Copy link
Member Author

JounQin commented Mar 29, 2022

I guess it doesn’t create a release for a prerelease 🤷‍♂️ Want me to add anything?

@wooorm Just drafted https://github.com/mdx-js/eslint-mdx/releases/tag/v2.0.0-next.0

@wooorm
Copy link
Member

wooorm commented Mar 29, 2022

sweet, thanks!

@JounQin
Copy link
Member Author

JounQin commented Mar 29, 2022

@wooorm Did you forget to run yarn build first before releasing? 😂 There is no prerelease-next script for it like prerelease.

See https://unpkg.com/browse/eslint-plugin-mdx@2.0.0-next.0/

@wooorm
Copy link
Member

wooorm commented Mar 29, 2022

Correct, I did not run yarn build.
I followed the (beta) release guidelines.

Can you:

  • Explain what steps you want me to follow? (are there more things I need to do?) I’ll try again.
  • Can you at some point update the contributing guide?

@JounQin
Copy link
Member Author

JounQin commented Mar 29, 2022

@wooorm Sorry, I forgot about that part because we'd had prerelease before. I'll update to contribute guide later. Now I think you need to run yarn build && yarn release-next to publish a correct next release again.

@wooorm
Copy link
Member

wooorm commented Mar 29, 2022

What flag do I have to add to force a publish without changes?

@JounQin
Copy link
Member Author

JounQin commented Mar 29, 2022

What flag do I have to add to force a publish without changes?

@wooorm https://github.com/lerna/lerna/tree/main/commands/version#--force-publish

@wooorm
Copy link
Member

wooorm commented Mar 29, 2022

I think it worked! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment