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
- How do you handle routing generation by documents
- 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