vuejs / vitepress

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

How to use third-party libraries? #603

Closed Tyh2001 closed 2 years ago

Tyh2001 commented 2 years ago

Is your feature request related to a problem? Please describe.

Before, I want to use the third-party component library element-plus in vuepress, which can be directly in clientAppEnhance.ts folder for app Use(). The code is as follows:

import { defineClientAppEnhance } from '@vuepress/client'

import elementPlus from 'element-pus'

export default defineClientAppEnhance(({ app, router, siteData }) => {
  app.use(elementPlus)
})

So how do I use third-party libraries in vitepress?

Describe the solution you'd like

I hope to supplement the detailed configuration of the document. Now the content of the document configuration of vitepress is too few, and it is difficult for novices to get started with vitepress

Describe alternatives you've considered

No response

Additional context

No response

Validations

brc-dd commented 2 years ago

Just create a file .vitepress\theme\index.js having this:

import DefaultTheme from 'vitepress/theme'
import { install } from 'element-plus'
import 'element-plus/dist/index.css'

export default {
  ...DefaultTheme,
  enhanceApp({ app }) {
    install(app)
  }
}

This is documented here: https://vitepress.vuejs.org/guide/theming.html#extending-the-default-theme and mentioned at https://vitepress.vuejs.org/guide/differences-from-vuepress.html#general (last difference).

Refer brc-dd/vitepress-element-plus-demo for complete example.

Tyh2001 commented 2 years ago

thanks~

kasvith commented 2 years ago

Im trying to demo my client-only plugin with vitepress

In theme/index.ts

import DefaultTheme from "vitepress/theme";
import Plugin from "../../../src/plugin";

export default {
  ...DefaultTheme,
  enhanceApp({ app }: any) {
    app.use(Plugin, {
      clientId: import.meta.env.VITE_SOME_ENV,
    });
  },
};

This works fine in the dev mode. On build, it throws an error since my plugin registers a component that uses window object and somehow it triggers on SSR.

I tried removing all the references to any of the components and still issue is there

kasvith commented 2 years ago

OK resolved it using

import DefaultTheme from "vitepress/theme";

export default {
  ...DefaultTheme,
  async enhanceApp({ app }: any) {
    if (!import.meta.env.SSR) {
      const plugin = await import("../../../src/plugin");
      app.use(plugin.default ?? plugin, {
        clientId: import.meta.env.VITE_SOME_ENV,
      });
    }
  },
};
akil-rails commented 2 years ago

Just create a file .vitepress\theme\index.js having this:

import DefaultTheme from 'vitepress/theme'
import { install } from 'element-plus'
import 'element-plus/dist/index.css'

export default {
  ...DefaultTheme,
  enhanceApp({ app }) {
    install(app)
  }
}

This is documented here: https://vitepress.vuejs.org/guide/theming.html#extending-the-default-theme and mentioned at https://vitepress.vuejs.org/guide/differences-from-vuepress.html#general (last difference).

Refer brc-dd/vitepress-element-plus-demo for complete example.

This works, but with the following warning - what does this mean?

vitepress v1.0.0-alpha.4
⠧ building client + server bundles...
(!) Some chunks are larger than 500 KiB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/guide/en/#outputmanualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ building client + server bundles...
brc-dd commented 2 years ago

This works, but with the following warning - what does this mean?

When you install it like that, it doesn't code split. The bundle will include lot of unused JS/CSS. It is recommended to use unplugin-vue-components instead so that the bundle only has the components you're actually using. Refer their official guide for that: https://element-plus.org/en-US/guide/quickstart.html#on-demand-import .

Here I had done this for Arco Design, you just need to change vite.config and update deps there: https://github.com/brc-dd/vitepress-with-arco

akil-rails commented 2 years ago

I tried the steps, but can't seem to get the auto-imports working. Could you help me figure out what's it that I've missed? Neither the element-plus, nor the custom component is getting loaded.

The source is https://github.com/akil-rails/vitepress-with-element-plus

Here I had done this for Arco Design, you just need to change vite.config and update deps there: https://github.com/brc-dd/vitepress-with-arco

brc-dd commented 2 years ago

@akil-rails Do it like this:

// docs/vite.config.js

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    AutoImport({
      include: [/\.vue$/, /\.md$/],
      resolvers: [ElementPlusResolver({ ssr: true })]
    }),
    Components({
      dirs: ['components'],
      include: [/\.vue$/, /\.md$/],
      resolvers: [ElementPlusResolver({ ssr: true })]
    })
  ]
}
akil-rails commented 2 years ago

Thanks!

The component import is working ( I notice that vite.config.js needs to be in docs\ - i thought that project root was ..\docs) )

