Closed patak-dev closed 2 years ago
If I understand correctly, vitepress doesn't want to auto register components by convention as Vuepress does. Is this the case?
Yes, at the moment it's. This is a kind of feature that we would want to tell users to use VuePress instead.
A little background on this. It might subject to change in the future, but for now, VitePress is aiming to be smaller VuePress. Like Lumen for Laravel (if you're familiar with PHP 👀). VitePress should have bare minimal features for authoring docs, and for simple markdown based build system for Vue, and all necessary features like Search, Service Workers, built in to the core, where else VuePress has those features enabled by plugins. That's reason why we're merging features like Carbon Ads.
And also to note, VuePress might integrate with Vite in the future. So that user can get benefits from Vite, with all the powerful features in VuePress (we should consider the naming though 😅).
However, maybe we could provide a script that traverse file system and auto include components inside .vitepress/theme/index.js
(not sure if possible yet), then add that as a recipe in the docs.
What is the recommended way to register the components? I see that in vue-router-next docs they are registered globally inside
enhanceApp
Yes, this is the way to go about it. However, I would really like to make this customization process much more smoother. Currently, creating a whole new theme, is easy but extending the default theme is painful. You have to import theme from vitepress/dist/theme-default
and such.
So yes, we should document this, but before doing that I want to rethink, and refactor how to do the customization. So I guess we can use this issue to discuss about it!
Here's what I'm thinking, but not 100% sure yet.
export default {
Layout: CustomLayout,
NotFound: CustomNotFound,
enhanceApp({ app, router, siteData }) {}
}
Very well. Easy. Good enough.
import Theme from 'vitepress/dist/client/theme' // <- rename to theme instead of default-theme
import CustomComponent from './components/CustomComponent.vue'
export default {
...Theme,
enhanceApp({ app, router, siteData }) {
app.component('CustomComponent', CustomComponent)
}
}
I don't like 'vitepress/dist/client/theme' path... but... hmmm....
import 'vitepress/dist/client/styles' // import global css
import NotFound from 'vitepress/dist/client/theme/NotFound.vue' // Use default NotFound component.
import Layout from './components/Layout.vue' // Use your own layout
export default {
Layout,
NotFound,
enhanceApp({ app, router, siteData }) {
app.component('CustomComponent', CustomComponent)
}
}
And in Layout.vue
<template>
<Layout>
<!-- Inject something to slot -->
<template #page-top>
<p>Hello page top!</p>
</template>
</Layout>
</template>
<script setup>
import Layout from 'vitepress/dist/client/theme/Layout.vue'
</script>
I guess simple enough? Importing global CSS is not that... hmmm...
And also to note, VuePress might integrate with Vite in the future. So that user can get benefits from Vite, with all the powerful features in VuePress (we should consider the naming though 😅).
So using Vite instead in VuePress, and not extending VitePress? Interesting, there could be a lot of duplication in that case 🤔
However, maybe we could provide a script that traverse file system and auto include components inside .vitepress/theme/index.js (not sure if possible yet), then add that as a recipe in the docs.
I like this, if you place it in the theme, you are not polluting the tool. Maybe it can be a config for the theme? Something like:
themeConfig: {
...,
components: './docs/components' // defaults to none
}
(Or componentsDir
, globalComponents
)
+1 for renaming default-theme to theme.
For the paths, it would be great if we could tell users to just use something like the code uses internally
import Theme from '/@theme'
Two ideas about importing the theme, sorry if this was discussed already.
Move the default theme to its own package. So users would import it like
import { Theme, NotFound } from 'vitepress-docs-theme'
This may also help to force vitepress to properly expose everything the default theme uses, so other themes can be play at the same level.
Another option would be to provide a new helper enhanceTheme
(or enhanceDefaultTheme
) that is defined as:
function enhanceTheme(enhanceApp,custom) {
import('../client/styles') // (can we do something like this?)
return {
...Theme,
...custom,
enhanceApp
}
}
So your examples can be written as
Only adding components
import CustomComponent from './components/CustomComponent.vue'
export default enhanceTheme(
({ app, router, siteData }) => {
app.component('CustomComponent', CustomComponent)
}
)
And Extending default theme layout
import Layout from './components/Layout.vue' // Use your own layout
export default enhanceTheme(
({ app, router, siteData }) => {
app.component('CustomComponent', CustomComponent)
},
{ Layout }
)
FWIW, adding this in .md
file should already work:
<script setup>
import CustomComponent from '../components/CustomComponent.vue'
</script>
I just tested it and works fine 👍
I think I tried it before vue 3.0.3, my bad, and that is why it wasn't working.
In my opinion, importing the components you use on a page directly in the .md is quite nice. At least for one-of components (like examples, playgrounds, etc). It would be interesting to document this in the use Vue in markdown guide.
For components like
While you can write HTML directly into the md file, due to the md parsing it becomes almost impossible to do anything which would need any sort of layout.
When trying to get around this issue myself I ended up copying over the entire default theme folder so I could add my custom component to components
and setting it up in enhanceApp
.
I think it needs to be clear and easy for developers to add a custom component. It seems like it's trending to magically load them in when they're needed(Nuxt.js, Vuetify, etc).
I'm not sure about the performance cost of it but having a configurable components
folder in .vitepress
that automatically imported components as you used them, seems like a solid DX improvement.
In the next release you can do
// .vitepress/theme/index.js
import { defaultTheme } from 'vitepress'
import MyGlobalComp from './Comp.vue'
defaultTheme.enhanceApp = ({ app }) => {
app.component('MyGlobalComp', MyGlobalComp)
}
And yes we can consider auto registering components in a directory as global.
Also not sure what you mean by
due to the md parsing it becomes almost impossible to do anything which would need any sort of layout.
since you can use <script>
and <style>
in md files just like in an SFC.
Thanks for the reply @yyx990803 and good to know! That would make life easier.
Sorry for not being clear on the markdown parsing. Previously I had an issue using HTML markup within the markdown file, it was rendering out incorrectly (was moving divs around). I've tried to replicate it now but looks like I can't, so was likely an issue on my end.
Irrelevant to this issue either way.
I use the following pattern currently:
// @ts-ignore
const modules = import.meta.globEager('../components/**/*.vue')
const components = []
for (const path in modules) {
components.push(modules[path].default)
}
export default {
...DefaultTheme,
enhanceApp({ app }) {
components.forEach(component => {
app.component(component.name, component)
})
}
}
Closing since this is documented with details 👍
I am looking into porting the using vue in Markdown from vuepress: https://vuepress.vuejs.org/guide/using-vue.html
If I understand correctly, vitepress doesn't want to auto register components by convention as Vuepress does. Is this the case? I actually liked this feature, but I understand that vitepress wants to keep the moving parts as small as possible.
What is the recommended way to register the components? I see that in vue-router-next docs they are registered globally inside
enhanceApp
: https://github.com/vuejs/vue-router-next/search?q=HomeSponsors. Same as with this comment: https://github.com/vuejs/vitepress/issues/92#issuecomment-724645482Should we document this way in the docs?
Some thoughts about this. It would be great that users that want to use the default theme as is, do not need to learn straight away about enhanceApp to be able to use a vue component in their markdown.
If auto registering by convention in a folder like
.vitepress/components
is not an option, could we import them directly in the markdown?Script & style hoisting is working in vitepress: https://vuepress.vuejs.org/guide/using-vue.html#script-style-hoisting, but I tried this example to import a Component and it is not at this point.