vuejs / vitepress

Vite & Vue powered static site generator.
https://vitepress.dev
MIT License
12.35k stars 2.01k forks source link

build error with @antv/g2plot #4021

Closed peiyanlu closed 1 month ago

peiyanlu commented 1 month ago

Describe the bug

vitepress 打包和 vite 存在一些差异,我在项目中使用 @antv/g2plot,如果使用 vite 可以正常编译,使用 vitepress 编译则会失败。 尽管我可以将 @antv/g2plot 的依赖指定低版本避免这个错误,但是我想知道为什么会出现这种情况;

en:There are some differences between vitepress compilation and vite, I use @antv/g2plot in my project, if I use vite it compiles fine, if I use vitepress it compiles fine, I use vitepress to compile it fails. Although I could avoid this error by specifying the dependency of @antv/g2plot at a lower version, I wonder why this is the case

Reproduction

  1. Create a new Vite+Vue project

  2. Add @ antv/g2plot dependency and use word cloud diagram in the component, for example: https://g2plot.antv.antgroup.com/examples/more-plots/word-cloud#same -place

  3. Preview effect, compile project, compile normally

  4. Install vitepress v1.2.3, initialize

  5. Create a component usage word cloud and import it in the document

  6. Compile document, compilation failed

https://github.com/peiyanlu/vite-test-antv

Expected behavior

build success

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13980HX
    Memory: 10.03 GB / 31.63 GB
  Binaries:
    Node: 18.16.0 - C:\Program Files\nodejs\node.EXE
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.4.0 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (126.0.2592.87)
    Internet Explorer: 11.0.26100.1
  npmPackages:
    vitepress: ^1.2.3 => 1.2.3

Additional context

No response

Validations

shellRaining commented 1 month ago

Add some info here, add @antv/g2plot from npm first, then write a test code

<script lang="ts" setup>
import { onMounted, ref } from "vue";
import { WordCloud } from "@antv/g2plot";

const container = ref<HTMLElement | null>(null);
onMounted(() => {
  fetch("https://gw.alipayobjects.com/os/antfincdn/jPKbal7r9r/mock.json")
    .then((res) => res.json())
    .then((data) => {
      if (!container.value) {
        return;
      }
      const wordCloud = new WordCloud(container.value, {
        data,
        wordField: "x",
        weightField: "value",
        color: "#122c6a",
        wordStyle: {
          fontFamily: "Verdana",
          fontSize: [24, 80],
        },
        interactions: [{ type: "element-active" }],
        state: {
          active: {
            style: {
              lineWidth: 3,
            },
          },
        },
      });

      wordCloud.render();
    });
});
</script>

<template>
  <div ref="container"></div>
</template>

in dev mode it not occur error message, but when build by type command pnpm run docs:build, error msg below

build error:
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/shellraining/Documents/blog/node_modules/.pnpm/d3-interpolate@3.0.1/node_modules/d3-interpolate/src/index.js from /Users/shellraining/Documents/blog/node_modules/.pnpm/@antv+g-base@0.5.16/node_modules/@antv/g-base/lib/animate/timeline.js not supported.
Instead change the require of index.js in /Users/shellraining/Documents/blog/node_modules/.pnpm/@antv+g-base@0.5.16/node_modules/@antv/g-base/lib/animate/timeline.js to a dynamic import() which is available in all CommonJS modules.
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at Object.<anonymous> (/Users/shellraining/Documents/blog/node_modules/.pnpm/@antv+g-base@0.5.16/node_modules/@antv/g-base/lib/animate/timeline.js:5:24)
 ELIFECYCLE  Command failed with exit code 1.
brc-dd commented 1 month ago

Try adding it to vite.ssr.noExternal

shellRaining commented 1 month ago
  vite: {
    ssr: {
      noExternal: ["@antv/g2plot"]
    }
  }

after add the above code to .vitepress/config.mts, it passed the build process, but there were some warning messages.

✓ building client + server bundles...
⠸ rendering pages...ReferenceError: window is not defined
    at setup (file:///Users/shellraining/Documents/blog/.vitepress/.temp/app.js?t=1720604065619:62991:41)
    at _sfc_main$2.setup (file:///Users/shellraining/Documents/blog/.vitepress/.temp/app.js?t=1720604065619:63040:25)
    at callWithErrorHandling (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+runtime-core@3.4.26/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:82:19)
    at setupStatefulComponent (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+runtime-core@3.4.26/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:6048:25)
    at setupComponent (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+runtime-core@3.4.26/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:6035:36)
    at renderComponentVNode (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+server-renderer@3.4.26_vue@3.4.26_typescript@5.4.5_/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:358:15)
    at ssrRenderComponent (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+server-renderer@3.4.26_vue@3.4.26_typescript@5.4.5_/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:84:10)
    at _sfc_ssrRender (file:///Users/shellraining/Documents/blog/.vitepress/.temp/tags.md.js?t=1720604065893:9:9)
    at renderComponentSubTree (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+server-renderer@3.4.26_vue@3.4.26_typescript@5.4.5_/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:430:9)
    at renderComponentVNode (/Users/shellraining/Documents/blog/node_modules/.pnpm/@vue+server-renderer@3.4.26_vue@3.4.26_typescript@5.4.5_/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js:376:12)

I am not familiar with the ssr feature of Vue. Not sure why this warning message is displayed.

brc-dd commented 1 month ago

Seems like that library doesn't support SSR, and is accessing window on import. You can probably try something like this:

import { onMounted, ref } from "vue";

const container = ref<HTMLElement | null>(null);
onMounted(() => {
  import('@antv/g2plot').then(({ WordCloud }) => {
    fetch ...
  })
})
shellRaining commented 1 month ago

Using dynamic import still did not solve the problem, but this will not have too much impact, after all (I think)😄

brc-dd commented 1 month ago

Weirdly enough, your code above is working fine for me without any window is undefined error. So, it might be coming from some place else. If you can share a reproducible example using https://vitepress.dev, I might be able to help.

shellRaining commented 1 month ago

I'm sorry, it was my own configuration error. I accidentally removed the <ClientOnly> wrapper for a component, which caused this issue. I think the issue has been resolved, very thanks!!!

brc-dd commented 1 month ago

Closing this then. vite.ssr.noExternal is the recommended solution unless they fix it upstream. Please track/upvote https://github.com/antvis/G2Plot/issues/3780 -- https://publint.dev/@antv/g2plot@2.4.31