But there are still issues -

  1. The styles aren't applied (how do I check if they are being over-ridden or not imported at all?)
  2. The chunk error is back, when I run docs:build

Committed the updated code at https://github.com/akil-rails/vitepress-with-element-plus.

brc-dd commented 2 years ago

The base file of theme is not loading when ssr: true. Seems like an issue with either unplugin-vue-components or element-plus itself. Without that ssr thing, I'm getting errors like unknown file extension '.css'. 🤔

akil-rails commented 2 years ago

The theme loads with ssr: false, but yes, then pnpm build fails with the following error

✓ building client + server bundles...
⠋ rendering pages...Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/akhileshkataria/Code/spikes/vitepress-with-element-plus/node_modules/.pnpm/element-plus@2.2.13_vue@3.2.37/node_modules/element-plus/es/index.mjs not supported.
Instead change the require of /Users/akhileshkataria/Code/spikes/vitepress-with-element-plus/node_modules/.pnpm/element-plus@2.2.13_vue@3.2.37/node_modules/element-plus/es/index.mjs to a dynamic import() which is available in all CommonJS modules.
    at Module.<anonymous> (/Users/akhileshkataria/Code/spikes/vitepress-with-element-plus/docs/.vitepress/.temp/index.md.js:3:10)
    at /Users/akhileshkataria/Code/spikes/vitepress-with-element-plus/docs/.vitepress/.temp/app.js:4045:50
    at async loadPage (/Users/akhileshkataria/Code/spikes/vitepress-with-element-plus/docs/.vitepress/.temp/app.js:216:16) {
  code: 'ERR_REQUIRE_ESM'

Is this related ? - https://github.com/antfu/vite-ssg/discussions/232

brc-dd commented 2 years ago

ESM is not supported on VitePress now anyway. I was using Vite 3 version, there the error was different:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".css"

Is this related ? - https://github.com/antfu/vite-ssg/discussions/232

It can be, though I doubt this is an issue with vite-ssg. Feel free to create a separate issue here, I'll take a look if I get time.

akil-rails commented 2 years ago

Okay - will do..Thanks!

akil-rails commented 2 years ago

Is https://github.com/vuejs/vitepress/issues/476#issuecomment-1046189073 related ? With the following config, but I guess it's skipping the SSR completely?

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    AutoImport({
      include: [/\.vue$/, /\.md$/],
      resolvers: [ElementPlusResolver()],
    }),    
    Components({
      dirs: ['components'],
      include: [/\.vue$/, /\.md$/],
      resolvers: [ElementPlusResolver({ ssr: false })]
    })
  ],
   ssr: { noExternal: ['element-plus'] }
}
brc-dd commented 2 years ago

With the following config, but I guess it's skipping the SSR completely?

@akil-rails Is it working fine? And, no it doesn't skip SSR. It will sort of transpile element-plus with Vite that may slow the build process but its a valid fix if it works.

akil-rails commented 2 years ago

pnpm build gives a warning

vitepress v1.0.0-alpha.4
⠦ building client + server bundles...warnings when minifying css:
▲ [WARNING] "@charset" must be the first rule in the file

    <stdin>:3820:0:
      3820 │ @charset "UTF-8";:root{--el-color-white:#ffffff;--el-color-black...
           ╵ ~~~~~~~~

  This rule cannot come before a "@charset" rule

    <stdin>:1:0:
      1 │ @font-face {
        ╵ ^

& the styling for the table is a bit-off , but at-least it builds.

Committed the code at https://github.com/akil-rails/vitepress-with-element-plus.

Could you have a look if you get time?

brc-dd commented 2 years ago

& the styling for the table is a bit-off , but at-least it builds.

The large chunk warning is gone too, but still I can see 20+ components (earlier were 150+) in the generated file, maybe they depend on each other, that should be fine IG.

Regarding that charset warning, it's fine to ignore it. If you wanna suppress this, you can remove charset by adding something like this: https://github.com/vitejs/vite/discussions/5079#discussioncomment-1890839 in your vite.config (or postcssrc if you have one)

Also, regarding that no external thing, it was needed in case of arco too.

akil-rails commented 2 years ago

Thanks - that removed the warning - should we close https://github.com/vuejs/vitepress/issues/1164 ?

Committed to https://github.com/akil-rails/vitepress-with-element-plus.

brc-dd commented 2 years ago

should we close https://github.com/vuejs/vitepress/issues/1164 ?

No, let's keep it open. It should probably work without noExternal in Vite 3 version, but it isn't. We need to track that. We won't be tracking ssr: true thing (no base styles) because it has something to do with unplugin-vue-components' element plus resolver. I might create an issue there later.