vuejs / vitepress

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

Theme is made into npm package, if use the theme, Symbol is duplicated in dev. #3292

Open zycoJamie opened 9 months ago

zycoJamie commented 9 months ago

Describe the bug

Custom theme is a npm package, layout of the theme is following:

// myTheme/src/index.ts
import type { Theme } from "vitepress";
import { configProvider } from "./compositions/configProvider";
import Layout from "./components/layout/index.vue";

const pureTheme: Theme = {
  Layout: configProvider(Layout),
};

export default pureTheme;

configProvider's source is following:

//  myTheme/src/compositions/configProvider.ts
export const themeConfig: InjectionKey<PureThemeConfig> = Symbol("themeConfig");

export const configProvider = (component: Component) => {
  return defineComponent(() => {
    const { theme } = useData();
    provide(themeConfig, theme.value); // Notice this line
    return () => h(component, null, {});
  });
};

themeConfig is a Symbol in configProvider.

when i setup vitepress and use custom theme in development "vitepress dev", i get an error.

// doc/.vitepress/theme/index.ts
import pureTheme from "vitepress-pure-theme-zyco";
export default pureTheme;

In .vitepress/cache/deps, myTheme.js has a duplicated themeConfig variable.

but in Layout.vue it uses Header and Header uses themeConfig that is a Symbol:

// Layout.vue
<template>
  <Header :nav="Navlist"></Header>
</template>

<script setup lang="ts">
import Header from "../header/index.vue";
</script>
// Header.vue
<script setup lang="ts">
import { inject, computed } from "vue";
import { themeConfig } from "../../compositions/configProvider"; // Notice this line

const theme = inject(themeConfig)!; // Notice this line

In Header.vue, themeConfig exists in myTheme/src/compositions/configProvider.ts, but in .vitepress/cache/deps/myTheme.js, it also exits a themeConfig. two themeConfig, two Symbol. In the result, provide/inject is fail. 1701791132313

In development this is bad, in production, the configProvider module is not extracted, the themeConfig variable is unique.

Reproduction

as mentioned earlier

Expected behavior

In development, some es module that come from node_modules ain't extracted, the variable don't be duplicated.

System Info

System:
    OS: Windows 11 10.0.22000
  Binaries:
    Node: 18.16.0
    pnpm: 8.6.0
  npmPackages:
    vitepress: 1.0.0-rc.31

Additional context

No response

Validations

brc-dd commented 8 months ago

You probably need to add your theme to vite.ssr.noExternal in config. Can you share a repo where I can reproduce this?

zycoJamie commented 7 months ago

I write following code in my theme config,

vite: {
  optimizeDeps: {
  exclude: ["my-theme-name"],
},

The error is resolved, but is it bug of vite's "optimizeDeps"? The variable of Symbol is extracted and it is duplicated.