Giter Club home page Giter Club logo

vite-plugin-mdx's Introduction

====================== WE ARE LOOKING FOR A NEW MAINTAINER ====================

Vite Plugin MDX

Use this Vite plugin to use MDX v1 with your Vite v2 app. For Vite v3+ we recommend migrating to MDX v2 using the official @mdx-js/rollup, this comment explains how to implement it.

Features:

  • Works with React and Preact.
  • Works with Vue [WIP].
  • HMR support.
  • SSR support.
  • Plugin support, such as remark-frontmatter.

Getting Started

  1. Install:

    1. Vite Plugin:
       npm install vite-plugin-mdx
    2. MDX v1:
      npm install @mdx-js/mdx
    3. MDX React:
      npm install @mdx-js/react
      Or MDX Preact:
      npm install @mdx-js/preact
  2. Add the plugin to your vite.config.js.

    // vite.config.js
    
    import mdx from 'vite-plugin-mdx'
    
    // `options` are passed to `@mdx-js/mdx`
    const options = {
      // See https://mdxjs.com/advanced/plugins
      remarkPlugins: [
        // E.g. `remark-frontmatter`
      ],
      rehypePlugins: [],
    }
    
    export default {
      plugins: [mdx(options)]
    }
  3. You can now write .mdx files.

    // hello.mdx
    
    import { Counter } from './Counter.jsx'
    
    # Hello
    
    This text is written in Markdown.
    
    MDX allows Rich React components to be used directly in Markdown: <Counter/>
    
    // Counter.jsx
    
    import React, { useState } from 'react'
    
    export { Counter }
    
    function Counter() {
      const [count, setCount] = useState(0)
    
      return (
        <button onClick={() => setCount((count) => count + 1)}>
          Counter: {count}
        </button>
      )
    }

Examples

File-specific options

To define options a per-file basis, you can pass a function to the mdx plugin factory.

mdx((filename) => {
  // Any options passed to `mdx` can be returned.
  return {
    remarkPlugins: [
      // Enable a plugin based on the current file.
      /\/components\//.test(filename) && someRemarkPlugin,
    ]
  }
})

Pre-built transclusion

To embed an .mdx or .md file into another, you can import it without naming its export. The file extension is required. Remark plugins are applied to the imported file before it's embedded.

import '../foo/bar.mdx'

vite-plugin-mdx's People

Contributors

ajstrand avatar aleclarson avatar brillout avatar codpoe avatar csr632 avatar joshwooding avatar mijamo avatar silvenon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

vite-plugin-mdx's Issues

Transform Error

I add the following code in my mdx

///demo.jsx
export default Demo = () => <></>

///mdx
import Demo from './demo.jsx'

<Demo  test='{test:"22"}' />

and went to an error

[vite] Internal server error: Transform failed with 1 error:
<stdin>:7:1427: error: Expected ">" but found "2"
  Plugin: vite-plugin-mdx

is the bug between the esbuild transform and mdx-js ?

TypeError: mdx is not a function

vite.config.json is:

import { defineConfig } from 'vite';
import mdx from 'vite-plugin-mdx'

const { resolve } = path;

export default defineConfig({
  plugins: [
    mdx()
  ],
})

but I got error:

TypeError: mdx is not a function

May I ask Why and how to solve it?

esbuild should be peer dependency

requiring a hard version can cause issues and multiple esbuild versions in a repo, creating inconsistency in build env vs development env

image

Using this plugin with Vite SSR fails

I don't know if it's specific to this plugin but when I try to run a simple static page with it using SSR it throws this error:

/home/thelinuxlich/frontend-starter/node_modules/@mdx-js/react/dist/esm.js:1
import React from 'react';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1024:16)
    at Module._compile (node:internal/modules/cjs/loader:1072:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at Module.<anonymous> (/home/thelinuxlich/frontend-starter/dist/server/entry-server.js:24:14)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)

How do I access the frontmatter

I am new to MDX and want to use it in a React app. My vite.config.ts file looks like:

import { defineConfig } from 'vite'
import mdx from 'vite-plugin-mdx'
import reactRefresh from '@vitejs/plugin-react-refresh'
import frontmatter from 'remark-frontmatter'

export default defineConfig({
  plugins: [
      reactRefresh(),
      mdx({
          remarkPlugins: [
              frontmatter,
          ],
      }),
    ],
})

