什么是vue技术站点(Vue组件库文档站点的搭建思路)
如何快速创建一个网页文件某视频剪辑软件组件库文档站点的搭建思路
本文为恶棍组件库源码主题阅读系列第四篇,读完本篇,可以了解到如何使用轻快地的美国石油学会(美国石油协会)接口来启动服务、如何动态生成多语言的页面路由。
恶棍的文档网站其实就是一个某视频剪辑软件项目,整体分成两个单独的页面文档页面及手机预览页面。
网站源代码文件默认是放在varlet-cli目录下,也就是脚手架的包里
执行脚手架提供的偏差命令时会把这个目录复制到varlet-ui/.恶棍目录下,并且动态生成两个页面的路由配置文件
然后使用轻快地启动服务。
启动命令
先来看一下varlet-cli提供的偏差命令都做了些什么。//varlet-CLI/src/index。t从 导入{ Command }指挥官 const program=new Command()程序.命令( 发展与创新。)。选项( f-force ; 强制dep预优化,不管dep是否已更改 )。描述(运行恶棍开发环境)。行动(发展)可以看到这个命令是用来运行恶棍的开发环境的,还提供了一个参数,用来强制开启轻快地的依赖预构建功能,处理函数是开发人员
//varlet-CLI/src/commands/dev。t导出异步函数dev(cmd: { force?布尔}){流程。环境。node _ ENV= 发展与创新。//SRC _ DIR:varlet-ui/SRC,即组件的源码目录ensureDirSync(SRC _ DIR)等待startServer(cmd。强制)}设置了环境变量,确保组件源目录是否存在,调用了启动服务器
//varlet-CLI/src/commands/dev。tslet服务器 ViteDevServerlet观察器 FSWatcherasync函数startServer(force : boolean | undefined){//如果计算机 服务器实例已经存在了,那么代表是重启const is restart=Boolean(server)//先关闭之前已经存在的实例服务器(等待服务器。close())观察器(等待观察器。close())//构建站点入口await buildSiteEntry()}
构建站点项目
复制站点文件的操作就在buildSiteEntry 里//varlet-CLI/src/compiler/compile site entry。ts导出异步函数buildSiteEntry(){ getVarletConfig(true)await promise。所有([buildMobileSiteRoutes()、buildPcSiteRoutes()、buildSiteSource()])}主要执行了四个 ,先看getVarletConfig:
//VARLET-CLI/src/CONFIG/VARLET。配置。t导出函数getVarletConfig(emit=false): Recordstring,any { let CONFIG : any={ }//VARLET _ CONFIG:VARLET-ui/VARLET。配置。js,即varlet-ui组件库目录下的配置文件if(patheistssync(VARLET _ CONFIG)){//require 导入后会进行缓存,下次同样的导入会直接使用缓存,所以当重新启动服务时需要先删除缓存删除要求。缓存[需要。resolve(VARLET _ CONFIG)]CONFIG=require(VARLET _ CONFIG)}//默认配置,varlet-CLI/varlet。默认。配置。需要js删除。缓存[需要。解决( /./varlet。默认。配置。js )]const default config=require( ;/./varlet.default.config.js) //合并配置const mergedConfig=merge(默认配置,配置
) if (emit) { const source = ON.stringify(mergedConfig, null, 2) // SITE_CONFIGresolve(CWD, #39.varlet/site.config.json#39) // outputFileSyncOnChange 会检查内容是否有变化,没有变化不会重新写入文件 outputFileSyncOnChange(SITE_CONFIG, source) } return mergedConfig}这个 主要是合并组件库目录varlet-ui下的配置文件和默认的配置文件,然后将合并后的配置写入到站点的目标目录varlet-ui/.varlet/下。
合并完配置后执行了三个build
生成手机页面路由
1.buildMobileSiteRoutes()
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildMobileSiteRoutes() { const exles: string[] = await findExles() // 拼接路由 const routes = exles.map( (exle) =gt ` { path: #39${getExleRoutePath(exle)}#39, // @ts-ignore component: () =gt import(#39${exle}#39) }` ) const source = `export default [\ ${routes.join(#39,#39)}]` // SITE_MOBILE_ROUTESresolve(CWD, #39.varlet/mobile.routes.ts#39),站点的手机预览页面路由文件 await outputFileSyncOnChange(SITE_MOBILE_ROUTES, source)}
这个 主要是构建手机预览页面的路由文件,路由其实就是路径到组件的映射,所以先获取了路由组件列表,然后按格式拼接路由的内容,写入文件。
findExles()
// varlet-cli/src/compiler/compileSiteEntry.tsexport function findExles(): Promiseltstring[]gt { // SRC_DIRvarlet-ui/scr目录,即组件库的源码目录 // EXAMPLE_DIR_NAMEexle,即每个组件的示例目录 // DIR_INDEXindex.vue return glob(`${SRC_DIR}//${EXAMPLE_DIR_NAME}/${DIR_INDEX}`)}
从组件库源码目录里获取每个组件的示例组件,每个组件都是一个单独的目录,目录下存在一个exle示例文件目录,该目录下的index.vue即示例组件,比如按钮组件Button的目录及示例组件如下
这个 获取到的是绝对路径,并不能用作路由的path,所以需要进行一下处理
// varlet-cli/src/compiler/compileSiteEntry.tsconst EXAMPLE_COMPONENT_NAME_RE = /\/([-\w]+)\/exle\/index.vue/export function getExleRoutePath(exlePath: string): string { return #39/#39 + exlePath.match(EXAMPLE_COMPONENT_NAME_RE)?.[1]}
提取出exle前面的一段,即组件的目录名称,也就是组件的名称,生成的路由数据如下
生成pc页面路由
2.buildPcSiteRoutes()
pc页面的路由稍微会复杂一点
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildPcSiteRoutes() { const [componentDocs, rootDocs, rootLocales] = await Promise.all([ findComponentDocs(), findRootDocs(), findRootLocales(), ])}
获取了三类文件,之一种
// varlet-cli/src/compiler/compileSiteEntry.tsexport function findComponentDocs(): Promiseltstring[]gt { // SRC_DIRvarlet-ui/scr目录,即组件库的源码目录 // DOCS_DIR_NAMEdocs return glob(`${SRC_DIR}//${DOCS_DIR_NAME}/.md`)}
获取组件目录varlet-ui/src//docs/.md文件,也就是获取每个组件的文档文件,比如Button组件
文档是markdown格式编写的。
第二种
// varlet-cli/src/compiler/compileSiteEntry.tsexport function findRootDocs(): Promiseltstring[]gt { // ROOT_DOCS_DIRvarlet-ui/docs return glob(`${ROOT_DOCS_DIR}/.md`)}
获取除组件文档外的其他文档,比如基本介绍、快速开始之类的。
第三种
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function findRootLocales(): Promiseltstring[]gt { // 默认的语言 const defaultLanguage = get(getVarletConfig(), #39defaultLanguage#39) // SITEvarlet-cli/site/ // LOCALE_DIR_NAMElocale const baseLocales = await glob(`${SITE}/pc/pages//${LOCALE_DIR_NAME}/.ts`)}
获取默认的语言类型,默认是zh-CN,然后获取站点pc页面的locale文件,继续
// varlet-cli/src/compiler/compileSiteEntry.tsconst ROOT_LOCALE_RE = /\/pages\/([-\w]+)\/locale\/([-\w]+)\.ts/export async function findRootLocales(): Promiseltstring[]gt { // ... const filterMap = new Map() baseLocales.forEach((locale) =gt { // 解析出页面path及文件的语言类型 const [, routePath, language] = locale.match(ROOT_LOCALE_RE) ?? [] // SITE_PC_DIRvarlet-ui/.varlet/site/pc filterMap.set(routePath + language, slash(`${SITE_PC_DIR}/pages/${routePath}/locale/${language}.ts`)) }) return Promise.resolve(Array.from(filterMap.values()))}
返回获取到pc站点的locale文件路径,也就是这些文件
目前只有一个Index页面,也就是站点的首页
回到buildPcSiteRoutes() ,文件路径都获取完了,接下来肯定就是遍历生成路由配置了
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildPcSiteRoutes() { // ... // 生成站点页面路由 const rootPagesRoutes = rootLocales.map( (rootLocale) =gt ` { path: #39${getRootRoutePath(rootLocale)}#39, // @ts-ignore component: () =gt import(#39${getRootFilePath(rootLocale)}#39) }\` )}
有多少种翻译,同一个组件就会生成多少种路由,对于站点首页来说,目前存在en-US.ts、zh-CN两种翻译文件,那么会生成下面两个路由
继续
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildPcSiteRoutes() { // ... // 生成每个组件的文档路由 const componentDocsRoutes = componentDocs.map( (componentDoc) =gt ` { path: #39${getComponentDocRoutePath(componentDoc)}#39, // @ts-ignore component: () =gt import(#39${componentDoc}#39) }` ) // 生成其他文档路由 const rootDocsRoutes = rootDocs.map( (rootDoc) =gt ` { path: #39${getRootDocRoutePath(rootDoc)}#39, // @ts-ignore component: () =gt import(#39${rootDoc}#39) }` )}
接下来拼接了组件文档和其他文档的路由,同样也是存在几种翻译,就会生成几个路由
继续
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildPcSiteRoutes() { // ... const layoutRoutes = `{ path: #39/layout#39, // @ts-ignore component:()=gt import(#39${slash(SITE_PC_DIR)}/Layout.vue#39), children: [ ${[...componentDocsRoutes, rootDocsRoutes].join(#39,#39)}, ] }`}
这个路由是干嘛的呢,其实就是真正的文档页面了
组件文档路由和其他文档路由都是它的子路由,Layout.vue组件提供了组件详情页面的基本骨架,包括页面顶部栏、左边的菜单栏,中间部分就是子路由的出口,即具体的文档,右侧通过iframe引入了手机预览页面。
导出路由配置及写入到文件即可
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildPcSiteRoutes() { // ... const source = `export default [\ ${rootPagesRoutes.join(#39,#39)}, ${layoutRoutes}]` // SITE_PC_ROUTESvarlet-ui/.varlet/pc.routes.ts outputFileSyncOnChange(SITE_PC_ROUTES, source)}
复制站点文件
3.buildSiteSource()
// varlet-cli/src/compiler/compileSiteEntry.tsexport async function buildSiteSource() { return copy(SITE, SITE_DIR)}
这个 很简单,就是将站点的项目文件由varlet-cli/site目录复制到varlet-ui/.varlet/site目录下。
一下上述操作,就是将站点的源代码文件由cli包复制到ui包,然后动态生成站点项目的路由文件。整个站点分为两个页面pc、mobile,pc页面主要是提供文档展示及嵌入mobile页面,mobile页面用来展示各个组件的demo。
启动服务
项目准备就绪,接下来就是启动服务了,回到startServer
// varlet-ui/src/commands/dev.tsasync function startServer(force: boolean | undefined) { await buildSiteEntry() // 获取合并后的配置 const varletConfig = getVarletConfig() // 获取Vite的启动配置,部分配置来自于varletConfig const devConfig = getDevConfig(varletConfig) // 将是否强制进行依赖预构建配置合并到Vite配置 const inlineConfig = merge(devConfig, force ? { server: { force: true } } : {})}
生成Vite的启动配置,然后就可以启动服务了
// varlet-ui/src/commands/dev.tsasync function startServer(force: boolean | undefined) { // ... // 启动Vite服务 server = await createServer(inlineConfig) await server.listen() server.printUrls() // VARLET_CONFIGvarlet-ui/varlet.config.js // 监听用户配置文件,修改了就重新启动服务 if (pathExistsSync(VARLET_CONFIG)) { watcher = chokidar.watch(VARLET_CONFIG) watcher.on(#39change#39, () =gt startServer(force)) }}
使用了Vite的JavaScript API来启动服务,并且当配置文件发送变化会重启服务。
Vite配置
接下来详细看一下上一步启动服务时的Vite配置
// varlet-cli/src/config/vite.config.tsexport const VITE_RESOLVE_EXTENSIONS = [#39.vue#39, #39.tsx#39, #39.ts#39, #39.jsx#39, #39.js#39, #39.less#39, #39.css#39]export function getDevConfig(varletConfig: Recordltstring, anygt): InlineConfig { // 默认语言 const defaultLanguage = get(varletConfig, #39defaultLanguage#39) // 端口 const host = get(varletConfig, #39host#39) return { root: SITE_DIR,// 项目根目录varlet-ui/.varlet/site resolve: { extensions: VITE_RESOLVE_EXTENSIONS,// 导入时想要省略的扩展名列表 alias: {// 导入路径别名 #39@config#39: SITE_CONFIG, #39@pc-routes#39: SITE_PC_ROUTES, #39@mobile-routes#39: SITE_MOBILE_ROUTES, }, }, server: {// 设置要监听的端口号和ip地址 port: get(varletConfig, #39port#39), host: host === #39localhost#39 ? #390.0.0.0#39 : host, }, publicDir: SITE_PUBLIC_PATH,// 作为静态资源服务的文件夹varlet-ui/public // ... }}
设置了一些基本配置,你可能会有个小疑问,站点项目明明是个多页面项目,上面似乎并没有配置任何多页面相关的内容,其实在Vue Cli项目中是需要修改入口配置的,在Vite项目中不需要,这可能就是开发环境不需要打包的一个好处吧,不过虽然开发环境不需要配置,打包的时候是需要的
接下来还配置了一系列的插件
import vue from #39@vitejs/plugin-vue#39import md from #39@varlet/markdown-vite-plugin#39import jsx from #39@vitejs/plugin-vue-jsx#39import { injectHtml } from #39vite-plugin-html#39export function getDevConfig(varletConfig: Recordltstring, anygt): InlineConfig { // ... return { // ... plugins: [ // 提供 Vue 3 单文件组件支持 vue({ include: [/\.vue$/, /\.md$/], }), md({ style: get(varletConfig, #39highlight.style#39) }), // 提供 Vue 3 X 支持 jsx(), // 给html页面注入数据 injectHtml({ data: { pcTitle: get(varletConfig, `pc.title[#39${defaultLanguage}#39]`), mobileTitle: get(varletConfig, `mobile.title[#39${defaultLanguage}#39]`), logo: get(varletConfig, `logo`), baidu: get(varletConfig, ` ysis.baidu`, #39#39), }, }), ], }}
一共使用了四个插件,其中的md插件是Varlet自己编写的,顾名思义,就是用来处理md文件的,具体逻辑我们下一篇再看。
打包
就是站点项目的打包了,使用的是varlet-cli提供的build命令
// varlet-cli/src/index.tsprogram.command(#39build#39).description(#39Build varlet site for production#39).action(build)
处理函数为build
// varlet-cli/src/commands/build.tsexport async function build() { process.env.NODE_ENV = #39production#39 ensureDirSync(SRC_DIR) await buildSiteEntry() const varletConfig = getVarletConfig() // 获取Vite的打包配置 const buildConfig = getBuildConfig(varletConfig) await buildVite(buildConfig)}
逻辑很简单,先设置环境变量为生产环境,然后同样执行了buildSiteEntry ,获取Vite的打包配置进行打包即可
// varlet-cli/src/config/vite.config.tsexport function getBuildConfig(varletConfig: Recordltstring, anygt): InlineConfig { const devConfig = getDevConfig(varletConfig) return { ...devConfig, base: #39./#39,// 公共基础路径 build: { outDir: SITE_OUTPUT_PATH,// varlet-ui/site brotliSize: false,// 禁用 brotli 压缩大小报告 emptyOutDir: true,// 输出目录不在root目录下,所以需要手动开启该配置来清空输出目录 cssTarget: #39chrome61#39,// https://www.vitejs.net/config/#build-csstarget rollupOptions: { input: {// 多页面入口配置 main: resolve(SITE_DIR, #39index.html#39), mobile: resolve(SITE_DIR, #39mobile.html#39), }, }, }, }}
在启动服务的配置基础上增加了几个打包相关的配置。
到这里文档站点的初始化、启动、构建办法就介绍完了,我们下一篇再见~
element vue 国内站点 部署vue站点的教程学习