Design Concepts of VuePress 1.x

The design concepts of VuePress 1.x are mainly reflected in the following aspects:

  1. Pluggable.
  2. Convention over configuration.
  3. Reasonable priority management.

Pluggable

VuePress 1.0 has been rewritten extensively, and the most important one is the introduction of the Plugin API. What are the benefits of plugins?

Decoupling

With plugins, we can implement many of the core functions with plugins, and you can see many built-in plugins here that cover many of the core functions of VuePress, which used to blend in all parts of the code base, but now they’re clear at a glance.

Configuration management

In the past, when we came across some less common requirements, we had some doubts: if we wanted to not support it, VuePress usage scenarios were limited; but if we wanted to support it, we had to write it into the core code base and set up a separate configuration API for it. For the maintainers, apart from not conducive to long-term maintenance, this sometimes makes us feel exhausted. We must think of some better solutions. Yes, this is plugin.

.vuepress/config.js is also a plugin

Yes, your configuration file is also a plugin, so you can use the Plugin API directly without having to create a new plugin for it and import it in the configuration.

The options supported by .vuepress/config.js are actually based on the plugin options and add some specific options.

theme/index.js is also a plugin

The root configuration file of the theme is also a plugin.

As with .vuepress/config.js, the options supported by theme/config.js are based on the plugin options and add some specific options. Using a graph to express their relationship:

Created with Sketch. .vuepress/ config.js Plugin API theme/ index.js

Apply plugins in a plugin

In VuePress, you have the ability to apply some plugins in a plugin:

// vuepress-plugin-xxx
module.exports = {
  plugins: [
    'a', 'b', 'c'
  ]
}

Convention over configuration.

VuePress 1.0 begin to introduce some conventions to reduce the user’s excessive configuration pressure, the most intuitive manifestation of this is the conventions for the document directory structure and the theme directory structure.

In the future, we may combine community feedback to introduce more agreements. Let’s wait and see.

Reasonable priority management.

Senior users have found that both theme developers and regular users have the ability to customize global palettes, styles, templates and plugins, so how do they work together?

Loading Priority

For templates/*, follow the certain loading priority. Taking templates/ssr.html as an example:

@flowstart cond1=>condition: User’s ssr.html exists? cond2=>condition: Theme’s ssr.html exists? stage1=>operation: Using user’s ssr.html stage2=>operation: Using theme’s ssr.html stage3=>operation: Using default ssr.html

cond1(no, right)->cond2(no)->stage3 cond1(yes, bottom)->stage1 cond2(yes, bottom)->stage2 @flowend

Note

When customizing templates/ssr.html, or templates/dev.html, it’s best to edit it on the basis of the default template files, otherwise it may cause a build failure.

Overriding

For palette.styl, index.styl and plugins, follow the principles of overriding:

palette.styl

User’s styles/palette.styl has a higher priority than the theme’s styles/palette.styl, so the theme can define its own palette and the user can tweak it. For example:

// theme/styles/palette.styl
$accentColor = #0f0
// .vuepress/styles/palette.styl
$accentColor = #f00

So the final value of $accentColor is #f00.

index.styl

Both the user’s styles/index.styl and the theme’s styles/index.styl are generated into the final CSS file, but the user’s style is generated later and therefore has higher priority. For example:

// theme/styles/index.styl
.content
  font-size 14px
// .vuepress/styles/index.styl
.content
  font-size 15px

The final generated CSS is as follows:

/* theme/styles/index.styl */
.content {
  font-size: 14px;
}

/* theme/styles/index.styl */
.content {
  font-size: 15px;
}

plugins

Since all plugins with the same name can be applied ONLY once by default, users can override the default options for plugins in theme. For example:

// theme/index.js
module.exports = {
  plugins: [
    'vuepress-plugin-xxx',
    { name: 'foo' }
  ]
}
// .vuepress/config.js
module.exports = {
  plugins: [
    'vuepress-plugin-xxx',
    { name: 'bar' }
  ]
}

Then the final value of name option will be bar.

Others

With the goal of decoupling, we were able to separate VuePress into the following two libraries by introducing monorepo:

Of course, for most users, you don’t need to worry about these three libraries. The VuePress package has already assembled them together, so you can use VuePress like 0.x.