Now I want to import the React component and the frontmatter. Something like:

import Home, { frontMatter } from './pages/Home.mdx';

Are there plugins that generate an export of the frontMatter constant?

Usage Example?

Hey! I tried setting up this plugin and ran into some issues. I bootstrapped a project with npm init @vitejs/app and added the plugin to vite.config.js:

import reactRefresh from "@vitejs/plugin-react-refresh";
import mdx from "@brillout/vite-plugin-mdx";

export default {
  jsx: "react",
  plugins: [reactRefresh(), mdx],
};

Then I created a simple app.mdx file that I tried to import in main.jsx:

import React from "react";
import ReactDOM from "react-dom";
import App from "./app.mdx";

ReactDOM.render(<App />, document.getElementById("root"));

which gives me an error in the browser window: Uncaught SyntaxError: Invalid or unexpected token (app.mdx).
So... what am I missing?

Plugin usage example

Hello, I'm new to mdx, so maybe I'm doing somethign wrong, but I was trying to use this plugin with react and I wanted to enbale syntac highlighting and line numbers. I've tryed remark-prism and rehype-prism something like follows:

const remarkPrism = require('remark-prism');

const mdxOptions = {
  remarkPlugins: [
    remarkPrism,
  ],
  rehypePlugins: [],
}

But I don't see any change. Is there anything else I need to enable?

MDX v2 not working

Hello,

If I install the @mdx-js/mdx package and follow the instructions in README.md, everything works well.

However, if I use the @mdx-js/mdx@next package, an error would occur:

error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module <project>/node_modules/@mdx-js/mdx/index.js from <project>/node_modules/vite-plugin-mdx/dist/imports.js not supported.
Instead change the require of index.js in <project>/node_modules/vite-plugin-mdx/dist/imports.js to a dynamic import() which is available in all CommonJS modules.
    at Object.requireMdx (<project>/node_modules/vite-plugin-mdx/dist/imports.js:10:12)
    at Object.createTransformer (<project>/node_modules/vite-plugin-mdx/dist/transform.js:16:27)
    at Object.configResolved (<project>/node_modules/vite-plugin-mdx/dist/index.js:46:43)
    at <project>/node_modules/vite/dist/node/chunks/dep-e0fe87f8.js:68353:127
    at Array.map (<anonymous>)
    at resolveConfig (<project>/node_modules/vite/dist/node/chunks/dep-e0fe87f8.js:68353:35)
    at async createServer (<project>/node_modules/vite/dist/node/chunks/dep-e0fe87f8.js:66702:20)
    at async CAC.<anonymous> (<project>/node_modules/vite/dist/node/cli.js:687:24)

TypeScript support

# Hello

This text is written in Markdown. 1 + 1 = { (1 as number) + 1}

We should support ts code

Rendering code demo fences

I am trying to port a site using gatsby-plugin-mdx-code-demo to vite. This plugin allows you to render sample code in a normal pre together with the resulting generated component. See https://material-ui.com/components/buttons for an example of the type of thing.

I would like to be able to write MDX like:

// buttons.mdx

# Buttons

See below for an example of a button:

```jsx demo
    import {Button} from "@acme/controls"

    export default () => <Button>Click Me</Button>
```

I realise this is a very open question but any advice on the idiomatic way to achieve this using vite + vite-plugin-mdx would be appreciated!

Vue support

I started implementing Vue support. Let me know if you are interested in this and I'll further push this forward.

Broken with yarn PNP

Currently if you use Yarn PNP you get Error: [vite-plugin-mdx] "react" must be installed

This is because this package is using find-dependency which seems to be a rather confidential library that tries to get the path of a dependency only using node_modules, a trivial but often wrong approach of importing in node.

I haven't looked much into why this library is trying to resolve dependencies itself. Usually it should be left to Vite to handle this kind of things (because some Vite config options such as aliases can impact the resolution, and also because resolving import is actually a very complex task). If I get a bit of background on the why I can try to write some pull request to fix it.

Dependency resolution doesn't work as expected when a project *also* uses MDX 2

Hello! I've read the README, I know you're looking for a maintainer and also you don't want to hear about MDX 2 problems 馃檪 but wanted to FYI in case you have any obvious answers, as I believe imports.ts is giving me issues in a project where MDX 2 is present (but this plugin should be ignoring it and using MDX 1)

