likes
comments
collection
share

antv 源码查看

作者站长头像
站长
· 阅读数 12

为什么看源码?

自搭组件库,目的是改造成我们自己的组件库。 后期大版本升级非常麻烦

文档网站怎么改?

 "predev": "npm run version & npm run collect-token-statistic & npm run token-meta && node node_modules/esbuild/install.js", // 生成版本号;
"dev": "npm run predev && npm run routes && vite serve site" // vite serve site 用来跑文档网站 而npm run routes 用来生成路由
"fast-dev": "npm run routes && vite serve site"
"routes": "node site/scripts/genrateRoutes.js",

文档网站构造

antv 源码查看

1.生成路由

npm run routes:node site/scripts/genrateRoutes.js

主要任务:会使用nodejs 捕捉 components 下面的md,然后根据路径生成路由需要的东西(字符串模版),写入到js文件里面 (详情见genrateRoutes.js文件)

然后在main.js引入routes。

2.md文件转vue组件在页面渲染

中间出现一个问题?-- md怎么被编译的,怎么就在页面正确展示了?

团队自己写了一个将md文件格式编译成vue的插件。内部很细(详见markdownToVue.js文件)

不仅仅如此,内部实现了vueToMarkdown插件(详见vueToMarkdown.js文件),作用是将vue的demo等文件可以转换成md格式,在页面渲染

怎么做到将demo文件下拼到md文件中?

antv 源码查看

3.文档一些其他组件查看

  1. Layout组件: 内置了 router-view。 将除了一些主题编辑等页面 内置在组件内部 内置左边的菜单
const useMenus = (): {
  menus: ComputedRef<any[]>;
  dataSource: ComputedRef<any[]>;
  currentMenuIndex: ComputedRef<number>;
  activeMenuItem: ComputedRef<string>;
} => {
  const route = useRoute();
  const router = useRouter();
  const routes = router.getRoutes();
  const globalConfig = inject<any>(GLOBAL_CONFIG);
  const menus = computed(() => {
    const path = route.path;
    const category = path.split('/')[1]; // 例如 http://localhost:5173/docs/vue/introduce-cn 中 'docs' 
    const pattern = /^\/iframe/;
    const isZhCN = globalConfig.isZhCN.value;
    const ms = routes
      .filter(r => {
      // 根据当前路由例如 
        const inCategory =
          r.meta &&
          r.meta.category &&
          (r.meta.category as string).toLowerCase() === category &&
          !pattern.test(r.path); 
          
        if (inCategory && category === 'docs') {
          if (isZhCN) {
            return r.path.indexOf('-cn') >= 0;
          } else {
            return r.path.indexOf('-cn') === -1;
          }
        } else {
          return inCategory;
        }
      })
      // 在这根据当前语言将routes里面中英文分开
      .map(r => ({ ...r.meta, path: r.path.split(':lang')[0].replace('-cn', '') })); 
    return ms;
  });
  const activeMenuItem = computed(() => {
    return route.path.split('-cn')[0];
  });
  const currentMenuIndex = computed(() => {
    return menus.value.findIndex(m => m.path === activeMenuItem.value);
  });
  const dataSource = computed(() => {
    // 根据type||category 进行分组 生成左边的菜单
    const group = groupBy(menus.value, (m: any) => m.type || m.category);
    const keys: string[] = Object.keys(group);
    const newMenus = keys
      .map(key => {
        return {
          title: key,
          order: typeOrder[key] && typeOrder[key].order,
          enTitle: typeOrder[key] && typeOrder[key].en,
          children: sortBy(group[key], 'title'),
        };
      })
      .sort((a, b) => a.order - b.order);
    return keys.length === 1 ? menus.value : newMenus;
  });
  return { menus, dataSource, activeMenuItem, currentMenuIndex };
}; 
  1. SearchBox
window.docsearch({
        apiKey: '92003c1d1d07beef165b08446f4224a3',
        indexName: 'antdv',
        inputSelector: '#search-box input',
        algoliaOptions: { facetFilters: [`tags:${globalConfig.isZhCN.value ? 'cn' : 'en'}`] },
        transformData(hits: any[]) {
          hits.forEach(hit => {
            hit.url = hit.url.replace('www.antdv.com', window.location.host);
            hit.url = hit.url.replace('https:', window.location.protocol);
          });
          return hits;
        },
        debug: false, // Set debug to true if you want to inspect the dropdown
      })

这段代码是使用 DocSearch 插件进行文档搜索的初始化配置代码。具体审美意义可能因人而异,但以下是这段代码的一些重要部分和功能:

  • ***: '92003c1d1d07beef165b08446f4224a3': 这是 Algolia 的搜索 API 密钥,用于连接到 Algolia 搜索服务并获取搜索结果。
  • indexName: 'antdv': 这是要搜索的索引名称,指定了要在 Algolia 搜索服务中搜索的特定索引。
  • inputSelector: '#search-box input': 这是指定搜索框元素的选择器。在这个例子中,搜索框元素是位于 idsearch-box 的元素下的 input 元素。
  • algoliaOptions: { facetFilters: [tags:${globalConfig.isZhCN.value ? 'cn' : 'en'}] }: 这是 Algolia 的选项,用于传递一些额外的搜索参数。在这个例子中,使用 facetFilters 参数根据标签(tags)过滤搜索结果,根据 globalConfig.isZhCN.value 的值选择中文或英文标签。
  • transformData(hits: any[]) { ... }: 这是一个回调函数,用于自定义搜索结果的数据转换。在这个例子中,为搜索结果中的每个条目修改了 URL,以便正确跳转到目标文档页面。
  • debug: false: 这是一个调试选项,可以将它设置为 true 来查看搜索结果的下拉菜单。

