Repository structure

$ tree -I "node_modules"-l 2. ├ ─ ─ BACKERS. Md ├ ─ ─ CODE_OF_CONDUCT. Md ├ ─ ─ Dockerfile ├ ─ ─ LICENSE. The md ├ ─ ─ MIGRATION. The md ├ ─ ─ the README. Md ├ ─ ─ SECURITY. - - Crowdin.yml. ├── nerf-win.config.js. ├── nerf-wsl.config.js Eslint-local-rules.js ├── jest.config.js ├── lerna. Json ├── Package.json ├─ PackagesMonorepo management is divided into three small packages│ ├── README. Md │ ├── API - Generator │ ├─ docs# documentation packages│ └ ─ ─ vuetify# vuetify framework source code├ ─ ─ scripts │ ├ ─ ─ build. Js │ ├ ─ ─ confirm - NPM - tag. Js │ ├ ─ ─ the converter. The js │ ├ ─ ─ the deploy - and - alias. Js │ ├ ─ ─ the deploy. Sh │ ├ ─ ─ ├─ Parse-npm-tag.js │ ├─ Heavy Metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├─ heavy metal Exercises │ ├── prepare-commit-message.js │ ├── warn-npm-install.js │ ├── tsconfig.json ├─ vercel └ ─ ─ yarn. The lockCopy the code

Use the Yarn workspace mode to manage dependencies

package.json

  "private": true."workspaces": [
    "packages/*"].Copy the code

Lerna is used to deal with the dependency between the three packages

// TODO

The Vuetify repository is a lerna monorepo that connects the vuetify library, docs, api generator, and reduces the friction of working with multiple projects at once. The following guide is designed to get you up and running in no time.

/pacakges/doc

The research focuses on

  1. How do you handle routing generation by documents
  2. How are interactive components parsed and rendered in a document
# /vuetify/packages/docs/src/pages/en$tree -l 1 ├── about │ ├── Code-of-conduct.md │ ├── Meet-the-team.md │ ├── Securit-disclosure.md │ ├─ List-by-list.md │ ├── app-bars. Md │ ├─ application. Md │ ├── app-bars. Md │ ├─ application ├ ─ ─ autocompletes, md# The next level is omitted├── Features ├─ Getting-started ├─ HOMe.md ├─ introduction ├─ resources ├─ stylesCopy the code

In addition to the content in the API, Vuetify’s official document is written and stored here with *.md

The API is likely to be quite variable and strongly related to the data organization within Vuetify, so use

├ ─ ─ packages# monorepo│ ├── README. Md │ ├── API - Generator# This is generated
Copy the code

Take Alert as an example

The corresponding

## Usage

Alerts in their simplest form are a flat [sheets of paper] (/components/sheets) that display a message.

<usage name="v-alert" />
Copy the code

The route is generated according to apI-generator && Packages /docs/ SRC /pages/**/*.md

The interactive Component is based on parsing the MD (x) content -> referencing the written Component based on some tag in the content

(This set has a complete ecology in Gatsby)

Routes generating logic

packages/docs/src/router/index.js

import {
  abort,
  layout,
  locale,
  redirect,
  route,
  trailingSlash,
} from '@/util/routes'

export function createRouter (vuetify, store, i18n) {
  const loadedLocales = ['en']
  const router = new Router({
    mode: 'history'.base: process.env.BASE_URL,
    scrollBehavior: (. args) = >scrollBehavior(vuetify, store, ... args),routes: [
      locale([
        ...Object.keys(redirects).map(k= > ({
          path: k.replace(/ ^ / / /.' '),
          redirect: () = > redirects[k].replace(/ ^ / / /.' '),
        })),
        layout('Home', [route('Home')]),
        layout('Default', [route('Documentation')].':category/:page/'),
        layout('Wireframe', [route('Wireframes'.'examples/wireframes/:wireframe/')]),
        layout('Default', [abort()]),
      ]),
     // ...

Copy the code

/Users/sedationh/workspace/source/vuetify/packages/docs/src/util/routes.js

export function layout (name = 'Default', children = [], path = ' ') {
  const dir = kebabCase(name)

  return {
    children,
    component: () = > import(
      /* webpackChunkName: "layout-[request]" */
      `@/layouts/${dir}/index.vue`
    ),
    path,
  }
}
  
  export function route (name, path = ' ', strict = true) {
  return {
    name,
    component: () = > import(
      /* webpackChunkName: "views-[request]" */
      `@/views/${name}`
    ),
    path,
    pathToRegexpOptions: { strict },
  }
}
Copy the code

layout('Default', [route('Documentation')], ':category/:page/'),

Layout (‘ Default ‘- > packages/docs/SRC/layouts/Default/index. The vue as the father of the specific content of the document

Content (* md) itself using packages/docs/SRC/views/Documentation. The vue as a template

MDX parsing logic

packages/docs/src/views/Documentation.vue

  export default {
    name: 'DocumentationView'.async asyncData ({ route, store }) {
      const md = await load(route)

      store.state.pages.md = md
    },
    
    // ...
    
    computed: {
      ...sync('pages'['frontmatter'.'toc'.'md',),... get('route'['hash'.'params@category'.'params@page',]),},async created () {
      if (IN_BROWSER && !this.$vuetify.isHydrating) {
        await this.$options.asyncData({
          route: this.$route,
          store: this.$store,
        })
      }

      this.init(this.md)
Copy the code

Both SSR and client generation are supported

Get the local file (API-gen) first

  async function load (route) {
    const { category, page } = route.params
    const isApi = category === 'api'
    const locale = localeLookup(route.params.locale)

    const context = isApi
      ? await import(
        /* webpackChunkName: "api-[request]" */
        `@/api/${locale}.js`
      )
      : await import(
        /* webpackChunkName: "documentation-[request]" */
        `@/pages/${locale}.js`
      )

    const path = ['. ']

    if(! isApi) path.push(category) path.push(page)try {
      return context.default(`${path.join('/')}.md`)}catch (err) {
      return {
        vue: {
          component: (await error()).default,
        },
      }
    }
  }
Copy the code

But how does the parent of document get all the routes?

Here, although the view and data (MD) mapping is completed, it is not complete to obtain the entire list

Go to the Default Drawer for treatment

packages/docs/src/layouts/default/Drawer.vue

      drawer: sync('app/drawer'),
Copy the code

Well, it depends on the store

packages/docs/src/store/modules/app.js

// Data
const state = {
  branch: getBranch(),
  categories: {
    api: {
      icon: '$mdiFlaskOutline'.color: 'orange',},components: {
      icon: '$mdiViewDashboardOutline'.color: 'indigo darken-1',},features: {
      icon: '$mdiImageEditOutline'.color: 'red',},directives: {
      icon: '$mdiFunction'.color: 'blue-grey',},'getting-started': {
      icon: '$mdiSpeedometer'.color: 'teal',},introduction: {
      icon: '$mdiScriptTextOutline'.color: 'green',},about: {
      icon: '$mdiVuetify'.color: 'primary',},resources: {
      icon: '$mdiTeach'.color: 'pink',},styles: {
      icon: '$mdiPaletteOutline'.color: 'deep-purple accent-4',},themes: {
      icon: '$mdiScriptTextOutline'.color: 'pink',}},drawer: null.nav: [].scrolling: false.search: false.settings: false.version: null,}Copy the code

It turned out to be pre-written

There is no file reading from the dynamic list through Node