The issue manifests when using Storybook with storybook-builder-vite (which uses this plugin and MDX 1). This plugin attempts to require the incorrect version of mdx-js/mdx from the project root node_modules rather than the node_modules right next to it.

More details here storybookjs/builder-vite#234 and test reproduction here https://github.com/bensmithett/test-case-mdx-import

Appreciate any help or pointing me in the right direction.

The requested module `/node_modules/.vite/@mdx-js_react.js?v=d545b648` does not provide an export named `mdx`

Originally posted by @hfabio in #44 (comment)

Just wanted to add a bit more helpful info for others who venture here. I was successful with these steps:

  • Did not set type: "module" in my package.json. For me this caused a ton of other issues.
  • Added the MDX plugin in my vite.config.ts like this:
import { defineConfig } from 'vite';

export default defineConfig(async () => {
  const mdx = await import('@mdx-js/rollup');

  return {
    plugins: [mdx.default()]
  };
});
  • Had to set "target": "esnext" in my tsconfig.json otherwise I was getting transpilation errors

Does someone faced this kind of error?
Uncaught SyntaxError: The requested module '/node_modules/.vite/@mdx-js_react.js?v=d545b648' does not provide an export named 'mdx'
image
I'm using:

  • react - ^17.0.2
  • vite - ^2.5.3
  • @storybook/react - ^6.4.19
  • storybook-builder-vite - ^0.1.15
  • @mdx-js/react -^2.0.0
  • @mdx-js/rollup - ^2.0.0
  • vite-plugin-mdx - ^3.5.10

This is my .storybook/main.js:

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  core: {
    builder: 'storybook-builder-vite',
  },
};

and this is my vite.config.ts:

import { defineConfig } from 'vite';
import camelCase from 'camelcase';
import * as path from 'path';
import * as fs from 'fs';
import dts from 'vite-plugin-dts';
import eslint from 'vite-plugin-eslint';
import reactRefresh from '@vitejs/plugin-react-refresh';
import mdx from '@mdx-js/rollup';
import pkg from './package.json';

// `options` are passed to`@mdx-js/mdx`
const mdxOptions = {
  // See https://mdxjs.com/advanced/plugins
  remarkPlugins: [
    // E.g. `remark-frontmatter`
  ],
  rehypePlugins: [],
};

const getEntry = () => {
  const tsxFile = path.resolve(__dirname, 'src/index.tsx');
  if (fs.existsSync(tsxFile)) return tsxFile;
  const tsFile = path.resolve(__dirname, 'src/index.ts');
  if (fs.existsSync(tsFile)) return tsFile;
  throw new Error('Cannot find entry. (src/index.tsx or src/index.ts)');
};
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    reactRefresh(),
    eslint({ fix: true, throwOnWarning: false }),
    dts({ tsConfigFilePath: './tsconfig.build.json', insertTypesEntry: true }),
    mdx(mdxOptions),
  ],
  esbuild: {
    jsxInject: "import * as React from 'react';",
  },
  build: {
    lib: {
      entry: getEntry(),
      name: camelCase(path.basename(pkg.name)),
      fileName: (format) => `index.${format}.js`,
    },
    rollupOptions: {
      external: ['react', 'react-dom', 'styled-components'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
          'styled-components': 'styled',
        },
      },
    },
  },
});

Type safety for options

@mdx-js/mdx@next has TypeScript support

Any reason we're not using it in devDependencies?

Can `resolveImport` support vite `alias` or vite `resolve` ?

Hi, I鈥檓 currently trying to write a library that wraps vite-plugin-mdx and vite-plugin-react-pages. When I use my library by npx, I got the error "react" must be installed because there is no react directory in my node_modules.

So I wondered if vite-plugin-mdx could support alias of Vite so I could avoid this error in my plugin. thx 馃榾

Add note for Preact support?

I wanted to use your MDX plugin with Preact.

I had to add this block to my vite config:

  alias: {
    react: 'preact/compat',
    'react-dom': 'preact/compat'
    },

I also had to add "@mdx-js/preact" in my package json.

This may be helpful to note for others who want to use your plugin with Preact.

Obviously the better solution would be to not have a hard dependency on @mdx-js/react.

Could a possible solution be checking for React or Preact in the user's package.json and telling them to install either @mdx-js/react, @mdx-js/preact?

