preface

Some time ago I worked on the component library demo and some content hosted by the private NPM package. It was time to have an online document. It is also a closed loop of component library development, leaving some content, convenient myself also hope to give some help to my friends.

Develop vUE component library based on VueCli

Verdaccio builds a private NPM repository

In terms of documentation, vuepress is also used.

Vuepress static web site generator based on Vue. It was created to support the documentation needs of Vue and its subprojects.

So it’s really good to use it. Of course, it can also do some other documents, such as personal blogs, etc.. .

The project preview address and the project address are as follows:

  • preview

  • The source code

start

Create a comp-vuepress project and execute NPM init -y.

Install VuePress as a local dependency.

npm install vuepress -D
Copy the code

3. Create the docs folder in the root directory and create the readme. md file internally, and type in whatever you want.

4. Package. json Adds run scripts and package scripts.

"scripts": {
	"docs:dev": "vuepress dev docs"."docs:build": "vuepress build docs"
}
Copy the code

5. Run NPM run docs:dev vuepress will run the service at http://localhost:8080.

The basic configuration

Create a.vuepress folder in the documents directory, where all vuepress-related files will be stored. Your project structure might look like this:

.├ ─ docs │ ├─ download.download.txtCopy the code

Create config.js in.vuepress. This is a mandatory configuration file for vuepress. An object should be exported with the following content:

module.exports = {
  title: 'comp-vuepress'.description: 'ComP component library documentation. '
}
Copy the code

The navigation bar

There are two main ways to configure the navigation bar: first-level navigation and drop-down list navigation. Change the config. Js.

