Closed ulivz closed 6 years ago
nice to centralize info :) .
I'll just finish to create a vue cli plugin for vuepress maybe add that inside project features. https://github.com/dgpgdev/vue-cli-plugin-vuepress
Before work algolia docsearch maybe merge pullrequest validated. I don't think blog are useless... vuepress is perfect for documentation.
One extra thing we need to finalize in core: API for custom themes to write additional files during build.
so for some of our new features, we should consider whether it is handled in 1 or 2.
Or we can implement things in a theme, then once they are proven or popular look to migrating them into the core. As long as the core is flexible enough for themes to do this extra useful common features can be backported into the core so that more themes can take advantage of them.
For these, we need a way for themes to write additional files like @yyx990803 suggests. I have attempted to introduce this in #196 but we should probably take about the implementations details a bit more. In short, it loads themeDir/index.js
and .vuepress/index.js
and expects them to export a function that takes {options}
as an argument. This function runs in the context of the server as part of the prepare method so has access to write files to the outDir
and otherwise manipulate the set options before the site is generated (allowing injection of extra headers or other things).
One thing it does not expose is a way to hint to the build about extra routes that should be generated (such as routes added in enchanceApp.js like in #143)
@mdaffin @dacsang97 Thanks for your two guys' contribution for the plugin support (#196 & #216). Let me summarize for that here.
Obviously, VuePress core's prepare process is only to do some pre-build
work for the default theme. When user need to extend some data or do some specific generate work before building, plugins come in handy. So we should consider what can be changed by the developer of the plugin.
So the options
should not be exposed directly, especially such values that are not allowed to be modified, such as sourceDir
, outDir
, plugin system shouldn't let plugins to have permissions to modify them. So it would be better to create a shallow-cloned options to expose:
interface exposedOptions {
sourceDir: string; // readable
outDir: string; // readable
publicPath: string; // readable
markdown: Object; // readable
themePath: string; // readable, theme component entry
useDefaultTheme: boolean; // readable
notFoundPath: string; // readableļ¼404 component entry
siteConfig: Object;
pageFiles: string[]; // A list containing relative paths of source makrdown files
siteData: Object;
}
interface Page {
path: string;
title: string;
headers: Array<{ level: number, title: string, slug: string }>;
frontmatter: { [key: string]: string };
}
interface siteData {
title: string,
description: string,
base: string,
pages: Page
}
At the moment, I found out that both of yours put the excution timing at the end of prepare
. I agree that at least we can ensure that the core is stable enough. and @yyx990803 what do you think about this?
Obviously, I think everyone supports pure function API, However, at this stage we have two optionsļ¼
The extra pluginOptions
was mixed into the exposed options object.
module.exports = ({siteConfig, siteData, pageFiles, pluginOptions}) => {}
Also from @dacsang97:
module.exports = (pluginOptions) => ({siteConfig, siteData, pageFiles}) => {}
Let's vote:
It is worth mentioned that the plugin should support the async function
and return Promise
.
User can add extra plugins via plugins
field at docs/.vuepress/config.js
, there are 4 optional types of usage:
module.exports = {
plugins: [
require('./rssPlugin.js')
]
}
String in Array
module.exports = {
plugins: [
'pluginName', // will to load 'vuepress-plugin-${pluginName}'
'vuepress-plugin-rss', // also support full name
]
}
Array in Array (Babel Style)
This configuration style comes from babel:
module.exports = {
plugins: [
[
'rss',
{
option1: '1',
option2: '2'
// ...
}
]
]
}
This configuration style comes from @dacsang97:
module.exports = {
plugins: {
resolve: 'rss', // resolve => 'name' ?
options: {
option1: '1',
option2: '2'
}
}
}
I think that the first two style are sure to support. so we need to make choices in the latter two:
Thank you for all of your guys' participation!
I had implemented to run Function
and AsyncFunction
https://github.com/dacsang97/vuepress/blob/673cc2e44d6f1694d21ef855aaadc2b73de7e5eb/lib/prepare.js#L79L82
Do you think we should support Generator Function
?
@dacsang97 I have seen your change, cool, butGenerator Function
is unnecessary. maybe you can add support for return Promise
.
- Figure out the responsibility of plugin.
I agree on the options side, my pull request was just an experiment to figure out what would be required. Your object looks reasonable but I think it might be worth adding a routes: []
section to allow plugins to hint to the ssr additional routes that it should attempt to render that don't have corresponding markdown files (ie more dynamic components added by the theme). This might want to live inside siteData
though.
It is also worth adding a base URL to siteData
as a number of plugins require this value (RSS feeds, sitemaps etc) and being able to inject this at build time is also worthwhile (for example for changing it during netlifys preview deploys).
- Deciding on the plugin's API.
I vote for 1. First-order function as it looks cleaner to plugin developers and it is only ever going to be a run once function.
- Deciding on the usage of plugins
I prefer the Object in Array like the way Nuxt does it:
module.exports = {
plugins: [
{ src: '~/plugins/vue-notifications', ssr: false }
]
}
Keeping things similar to Nuxt is a good way to go as I suspect there will be a crossover of the user base here.
Also, what about theme/site plugins? ie ones that are baked into a theme or site like in my original implementation. I think we can get rid of the site ones as that is covered by the plugins array in the config, but there should be a way for themes to add to the list of plugins, maybe a config.js
inside the theme? Or just treat the theme as a plugin (as my implementation does)?
i agree with @ulivz, if anyone can write a plugin we need to secure input data. i agree too with @mdaffin to expose plugin as nuxt way.
i love how vue cli use plugin maybe can we use same for vuepress to install and manage plugin .
i agree, but often we need same configuration (rssfeed, sitemap...) (vue cli presets) for many project. yarn add vuepress-plugin-<plugin>
is correct too. I try to think of what is simpler to use.
@dgpgdev all dependencies of a project should be inside the package.json
for that project and there should be no side effects from globally installed packages (or you end up wot the 'It works for me' problem).
If you want to use the same plugins/base structure for many projects you should use vue cli to create a template for vuepress with all your plugins and desired config in the template. Vuepress does not need to know or understand vue cli at all and yarn/npm are the tools you should be using for managing project level dependencies.
as vue-cli is moving away from templates, it makes sense to create a vue-cli plugin that create a vuepress project with a bunch of vuepress plugin options to be selected during vue create
.
@ycmjason i made a vuepress plugin for vue/cli ;) , maybe include inside plugin an input prompt to add plugin after created template.
@mdaffin you're rigth ;)
Another point to consider: allowing plugins a hook into the client side code to allow them to register new dynamic components or otherwise change the client-side behaviour in a similar way to the enhanceApp.js
currently does.
Based on the results of the voting, I had updated plugin API to first-order function
, use Babel style
for configuring extra options. Now plugin support return Promise (5cdb744). Then I clone options
to exposedOptions
in order to avoid user modify system config (8aec214).
+1 for Additional content sources... such as Contentful, WordPress Headless etc at build time!
A lot of the static site generators hook to data-driven content sources, such as headless headless CMS like DatoCMS, StoryBlok, Netlify, Snipcart, ButterCMS, etc. Some have RESTful API's, some provide GraphQL.
For my less technical staff, I was considering a headless CMS for topic editing as opposed to a Markdown or AsciiDoc file editor.
One cloud CMS which would integrate quite easily is Dato, which āin addition to REST and soon GraphQL APIsā provides a workflow where all content can be 'dumped' to markdown files and then processed by a further the build process
I am currently trying to finagle a workflow for DatoCMS import at build time that involves another SSG running a build, then grabbing JSON from that build to add to VuePress. To have Dato or other headless CMSs import-able (?) and configurable directly within VuePress would be amazing.
@EnMod check out this dato documentation WRT metalsmith, it walks through how to dump your data in to markdown files, and it should give you an idea how to configure the script to output in the directory / naming scheme required by VuePress.
https://www.datocms.com/docs/metalsmith/
Alternately you can dump Dato data to YML or JSON, and just require()
them in to your app, as this is also supported by webpack
@lunelson Thanks for that, very nifty! I'm managing a slider gallery as one of my models, so I might either:
v-for
Either way, metalsmith's integration a good solution. Having DatoCMS's data right there in VuePress, ready at build time, would save quite a bit of trouble though haha.
Hey guys, about the next direction or planning of VuePress, specially set up a "channel" to discuss here.
Above all, we need to make clear that the original intention of VuePress is to write documents to Vue and its sub projects. As mentioned in the document, VuePress is composed of two parts:
If we leave everything to the default theme, then when you decide to develop a new theme, you would repeat many things. so for some of our new features, we should consider whether it is handled in
1
or2
.In fact, I expect to complete the development of the core functionality as soon as possible, Only core is STABLE can we focus on migrating the documents and blog theme development (Maybe need to create a separate repo called
vuepress-theme-blog
). Of course, the premise is that we have prepared useful enough data and APIs for the beginning of the custom theme.At present, the core function I think is probably only Algolia DocSearch Integration. If you think there are other deserved suitable core needs, feel free to tell us here.
Regards, Thanks.
Radmap