I'm happy to work on a PR for this if Preact is something you'd like to support.

Not Support In typescript file

in index.tsx

import Readme from './Readme.mdx'

and the lint told me

Cannot find module './Readme.mdx' or its corresponding type declarations.ts(2307)

add configure option to inferNamedImports

Clear and concise description of the problem

For monorepo projects, it is likely that both react and preact packages required in the dependencies, so passing resolveImport('preact', root) may be problematic

Suggested solution

add configure option

Alternative

yarn patch

diff --git a/dist/imports.js b/dist/imports.js
index 8f16352ab74f329dd01389d416059754bbf0a99f..418fc1b9b83b7111799c2fe4acd7564ba351df75 100644
--- a/dist/imports.js
+++ b/dist/imports.js
@@ -42,9 +42,7 @@ function assertImportExists(name, cwd) {
 }
 exports.assertImportExists = assertImportExists;
 function inferNamedImports(root) {
-    return resolveImport('preact', root)
-        ? { preact: ['h'], '@mdx-js/preact': ['mdx'] }
-        : { react: 'React', '@mdx-js/react': ['mdx'] };
+    return { react: 'React', '@mdx-js/react': ['mdx'] };
 }
 exports.inferNamedImports = inferNamedImports;
 //# sourceMappingURL=imports.js.map
\ No newline at end of file

Additional context

Sorry for any mistakes. English is not my native language

Issue with MDX V2

Hello,
I am unable to make this lib works with MDX V2.

I followed the Readme and did the following steps:

  • npm init vite@latest vite-mdx-2
  • cd vite-mdx-2/
  • npm i
  • npm install vite-plugin-mdx
  • npm install @mdx-js/mdx@next
  • Create vite.config.js with the same content as in the Readme file.

But then when I run npm run dev, I have the following error:

error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module /home/tocab/Projects/Tmp/vite-mdx-2/node_modules/@mdx-js/mdx/index.js from /home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite-plugin-mdx/dist/imports.js not supported.
Instead change the require of index.js in /home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite-plugin-mdx/dist/imports.js to a dynamic import() which is available in all CommonJS modules.
    at Object.requireMdx (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite-plugin-mdx/dist/imports.js:10:12)
    at Object.createTransformer (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite-plugin-mdx/dist/transform.js:16:27)
    at Object.configResolved (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite-plugin-mdx/dist/index.js:46:43)
    at /home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite/dist/node/chunks/dep-76613303.js:74807:127
    at Array.map (<anonymous>)
    at resolveConfig (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite/dist/node/chunks/dep-76613303.js:74807:35)
    at async createServer (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite/dist/node/chunks/dep-76613303.js:60309:20)
    at async CAC.<anonymous> (/home/tocab/Projects/Tmp/vite-mdx-2/node_modules/vite/dist/node/cli.js:688:24)

I also tried to add "type": "module" in package.json without success.

Here is the minimum reproducible repo: https://github.com/tonai/vite-mdx-2

Does someone know what I am missing ?
Thanks,

failed to install vite-plugin-mdx with yarn

  • command: yarn add vite-plugin-mdx --dev
  • result:
yarn add v1.22.11
[1/4] Resolving packages...
error Couldn't find package "vfile@^4.0.0" required by "unified@^9.2.1" on the "npm" registry.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Compatibility with MDX v2

Very great work to make this vite plugin framework-independent!

I've tested this with MDX v2 (currently unreleased) by changing the dependencies in this plugin and my project. It works great and fixes some issues I have when using MDX within a react component within MDX.

  "dependencies": {
    "@mdx-js/mdx": "^2.0.0-next.8",
    "@mdx-js/react": "^2.0.0-next.8",
    "@mdx-js/util": "^2.0.0-next.8",

Example document:

### hello page

Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum alias
vero cupiditate optio blanditiis adipisci eveniet. Error magnam
vel soluta, dolores unde laborum omnis numquam eaque itaque atque,
sunt perspiciatis.

export const Foo = ({ children, ...otherProps }) => (
  <div style={{ color: "red" }} {...otherProps}>
    {children}
  </div>
);

<Foo>
lorem **ipsum** dolor.

> foo [bar](https://example.org/)

</Foo>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    馃枛 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 馃搳馃搱馃帀

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google 鉂わ笍 Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.