Closed DerYeger closed 1 year ago
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/@gun-vue+components@0.3.1/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 : (
@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 : (
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:Reproduction
vitepress build
Expected behavior
The build passes.
System Info
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