这段代码的目的是通过配置 DocSearch,使其能够连接到 Algolia 搜索服务,并在特定的搜索框中实现即时的文档搜索。通过对搜索结果的定制和其他选项的设置,可以按需扩展和调整搜索功能。

下面aidog关于DocSearch的搜索结果

DocSearch 是一个由 Algolia 提供的文档搜索解决方案,它可以帮助你搜索整个文档。

DocSearch 使用 Algolia 的搜索服务来构建和索引文档内容,并提供快速、高效的搜索功能。它提供了一个基于 JavaScript 的客户端库,通过集成 Algolia 的搜索 API,能够实时搜索并返回文档搜索结果。

具体来说,当你使用 DocSearch 时,以下是它是如何实现搜索整个文档的:

  1. 建立索引:你需要为你的文档网站创建和配置一个 Algolia 索引。这涉及到将文档内容转换为适合搜索的数据格式,并将其上传到 Algolia 的索引中。
  2. 配置 DocSearch:使用 DocSearch 提供的初始化方法来配置搜索功能。你需要提供正确的 Algolia 搜索 API 密钥、索引名称以及搜索输入框的选择器。
  3. 后台搜索:当用户在搜索输入框中输入关键字时,DocSearch 会将搜索请求发送到 Algolia 的搜索 API。Algolia 会根据预先创建的索引,筛选和匹配与关键字相关的文档内容,并将搜索结果返回给 DocSearch。
  4. 前端呈现:DocSearch 将搜索结果呈现为下拉菜单,并在用户输入关键字时实时更新。下拉菜单中的每一项表示一个匹配的搜索结果,通常包含文档标题、摘要和链接等信息。
  5. 交互操作:当用户选择某个搜索结果时,可以触发相关的操作,例如导航到文档页面或执行其他操作,这取决于你的具体实现。

总之,DocSearch 通过使用 Algolia 的搜索服务和提供的客户端库,提供了一个方便、快速的文档搜索解决方案,能够帮助你搜索整个文档,并在前端界面上显示和交互搜索结果。

组件代码怎么修改?

例如button, 使用的defineComponent api 具体业务写在setup

export default defineComponent({
  compatConfig: { MODE: 3 },
  name: 'AButton',
  inheritAttrs: false,
  __ANT_BUTTON: true,
  props: initDefaultProps(buttonProps(), { type: 'default' }),
  slots: Object as CustomSlotsType<{
    icon: any;
    default: any;
  }>,
  // emits: ['click', 'mousedown'],
  setup(props, { slots, attrs, emit, expose }) { // 业务代码
  }

样式怎么处理的?

 const buttonProps = {
        ...attrs,
        title,
        disabled: mergedDisabled.value,
        class: [
          classes.value,
          attrs.class,
          { [`${prefixCls.value}-icon-only`]: children.length === 0 && !!iconType },
        ],
        onClick: handleClick,
        onMousedown: handleMousedown,
      };

通过拼接 attrs 组成新的props 放到 button 上

样式主题怎么修改?token 是怎么处理的?

/docs/vue/customize-theme-cn(这个路由是描述自定义主题的路由)

内部使用了vue3 提供的privodeinject,只需要在最外面的app进行包裹,设置的值,会在底层的组件被截取到, 截取到之后和defaultToken进行解构拼接

<a-config-provider 
  :theme="{ token: { colorPrimary: '#00b96b', }, }" >
    <a-button /> 
</a-config-provider>

可以在 theme-editor-cn 生成一套自定义主题 用于开发

框架怎么转换md渲染成html?

团队自己写了一个将md文件格式编译成vue的插件。内部很细(详见markdownToVue.js文件)

不仅仅如此,内部实现了vueToMarkdown插件(详见vueToMarkdown.js文件),作用是将vue的demo等文件可以转换成md格式,在页面渲染

单元测试

待办

怎么部署到私服

  1. 根据讯飞的方法生成权限码 antv 源码查看
  2. 原本antv自带了pub脚本 直接发到github公网上,现在改造了下 使用pub脚本
"pub-abandon": "npm run version & npm run collect-token-statistic & npm run token-meta && node --max_old_space_size=8192 antd-tools/cli/run.js pub",
"pub": "npm run version & npm run collect-token-statistic & npm run token-meta && npm publish --registry https://depend.iflytek.com/artifactory/api/npm/npm-private --with-antd-tools",

npm run collect-token-statistic :收集token的静态变量 生成token.json --具体组件用到的颜色,例如 Layout 用到 colorBgLayout

npm run token-meta:生成主题编辑页面的json文件

  1. 文档网站怎么部署 -npm run pub:site 详情见质效平台