vitepress
vitepress copied to clipboard
`vitepress build` fails with `ERR_REQUIRE_ESM`
Describe the bug
I'm trying to migrate my documentation from a regular Vite setup to Vitepress.
Everything works fine when using vitepress dev
(except that the CSS is sometimes broken upon first load).
However, vitepress build
fails with the following output:
$ vitepress build docs
vitepress v0.20.9
✓ building client + server bundles...
- rendering pages...
Error [ERR_REQUIRE_ESM]: require() of ES Module /home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/d3/src/index.js from /home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/demo_index.md.js not supported.
Instead change the require of index.js in /home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/demo_index.md.js to a dynamic import() which is available in all CommonJS modules.
at Module.<anonymous> (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/demo_index.md.js:25:10)
at /home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:1621:12
at loadPage (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:163:18)
at Object.go (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:156:12)
at renderPage (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/node/serve-61783397.js:40037:10)
at Object.build (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/node/serve-61783397.js:40169:15) {
code: 'ERR_REQUIRE_ESM'
}
✖ rendering pages...
build error:
TypeError: Cannot read properties of null (reading 'frontmatter')
at ReactiveEffect.fn (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:91:48)
at ReactiveEffect.run (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:153:29)
at ComputedRefImpl.get value [as value] (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:1010:39)
at ReactiveEffect.fn (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:1259:23)
at ReactiveEffect.run (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:153:29)
at ComputedRefImpl.get value [as value] (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:1010:39)
at ReactiveEffect.fn (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/vitepress/dist/client/app/temp/app.js:1279:36)
at ReactiveEffect.run (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:153:29)
at ComputedRefImpl.get value [as value] (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:1010:39)
at Object.unref (/home/runner/work/d3-graph-controller/d3-graph-controller/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js:923:29)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Reproduction
- Use d3 as a dependency.
- Run
vitepress build
Expected behavior
The build passes.
System Info
System:
OS: Windows 10 10.0.22000
CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor
Memory: 14.80 GB / 31.92 GB
Binaries:
Node: 16.13.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.15 - ~\AppData\Roaming\npm\yarn.CMD
npm: 7.20.3 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22000.120.0), Chromium (96.0.1054.62)
Internet Explorer: 11.0.22000.120
npmPackages:
vitepress: 0.20.9 => 0.20.9
Additional context
A reproducing repository is available at https://github.com/DerYeger/d3-graph-controller and a log of the error can be found at https://github.com/DerYeger/d3-graph-controller/runs/4618930216?check_suite_focus=true.
Validations
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
Same thing with my own ESM library. Dev works, but build fails with
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/davay/Documents/ФРУКТ/ФРУКТ/frkt.ru/node_modules/.pnpm/@[email protected]/node_modules/@gun-vue/components/dist/index.js from /Users/davay/Documents/ФРУКТ/ФРУКТ/frkt.ru/.vitepress/.temp/app.js not supported.
The library is packaged as ESM only mjs file and vitepress still tries to require() it and fails.
Same error. But vuepress 0.20.10 works
This is also an issue in vuepress-next https://github.com/vuepress/vuepress-next/issues/617
I opened a PR (#512) to fix this issue, in the meantime this can be fixed by adding a plugin to the Vite configuration:
import { resolve, join } from 'path';
import { writeFileSync } from 'fs';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
{
name: 'add-common-js-package-plugin',
writeBundle(options) {
if (options.format === 'cjs') {
writeFileSync(
join(options.dir, 'package.json'),
JSON.stringify({ type: 'commonjs' })
);
}
},
},
],
});
Edit: I misread the issue, #512 does not fix this problem, sorry for the confusion.
As a workaround, you can use dynamic imports for ESM-only packages. Here is a demo: brc-dd/vitepress-d3-demo.
Arc.vue
in the demo is taken from this article (with modifications).
PS: don't do async import at top level of script as it gets interpreted as async vue component and vitepress will try to require()
it instead of import()
-ing it.
brc-dd/vitepress-d3-demo
Your link top the repo is a 404 for me.
I'd be willing to give it a try and see it if doesn't change the compatibility of the generated modules, but in general I'd prefer to not modify a library for it to be usable in Vitepress/Vuepress. Do you know if this is an inherent issue of the technologies and not solvable in the future?
@DerYeger yeah sorry, forgot to make it public. Check it now.
Do you know if this is an inherent issue of the technologies and not solvable in the future?
It is solvable. I tried working on it but it was taking much time. Someone who has already implemented this in some other framework might be able to fix this proficiently.
in general I'd prefer to not modify a library for it to be usable in Vitepress/Vuepress.
Actually by that workaround you aren't modifying the library, just the way you use it. d3
has got dynamic imports mentioned in their docs too.
@DerYeger yeah sorry, forgot to make it public. Check it now.
Do you know if this is an inherent issue of the technologies and not solvable in the future?
It is solvable. I tried working on it but it was taking much time. Someone who has already implemented this in some other framework might be able to fix this proficiently.
in general I'd prefer to not modify a library for it to be usable in Vitepress/Vuepress.
Actually by that workaround you aren't modifying the library, just the way you use it.
d3
has got dynamic imports mentioned in their docs too.
I see, thank you for the example and response!
I should have worded it differently, as I meant modifying my own library to use the dynamic imports.
d3
is imported in quite a few places there and none of them are async
, so I can't really go with that approach.
For now, I'll wait until Vitepress/Vuepress-next are compatible with ESM-only packages.
I should have worded it differently, as I meant modifying my own library to use the dynamic imports.
d3
is imported in quite a few places there and none of them areasync
, so I can't really go with that approach.
@DerYeger no, you don't need to change your library. If a user needs to use your library with VitePress, then they need to use dynamic imports. Your library d3-graph-controller
works fine with async imports without any changes at your side.
Change Arc.vue
in my example to this:
<template>
<div id="graph" />
</template>
<script setup>
import { onMounted } from 'vue';
import 'd3-graph-controller/default.css';
const generateGraph = async () => {
const { defineGraph, defineGraphConfig, defineLink, defineNodeWithDefaults, GraphController } =
await import('d3-graph-controller');
const a = defineNodeWithDefaults({ type: 'node', id: 'a', label: { color: 'black', fontSize: '1rem', text: 'A' } });
const b = defineNodeWithDefaults({ type: 'node', id: 'b', label: { color: 'black', fontSize: '1rem', text: 'B' } });
const link = defineLink({ source: a, target: b, color: 'gray', label: false });
const graph = defineGraph({ nodes: [a, b], links: [link] });
const container = document.getElementById('graph');
const controller = new GraphController(container, graph, defineGraphConfig());
};
onMounted(generateGraph);
</script>
I should have worded it differently, as I meant modifying my own library to use the dynamic imports.
d3
is imported in quite a few places there and none of them areasync
, so I can't really go with that approach.@DerYeger no, you don't need to change your library. If a user needs to use your library with VitePress, then they need to use dynamic imports. Your library
d3-graph-controller
works fine with async imports without any changes at your side.Change
Arc.vue
in my example to this:<template> <div id="graph" /> </template> <script setup> import { onMounted } from 'vue'; import 'd3-graph-controller/default.css'; const generateGraph = async () => { const { defineGraph, defineGraphConfig, defineLink, defineNodeWithDefaults, GraphController } = await import('d3-graph-controller'); const a = defineNodeWithDefaults({ type: 'node', id: 'a', label: { color: 'black', fontSize: '1rem', text: 'A' } }); const b = defineNodeWithDefaults({ type: 'node', id: 'b', label: { color: 'black', fontSize: '1rem', text: 'B' } }); const link = defineLink({ source: a, target: b, color: 'gray', label: false }); const graph = defineGraph({ nodes: [a, b], links: [link] }); const container = document.getElementById('graph'); const controller = new GraphController(container, graph, defineGraphConfig()); }; onMounted(generateGraph); </script>
Ahh, thank you! I misunderstood what library had to be imported dynamically. I gave it a try in vuepress-next, but it didn't work and I don't have a Vitepress setup right now. So I'll stay with waiting for future changes.
I'm not sure if the same fix applies to Vitepress, but the approach described in https://github.com/vuepress/vuepress-next/issues/585#issuecomment-1046188074 fixes the issue for Vuepresss 2.
Yeah, setting all the non-ESM-ready packages as ssr: { noExternal: ['package-one', 'package-two'] }
fixes the problem! Recent vitepress builds everything just fine! 🔥
@davay42 where should I add that code?
@mesqueeb create a vite.config.js
near your package.json
and paste it there:
import { defineConfig } from 'vite'
export default defineConfig({
ssr: {
noExternal: ['lib-1', 'lib-2']
},
})
@mesqueeb create a
vite.config.js
near yourpackage.json
and paste it there:import { defineConfig } from 'vite' export default defineConfig({ ssr: { noExternal: ['lib-1', 'lib-2'] }, })
I use this cofnig fixed! but has another quesition when render pages : (
![image](https://user-images.githubusercontent.com/9244703/173741967-41f78845-a300-4aa0-894e-1dbf702e5b61.png)
@JobinJia Its happening because you're using some non SSR compatible library or code.
Oh, tks But how should i can find that non SSR library? An can't find some message in build logs : (