123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- import "dotenv/config";
- import { fileURLToPath, URL } from "node:url";
- import { defineConfig } from "vitepress";
- import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
- import Icons from "unplugin-icons/vite";
- import { FileSystemIconLoader } from "unplugin-icons/loaders";
- import { SVG, cleanupSVG, parseColors, runSVGO } from "@iconify/tools";
- import ImageFiguresPlugin from "markdown-it-image-figures";
- import {
- S3Client,
- ListObjectsCommand,
- GetObjectCommand,
- } from "@aws-sdk/client-s3";
- import fs from "node:fs";
- import path from "node:path";
- import { exec } from "child_process";
- import { buildSideBar } from "../utils/sideBar";
- const DOC_BASE_PATH = "pages";
- if (process.env.NODE_ENV === "production") {
- // 执行清理pages文件夹命令
- await new Promise((resolve, reject) =>
- exec(
- `git checkout -- ${DOC_BASE_PATH} & git clean -df ${DOC_BASE_PATH}`,
- (error, stdout, stderr) => {
- if (error) {
- console.error(`清理pages时出错: ${error.message}`);
- reject(stderr);
- }
- console.log(`清理pages结果: ${stdout}`);
- resolve(stdout);
- }
- )
- );
- }
- // 从S3构建pages里面的markdown文件
- const s3 = new S3Client({
- credentials: {
- accessKeyId: process.env.VITE_AWS_S3_ACCESS_KEY_ID!,
- secretAccessKey: process.env.VITE_AWS_S3_SECRET_ACCESS_KEY!,
- },
- region: process.env.VITE_AWS_S3_REGION!,
- });
- const command = new ListObjectsCommand({
- Bucket: process.env.VITE_DOCS_LIST_BUCKET,
- });
- const { Contents: contents } = await s3.send(command);
- await Promise.all(
- contents!.map((content) => {
- return new Promise(async (resolve, reject) => {
- try {
- const command = new GetObjectCommand({
- Bucket: process.env.VITE_DOCS_LIST_BUCKET,
- Key: content.Key,
- ResponseCacheControl: "no-cache",
- });
- const file = await s3.send(command);
- const writePath = path.join(DOC_BASE_PATH, content.Key!);
- const directory = path.dirname(writePath);
- fs.mkdirSync(directory, { recursive: true });
- fs.writeFileSync(writePath, await file.Body!.transformToString());
- resolve(content.Key);
- } catch (e) {
- reject(e);
- }
- fs.writeFile;
- });
- })
- );
- // 构建sideBar数据
- function readJsonFile(filePath) {
- try {
- // 同步读取文件内容,如果文件不存在会抛出异常
- const data = fs.readFileSync(filePath, "utf8");
- return JSON.parse(data); // 解析 JSON 数据
- } catch (err) {
- if (err.code === "ENOENT") {
- console.error("File not found:", filePath);
- // 可以返回默认值或者进行其他处理
- return {}; // 返回 null 或者其他默认值
- } else {
- throw err; // 抛出其他异常
- }
- }
- }
- const sideBarSortMap = {
- "zh-CN": readJsonFile("pages/zh-CN::SIDEBAR_SORTED_MAP.json"),
- "zh-HK": readJsonFile("pages/zh-HK::SIDEBAR_SORTED_MAP.json"),
- "en-US": readJsonFile("pages/en-US::SIDEBAR_SORTED_MAP.json"),
- };
- let { rootSideBar, zhHKSideBar, enUSSideBar } = buildSideBar(
- contents,
- sideBarSortMap
- );
- // import util from "util";
- // console.log(
- // util.inspect(sideBarSortMap, {
- // showHidden: false,
- // depth: null,
- // colors: true,
- // }),
- // util.inspect(rootSideBar, { showHidden: false, depth: null, colors: true })
- // );
- // https://vitepress.dev/reference/site-config
- export default defineConfig({
- title: "可可智慧教育平台",
- description: "可可智慧教育平台",
- base: "/help/",
- srcDir: DOC_BASE_PATH,
- ignoreDeadLinks: true,
- lastUpdated: true,
- themeConfig: {
- i18nRouting: false,
- search: {
- provider: "local",
- options: {
- locales: {
- root: {
- translations: {
- button: {
- buttonText: "搜索文档",
- buttonAriaLabel: "搜索文档",
- },
- modal: {
- noResultsText: "无法找到相关结果",
- resetButtonTitle: "清除查询条件",
- footer: {
- selectText: "选择",
- navigateText: "切换",
- closeText: "关闭",
- },
- },
- },
- },
- "zh-HK": {
- translations: {
- button: {
- buttonText: "搜索文档hk",
- buttonAriaLabel: "搜索文档hk",
- },
- modal: {
- noResultsText: "无法找到相关结果",
- resetButtonTitle: "清除查询条件",
- footer: {
- selectText: "选择",
- navigateText: "切换",
- closeText: "关闭",
- },
- },
- },
- },
- },
- },
- },
- },
- appearance: false,
- markdown: {
- breaks: true,
- config: (md) => {
- md.use(ImageFiguresPlugin, { figcaption: true });
- },
- },
- vite: {
- publicDir: "../public",
- envDir: "../",
- ssr: {
- // SSG Vue-i18n workaround
- noExternal: ["vue-i18n", "mark.js"],
- },
- plugins: [
- VueI18nPlugin({}),
- Icons({
- compiler: "vue3",
- customCollections: {
- "ccrbi-plain": FileSystemIconLoader(
- "assets/icons/plain",
- async (svgStr) => {
- const svg = new SVG(svgStr);
- cleanupSVG(svg);
- parseColors(svg, {
- defaultColor: "currentColor",
- callback: (attr, colorStr, color) => {
- // console.log('Color:', colorStr, color);
- // 普通图标
- return "currentColor";
- // Change black to 'currentColor'
- // const blackColor = stringToColor("black");
- // if (color && compareColors(color, blackColor!)) {
- // return "currentColor";
- // }
- // switch (color?.type) {
- // case "none":
- // case "current":
- // return color;
- // }
- // throw new Error(
- // `Unexpected color "${colorStr}" in attribute ${attr}`
- // );
- },
- });
- // Optimise, but do not change shapes because they are animated
- runSVGO(svg, {
- keepShapes: true,
- });
- return svg.toMinifiedString({});
- }
- ),
- "ccrbi-colored": FileSystemIconLoader(
- "assets/icons/colored",
- async (svgStr) => {
- const svg = new SVG(svgStr);
- cleanupSVG(svg);
- // Optimise, but do not change shapes because they are animated
- runSVGO(svg, {
- keepShapes: true,
- });
- return svg.toMinifiedString({});
- }
- ),
- },
- }),
- ],
- resolve: {
- alias: [
- {
- find: /^.*\/VPNavBar\.vue$/,
- replacement: fileURLToPath(
- new URL("../components/CustomNavBar.vue", import.meta.url)
- ),
- },
- {
- find: /^.*\/VPHome\.vue$/,
- replacement: fileURLToPath(
- new URL("../components/CustomVPHome.vue", import.meta.url)
- ),
- },
- {
- find: "@/",
- replacement: fileURLToPath(new URL("../", import.meta.url)),
- },
- ],
- },
- },
- locales: {
- root: {
- label: "简体中文",
- lang: "zh-CN",
- themeConfig: {
- i18nRouting: false,
- outline: { label: "本页目录", level: "deep" },
- logo: "/logo.png",
- siteTitle: false,
- sidebar: rootSideBar,
- },
- },
- "zh-HK": {
- label: "繁体中文",
- lang: "zh-HK",
- themeConfig: {
- i18nRouting: false,
- outline: { label: "本頁目錄", level: "deep" },
- logo: "/logo.png",
- siteTitle: false,
- sidebar: zhHKSideBar,
- },
- },
- "en-US": {
- label: "English",
- lang: "en-US",
- themeConfig: {
- i18nRouting: false,
- outline: { label: "On this page", level: "deep" },
- logo: "/logo.png",
- siteTitle: false,
- sidebar: enUSSideBar,
- },
- },
- },
- });
|