module.exports = {
  / /... .
  themeConfig: {
    nav: [
      // Level 1 navigation
      { text: 'guide'.link: '/guide/' },
      // Drop-down list navigation
      {
        text: 'Learn more'.items: [{text: 'github'.link: 'https://github.com/ShuQingX/vue-comp-test'.target: '_blank' },
          { text: 'preview'.link: 'https://shuqingx.github.io/vue-comp-test/'.target: '_blank'}}]]// Disable navigation, which is mutually exclusive with the above configuration.
    // navbar: false}};Copy the code

Interlude (Routing)

After the above configuration, I believe that some friends will click on the “guide”, found 404. Mainly /guide/ we are not configured, and VuePress follows the principle of convention over configuration. We need to create a new Guide directory.

.├ ─ ├─ download.txt ├─ download.txt ├─ download.txt ├─ download.txtCopy the code

An 🌰 :

  • /guide/ readme. md finds /guide/

  • /guide.md finds /guide.html

Readme.md is just like index.js in JavaScript, no.

The sidebar

To enable the Sidebar, you need to configure themeConfig. Sidebar. As a basic configuration, you need an array containing multiple links:

In general, sidebars fall into two broad categories, those generated by title and those generated by configuration. The configuration generation method is flexible, and it is strongly recommended to review the document repeatedly.

Configure the build sidebar

1, first create button.md card. md file in guide.

. ├ ─ docs │ ├ ─ ─ the README. Md │ ├ ─ ─ guide │ │ └ ─ ─ the README. Md │ │ └ ─ ─ Button. The md │ │ └ ─ ─ Card. The md └ ─ package. The jsonCopy the code

2. Modify the config.js file

module.exports = {
    themeConfig: {
        sidebar: {
          '/guide/': [[' '.'introduction'].// "is equivalent to /guide/
            {
              title: 'components'.collapsable: false.children: [['.. /guide/Button.md'.'Button'],
                ['.. /guide/Card.md'.'Card'[]}]}}Copy the code

Title generation sidebar

By default, the sidebar automatically displays a link consisting of the headers of the current page, nested according to the structure of the page itself, and you can modify its behavior with themeconfig.sidebardepth.

  • The default depth is 1, which extracts the title of H2;

  • Setting it to 0 disables headers linking;

  • The maximum depth is 2, which will extract both H2 and H3 headings.

Obviously, if we change the configuration file directly, it applies to all files, so we can use YAML Front Matter to override this value for a page:

---
sidebarDepth: 2
---
Copy the code

Rewrite and add a few second – and third-level headings at will, and you’ll get the following

Home page

After all this work, our Guide-related sidebar and navigation bar are now complete. Next, create a homepage like VuePress.

The front page of the default theme provides a set of default configurations. But pay attention to the premise of use.

  • The root level readme.md is present.

  • Home: true is required.

-- Home: true heroImage: /hero.png # heroText: hero Tagline: hero actionText: Get Started → actionLink: / Guide / # Here is the jump link to get Started. features:-Markdown-centric project structure that helps you focus on writing with minimal configuration.-Enjoy the development experience of Vue + Webpack, use Vue components in Markdown, and develop custom themes using Vue.-VuePress pre-renders static HTML for each page and runs as a SPA when the page is loaded.Footer: MIT Licensed | Copyright © 2018 - present Evan You -
Copy the code

Vignettes (Static Resources)

At this point, when you view the service, it is inevitable that the picture does not show the problem. Then change the homeImage value, but only after creating a new public folder in.vuepress to store our static resources.

The structure of the project should look like this:

. ├ ─ docs │ ├ ─ ─. Vuepress │ │ ├ ─ ─ config. Js │ │ └ ─ ─ public │ ├ ─ ─ guide │ │ ├ ─ ─ Button. The md │ │ ├ ─ ─ Card. The md │ │ └ ─ ─ ├ ─ garbage, └─ garbageCopy the code

If you want to use a resource in public, you can directly reference it, for example: /hero.png. Of course, this scheme is not suitable for static resources, because it will not be packaged. Of course, there’s another option, which I won’t show you here.

Episode (Style)

At this point we found that the image was a little too large to be coordinated. And I don’t want the green color of Vue, of course, VuePress still provides a solution.

For styles, theme color changes, create a new styles folder in.vuepress. Note that the internal style file is the stylus file.

  • If you want to modify, add some styles and create a new index.styl in styles. Of course, other CSS files can also be imported. reference

  • If you want to change some presets (built-in CSS variables), create a new palette. Styl in styles. Note: The following variables can be modified

/ / color
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34
$arrowBgColor = #ccc
$badgeTipColor = #42b983
$badgeWarningColor = darken(#ffe564.35%)
$badgeErrorColor = #DA5961

/ / layout
$navbarHeight = 3.6 rem
$sidebarWidth = 20rem
$contentWidth = 740px
$homePageWidth = 960px

// Response change point
$MQNarrow = 959px
$MQMobile = 719px
$MQMobileNarrow = 419px
Copy the code

The structure of the project should look like this:

. ├ ─ docs │ ├ ─ ─. Vuepress │ │ ├ ─ ─ config. Js │ │ ├ ─ ─ styles │ │ │ ├ ─ ─ but styl │ │ │ └ ─ ─ the palette. Styl │ │ └ ─ ─ public │ ├ ─ ─ guide │ │ ├ ─ ─ Button. The md │ │ ├ ─ ─ Card. The md │ │ └ ─ ─ the README. Md │ └ ─ README. Md └ ─ package. The jsonCopy the code

An 🌰 :

  • Suppose we want to change the size of the picture.
.home .hero img
  width: 500px
Copy the code
  • Let’s say we want to modify some variables directly inpalette.stylCan be overwritten.

Markdown syntax extension

Most of you are familiar with markdown’s grammar. Here are some extended grammars in VuePress, most of which are relatively simple. Here we focus on file import.

Components, MD in Vue

Before importing files, we need to know a little bit about:

  • docs/.vuepress/componentsVue components in this directory are automatically registered as global components. In other words, in this folder*.vueCan be in*.mdIs used as a component.

Components /demo-1. Vue

The components/guide/not vue when use is < guide – not > < / guide – not >

  • *.mdChinese will also supportVueTemplate syntax. The reason: The Markdown file will first be compiled into HTML and then passed in as a Vue componentvue-loader

This means you might write the following code.

If you don’t want it to compile, you still extend the syntax with Markdown.

::: v-pre
{{ 1 + 2 }}
:::
Copy the code

Code block import

Suppose we want to complete the documentation for the Button component at this point. First create a guide/button/demo1.js folder to store the demo, and then type in some random code. The syntax for importing is <<< @/ XXX /xx/x

  • <<< specific syntax

  • The default value for @ is process.cwd()

Importing external components (application level configuration)

Official: Since VuePress is a standard Vue app, you can do some app-level configuration by creating a.vuepress/ enhanceapp.js file, which will be imported into the app when it exists. Enhanceapp.js should export default a hook function and take an object containing some application-level properties as an argument. You can use this hook to install additional Vue plug-ins, register global components, add additional routing hooks, etc.

// Using asynchronous functions is also possible
export default ({
  Vue, // VuePress is using the Vue constructor
  options, // Some options to attach to the root instance
  router, // Route instance of the current application
  siteData, // Site metadata
  isServer // The current application configuration is either server rendering or client= > {})/ /... Do some other application-level optimizations
}
Copy the code

Enhanceapp.js plugins can be used, which is essential for writing component library documentation.

The documentation uses Element-UI as an example (the previous component library was based on it anyway).

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

export default ({ Vue, options, router, siteData, isServer }) => {
  Vue.use(ElementUI);
};

Copy the code

Then use the component in button.md.

<el-button type="primary" size="mini">button</el-button>
Copy the code

It was an accident or an accident.

Generally speaking, it is a problem caused by inconsistent dependence. If you are interested, you can look at it. Solutions are as follows:

NPM install [email protected]Copy the code

The plug-in

Plug-ins can use official or community plug-ins, or according to their own needs to develop their own plug-ins. Developing a plug-in

The installation

npm install -D @vuepress/plugin-back-to-top
Copy the code

The plug-in USES

// config.js
module.exports = {
  / /... .
  plugins: ['@vuepress/back-to-top']}Copy the code

How to use vuepress-plugin-demo-container?

Component library documentation

Go to element’s Button and copy the document and put it in our own button.md.

For those of you who may feel that the buttons are a little crowded, the content area is a little narrow, and so on, check out index.styl Palette. Styl palette.

internationalization

If the internationalization configuration is to be implemented, the project structure should look like this. Then inject en/guide/ button.md into the English document.

. ├ ─ docs │ ├ ─ ─. Vuepress │ │ ├ ─ ─ config. Js │ │ ├ ─ ─ styles │ │ │ ├ ─ ─ but styl │ │ │ └ ─ ─ the palette. Styl │ │ └ ─ ─ public │ ├ ─ ─ en │ │ ├ ─ ─ guide │ │ │ ├ ─ ─ Button. The md │ │ │ ├ ─ ─ Card. The md │ │ │ └ ─ ─ the README. Md │ │ └ ─ README. Md │ ├ ─ ─ guide │ │ ├ ─ ─ └. Md │ ├─ ├─ └. Md │ ├─ └Copy the code

The locales option is provided in config.js:

Note that locales. Title locales. Description takes precedence over title description, and a language switch dropdown appears in the upper right corner of the page.

module.exports = {
  locales: {
    '/': {
      lang: 'zh-CN'.title: 'VuePress'.description: 'Vue driven Static Web site Generator '
    },
    // The key name is the subpath to which the language belongs
    // As an exception, the default language can use '/' as its path.
    '/en/': {
      lang: 'en-US'.// Will be set to the lang property of < HTML >
      title: 'VuePress'.description: 'Vue-powered Static Site Generator'}}}Copy the code

Then we need to make changes to the navigation bar, sidebar, and document routing. All of this will be done in themeConfig. Locales.

Pay attention to When configuring the option, the original themeConfig. Nav themeConfig. Change the sidebar themeConfig. Locales. Nav themeConfig. Locales. The sidebar.

modeule.exports = {
  themeConfig {
    locales: {
      '/': {
        selectText: 'Select language'.// Select language Label in the upper right corner of the page
        lebel: 'Simplified Chinese'.// Select value from the language drop-down box in the upper right corner of the page
	nav: [{text: 'guide'.link: '/guide/' },
          // ...].sidebar: {
          '/guide/': [[' '.'introduction'] and {title: 'components'.collapsable: false.children: [['.. /guide/Button.md'.'Button'],
                ['.. /guide/Card.md'.'Card'[]}]}},// Pay attention to route changes when configuring English
      '/en/': {
        selectText: 'Languages'.// Select language Label in the upper right corner of the page
        lebel: 'English'.// Select value from the language drop-down box in the upper right corner of the page
	nav: [{text: 'guide'.link: '/en/guide/' },
          // ...].sidebar: {
          '/en/guide/': [[' '.'Guide'] and {title: 'Components'.collapsable: false.children: [['.. /guide/Button.md'.'Button'],
                ['.. /guide/Card.md'.'Card'[]}]}}}}}Copy the code

release

packaging

I’ve been busy for most of the day and finally packed. Run the NPM run docs:build command. Some of you may encounter the following errors in packing.

The reason is that static HTML is rendered through Node, and we don’t have a good time registering element components. You can change enhanceapp.js to the following:

import 'element-ui/lib/theme-chalk/index.css';

export default async ({ Vue, options, router, siteData, isServer }) => {
  if(! isServer) {await import('element-ui').then(ElementUI= >{ Vue.use(ElementUI); }); }};Copy the code

The packaged files are in /docs/.vuepress/dist

Published to githubPages

1. Log in to Github to create a Repository

2. Add the base option in config.js to set the base to the Repository name

modeule.exports = {
  base: '/comp-vuepress/'
}
Copy the code

3. Create the deploy.sh file in the root directory

#! /usr/bin/env sh

Make sure the script throws any errors it encounters
set -e

Generate static files
npm run docs:build

Go to the generated folder
cd docs/.vuepress/dist

# if publish to custom domain name
# echo 'www.example.com' > CNAME

git init
git add -A
git commit -m 'deploy'

# If posted to https://
      
       .github. IO /
      
# git push -f [email protected]:<USERNAME>/<REPO>.git master:gh-pages

cd -
Copy the code

3. Add a script to package.json and execute it

"scripts": {
    "docs:deploy": "bash deploy.sh"
}
Copy the code

4, then go to Github to check for an additional branch of GH-Pages. Then click Setting to set it

5, then wait two or three minutes, refresh the page, the link turns green and click!