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

Fail to import ESM dependencies in config file #4455

Closed
6 tasks done
codepunkt opened this issue Jul 31, 2021 · 9 comments
Closed
6 tasks done

Fail to import ESM dependencies in config file #4455

codepunkt opened this issue Jul 31, 2021 · 9 comments

Comments

@codepunkt
Copy link
Contributor

Describe the bug

Related to #1166 - this time with a reproduction.

Given the following vite.config.js file:

import { defineConfig } from "vite";
import preact from "@preact/preset-vite";
import grayMatter from "gray-matter";
import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
import remarkToRehype from "remark-rehype";
import rehypeRaw from "rehype-raw";
import { unified } from "unified";
import toJsx from "@mapbox/hast-util-to-jsx";

export default defineConfig({
  plugins: [
    {
      name: "markdown",
      async transform(code, id) {
        if (id.match(/\.md$/)) {
          const { content: markdown, data: frontmatter } = grayMatter(code);
          const processor = unified()
            .use(remarkParse)
            .use(remarkStringify)
            .use(remarkToRehype, { allowDangerousHtml: true })
            .use(rehypeRaw)
            .use(function stringifyToJsx() {
              this.Compiler = (tree) => toJsx(tree);
            });
          const vfile = await processor.process(markdown);
          console.log({ frontmatter, code: vfile.value });
          return { code: vfile.value };
        }
      }
    },
    preact
  ]
});

results in [ERR_REQUIRE_ESM]: Must use import to load ES Module error, as at least one of the imported packages (here: unified) is an ESM package.

I'm not sure why that happens, but the reasoning in #1166 seems understandable. Looking at that issue, it's supposed to be fixed in 2.x, but it seems like it isn't.

Reproduction

https://codesandbox.io/s/vite-config-esm-problem-mlill

System Info

Taken from the reproduction codesandbox

  System:
    OS: Linux 5.4 Debian GNU/Linux 10 (buster) 10 (buster)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
    Memory: 800.55 MB / 62.73 GB
    Container: Yes
    Shell: 5.0.3 - /bin/bash
  Binaries:
    Node: 14.16.1 - ~/.nvm/versions/node/v14.16.1/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v14.16.1/bin/yarn
    npm: 6.14.12 - ~/.nvm/versions/node/v14.16.1/bin/npm
  npmPackages:
    vite: ^2.4.4 => 2.4.4

Used Package Manager

yarn

Logs

failed to load config from /sandbox/vite.config.js
error when starting dev server:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /sandbox/node_modules/unified/index.js
require() of ES modules is not supported.
require() of /sandbox/node_modules/unified/index.js from /sandbox/vite.config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(),or remove "type": "module" from /sandbox/node_modules/unified/package.json.

    at Module._extensions..js (internal/modules/cjs/loader.js:1080:13)
    at Object.require.extensions.<computed> [as .js] (/sandbox/node_modules/vite/dist/node/chunks/dep-c1a9de64.js:75583:13)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/sandbox/vite.config.js:36:33)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.require.extensions.<computed> [as .js] (/sandbox/node_modules/vite/dist/node/chunks/dep-c1a9de64.js:75580:20)
    at Module.load (internal/modules/cjs/loader.js:928:32)
error Command failed with exit code 1.

Validations

@dominikg
Copy link
Contributor

more info on unified package: vitejs/vite-plugin-react#30

@codepunkt
Copy link
Contributor Author

@dominikg the linked issue and further ones linked to it don't have the ERR_REQUIRE_ESM as far as I can see, even though it might be the same underlying problem.

@sodatea
Copy link
Member

sodatea commented Aug 1, 2021

It's kinda tricky.

The vite.config.js in this project is not an actual ES module. It will be compiled to CJS by esbuild.

To use it as an actual ES module, you'll need to rename it to vite.config.mjs or add type: "module" to the project package.json.

Note that, in that case, you might encounter some other issues due to Node.js ESM-CJS interop restrictions.

@sodatea
Copy link
Member

sodatea commented Aug 1, 2021

It's not a bug, though.

@sodatea sodatea closed this as completed Aug 1, 2021
@codepunkt
Copy link
Contributor Author

@sodatea Did you try any one of your solutions in the codesandbox?

  • renaming to vite.config.mjs and running with --config vite.config.mjs resolts in exactly the same error
  • using "type": "module", the error doesn't happen because according to vite config, the config file is not pre-processed in this case. However, the page of a this very simple vite project stays empty and doesn't render the react components.

Will open another bug with that in this case.

If vite could prevent this without having to use "type": "module", it's a bug in my book.

What about vitejs/vite-plugin-react#30 #3024 sveltejs/kit#1961?Are they related?

@codepunkt
Copy link
Contributor Author

Anyways, thanks for having a look 👍🏻

I'll dig deeper into my problems with setting "type": "module" next!

@sodatea
Copy link
Member

sodatea commented Aug 1, 2021

Did you try any one of your solutions in the codesandbox?

The config in CodeSandbox seems to be different than the one you described in the issue.


  • renaming to vite.config.mjs and running with --config vite.config.mjs resolts in exactly the same error

Don't use --config vite.config.mjs, vite.config.mjs can be picked up automatically.

This can be considered a small bug of Vite. It currently only recognizes .mjs or .ts extensions of the default config file, but failed to process those passed by --config.


  • the page of a this very simple vite project stays empty and doesn't render the react components.

2 problems here:

  1. The preact preset should be called as a function per their documentation: https://github.com/preactjs/preset-vite#installation
  2. As said, when using real ES modules as the config file, you may encounter Node.js ESM-CJS interop issues.
    The preset was recognized by Node.js as a CJS module (which their main field points to).
    Unlike esbuild, Node.js doesn't have special treatment for the __esModule field in the CJS exports. So, you have to call preact.default() instead.

That is,

// vite.config.mjs
import { defineConfig } from "vite";
import preact from "@preact/preset-vite";

export default defineConfig({
  plugins: [preact.default()]
});

@codepunkt
Copy link
Contributor Author

@sodatea thanks! ❤️

@bensmithett
Copy link

bensmithett commented Aug 3, 2021

This can be considered a small bug of Vite. It currently only recognizes .mjs or .ts extensions of the default config file, but failed to process those passed by --config

Is there an issue tracking this? I'm currently using multiple config files to get around an issue with the --ssr flag...

https://github.com/bensmithett/tropical/blob/main/package.json#L39-L40
https://github.com/bensmithett/tropical/blob/main/vite.config.server.js#L13-L15

...but I don't think I can update a dependency (rehype-slug) to its latest ESM-only version until I can pass an .mjs file to --config.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants