跳至主要內容

问题列表

大约 21 分钟博客教程经历

问题列表

提示

  • 以下问题可能不具有时效性与主题泛用性,请自行判断。
  • 按时间升序。

字体颜色问题

网上教程为使用 <font color="red"> 标签,但此标签不受 html5 支持(并导致了下述 Rendering pages failed 问题)。我还尝试了 <p> 标签(但会自动换行)与 <a> 标签(但有下划线和点击效果)。最终选用 <text style="color:red;"> 标签,写起来最为简洁,无需添加额外属性。

Rendering pages failed 问题

显示的错误信息是 Vuepress 的底层问题,无法直接看出问题所在。且 docs:dev 本地预览完全不受影响。之后不断比对各处编译,发现是引入未知 html 标签导致的。(初次为 <font> 标签,之后还有:自定义组件的标签,被识别成组件的语法)(感谢dream 同学open in new window重蹈覆辙,提供完全一致的错误信息,如下所示。) 原本因为时隔太久且当时没有博客心得,因此没有记录,没想到有笨比(

TypeError: Invalid value used as weak map key
at WeakMap.set (<anonymous>)
at normalizePropsOptions (C:\Users\oyh\vuepress-starter\node_modules@vue\runtime-core\dist\runtime-core.cjs.prod.js:3179:15)
at createComponentInstance (C:\Users\oyh\vuepress-starter\node_modules@vue\runtime-core\dist\runtime-core.cjs.prod.js:5695:23)
at renderComponentVNode (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:168:22)
at Object.ssrRenderComponent (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:605:12)
at _sfc_ssrRender$b (C:\Users\oyh\vuepress-starter\docs.vuepress.temp.server\app.js:1362:24)
at renderComponentSubTree (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:250:13)
at renderComponentVNode (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:185:16)
at renderVNode (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:292:22)
at renderComponentSubTree (C:\Users\oyh\vuepress-starter\node_modules@vue\server-renderer\dist\server-renderer.cjs.prod.js:256:13)

Vue 组件注册失败的问题

前期开发过程中遇到的最大的问题。详情懒得再写一遍了,请直接跳转 stackoverflow 查看open in new window。我还剩一种方法(在 client.ts 中手动注册组件)没试,不过既然已经曲线救国成功(使用 iframe 引入带组件的 html),就暂时不尝试了。(20220720 速报:问题已解决,解决方法:重新下载 vuepress2 包。猜测是旧 vuepress2 的依赖包出了问题。)

评论插件配置失败问题

我使用的评论插件是vuepress-plugin-comment2open in new window。该插件的文档写的甚至比 vuepress2 文档还含糊不清,关键部分更是一句没提。配置成功后评论插件一开始并没有载入成功(而且抓瞎不知道什么原因),我非常疑惑,花了好多时间仔细检查好多遍,都不能理解为什么。后来对照官方的例子(还好有给出演示open in new window)才发现原来还需要自己写一个 theme 出来...我哪有那个能耐啊,直接 Ctrl+CV 了。不过这种东西本应在文档里指明的。

后来发现。。事实上这个插件是 VuePress Theme Hope 主题的专用组件,因此未说明默认主题下的使用方法。

添加黑幕

其实就是添加全局 css。

.vuepress/public下任意位置新建head.css(名字不重要),输入:

.heimu,
.heimu a,
a .heimu,
.heimu a.new {
  background-color: #404040;
  color: #404040;
  text-shadow: none;
}
.heimu:hover,
.heimu:active,
.heimu:hover .heimu,
.heimu:active .heimu {
  color: white !important;
}
.heimu:hover a,
a:hover .heimu,
.heimu:active a,
a:active .heimu {
  color: lightblue !important;
}
.heimu:hover .new,
.heimu .new:hover,
.new:hover .heimu,
.heimu:active .new,
.heimu .new:active,
.new:active .heimu {
  color: #ba0000 !important;
}

config.ts内添加全局 css:

export default defineUserConfig({
  head: [
    ["link", { rel: "stylesheet", href: "/styles/head.css" }], // 填写对 public 的 css 相对路径
  ],
});

然后就可以在 .md 文件中使用黑幕了:<span class="heimu" title="你知道的太多了">你想说的话</span> 效果:比如这样

另一个方法

创建 .vuepress/styles/index.scss 并写入 css。vuepress 会自动引入,无需写入配置。是通用解法,与主题无关。

图床衍生问题

由于图片越来越多,博客更新频繁,这样占云端空间大,上传也慢。于是就直接就地开了个 images 分支当作图床。我一开始直接在 .vuepress/public/images 文件夹里创建仓库上传的,然后也能正常使用,到了发布博客的时候,编译也过了,上传也成功了,结果 Github 告诉我因为一个奇妙的问题构建不成功......此处放出错误信息:

Fetching submodules
/usr/bin/git submodule sync --recursive
/usr/bin/git -c protocol.version=2 submodule update --init --force --depth=1 --recursive
Error:fatal:No url found for submodule path 'images' in .gitmodules
Error:The process '/usr/bin/git' failed with exit code 128

后来经过不断摸索发现大概是 git 内包含了一个 git 的原因。把 images 文件夹整个移出去以后就好了。

EPERM 编译失败问题

运行 npm run docs:build 时报错。显示:

Error: EPERM: operation not permitted, lstat 'F:\program\myweb\docs.vuepress\dist.git\logs\refs\heads\main'

本地预览 npm run docs:dev 不受影响。

上网搜索,尝试管理员权限,清除缓存,更新 npm 手段,皆无效。看到有人说是 xftp 造成的 dist 文件夹占用问题,不了解。但是既然说是占用,那我就重启试试。于是问题解决。看来这是 99%的问题其中之一呢

图床国内无法解析问题

我原本博客托管在 github.io,图片加载链接为https://raw.githubusercontent.com/lxl66566/lxl66566.github.io/images/logo.jpg,由于我 clash 双端全天候开启,我根本没发现图片无法加载的这个问题,直到 20220803 我关了梯才发现,原来国内无法正常加载图片,报错:

Failed to load resource: net::ERR_NAME_NOT_RESOLVED

原因是 raw.githubusercontent.com 域名在墙内受到污染。

然后我尝试了使用其他图床托管图片:SM.MSopen in new window,但是:

  1. 这个图床有 容量上限:5GB单张图片上限:5MB
  2. 原有的每张图都需要手动替换,因为 src 是随机生成的
  3. 会出现一些玄学问题,例如:使用<img src="https://s2.loli.net/2022/08/03/DCPGWEa6dyoLK1t.jpg" width="100%" height="100%">进行图片缩放时将不显示图片,即无法获取图片原始大小,需要使用绝对大小缩放(下文有解释,这并不是图床的问题)
  4. 关于 SM.MSopen in new window界面你将能看到:fucksmms 这样的图床还是早点死吧!

因此寻找其他解决方案。开始采用 CDN 加速 Github 图床的方案。cdn 的好处:

  • 不改变图片目录结构
  • 替换方便。仅需全局查找替换,点一下鼠标即可。(但是对我来说需要把 SM.MS 图床的链接再换回原链接…)

后来尝试了以下 cdn:

  • jsdelivropen in new window,然而国内无法使用。网上搜,大家也都说寄了。
  • staticallyopen in new window,成功。于是就决定用它了。
    • 后来 cdn.staticaly.com has expired.,然而我并没有发现是代理域名的问题(statically.io 可以正常使用),于是把图片直接放到静态站点里了。由于博客主要托管不再是 github.io 而是 cloudflare,因此回归本源也不错,不会再出现此问题。

关于数学插件

为 markdown-it 渲染器安装LaTeX\displaystyle \LaTeX插件。参考来源open in new window,亲测有效。

由于$...$会被 vuepress 识别为未知标签,因此在需要使用公式时需包裹<span v-pre></span>标签。否则将触发weak map key bug。

图片无法比例缩放问题

实际上,在之前已经出现过此问题,当时只会使用绝对大小解决。而这次,当我向图床中添加第一张手机照片时,玄学问题出现了。

我之前一直使用 <img src="..." width="100%" height="100%"> 进行图片缩放。当我使用此方法对此图片进行缩放时,图片将不显示,调试显示此图片标签属性为 width="0" height="0"。只有当 widthheight 都不含 % 时,图片才能显示。

解决方法:

  • 在全局 css 中新增类选择器.ClassName img{width: 60% !important; height:auto !important;}.ClassName img{max-width: 60%;},并在 md 中以<div class="ClassName"><img src="..."/></div>使用。

为单一页面添加 css

未解决!

起因:不想全局添加 css。官方说明open in new window已尝试,无效。(该文档为 v1 文档,不适用于 v2)

最新发现:官方在此处的声明open in new window中,style 文件类型从 .styl 改为 .scss。有机会的话可以尝试。扩展名与文件无关!

其实加的 css 也就这么几行,全局不全局的无所谓了

html 转 vue 组件失败问题

未解决!

用 html, js, css 三件套写了一个简陋的背词器出来,但是受制于 iframe 的固定大小,很容易出现超出边框的情况。(曲线救国:预留大量位置) 于是想到了 vue 组件引入的方法。但是,遇到了前所未有的麻烦。vue 组件单文件(SFC)仅允许一个 <script> 标签的存在。而我的背词器中使用了两个 script:jquery 库与我自己写的 js。现在无法正常执行 js 脚本。

学长提示:可使用另一种曲线解法:you might not need jqueryopen in new window(XD

后来发现需要学习 Vue 而不是普通地套 html。。在学了在学了

配置 sidebar 问题

由于我一开始对 sidebar 的机制并不清楚,官方文档的教程也无法满足我的需求,于是就自己慢慢摸了几个小时…此处只讲述如何 在不同子路径中使用不同的侧边栏 这一泛用性广但示例少的解决方案。

首先,sidebar 配置结构为 绝对路径:sidebar对象 这样的键值对。一个 sidebar 对象有:

  • text,表示该栏显示的文字
  • link,表示点击该栏后跳转的位置
  • children,表示该栏下的 sidebar 对象

当然它也可以是一个路径字符串,其他功能由 vuepress2 帮你自动生成。

另外,若需要为文件夹做一个向导,应在文件夹内部添加 README.md 主页。指向该主页的路径为文件夹名称。使指定页面覆盖配置,自动生成 sidebar 需要在该页面顶部添加sidebar frontmatteropen in new window

下面是我的 sidebar 配置参考。

sidebar:{
    '/gossip/': [
    {
        text : '闲聊',
        link : '/gossip/',
        children: ['author.md',...],
    },
    ],
    '/articles/': [
    {
        text : '我的文章',
        link : '/articles/',
        children: ['windows_setting.md',...],
    },
    ],
    '/': [
    '../index.md',
    {
        text : '闲聊',
        link : '/gossip/',
        children: ['/gossip/author.md',...],
    },
    {
        text : '我的文章',
        link : '/articles/',
        children: ['/articles/windows_setting.md',...],
    },
    {
        text : '编程',
        children: ['/coding/Rust.md',...],
    },
    {
        text : '爱好',
        children: ['/hobbies/rhythm_games.md',...],
    },
    {
        text : '杂项',
        children: ['/farraginous/recommend_packages.md',...],
    },
    ],
},

17 行写的是'../index.md'而不是'/index.md',是因为我需要让某些二级页面也能显示主页的侧边栏,为此提供索引。主页已经在顶层目录下,无法向前回退。

vuepress v1.x 的要求

vuepress1 的配置有一点不一样。

v1.x sidebar 工作机制为:从上到下寻找该页面匹配的绝对路径前缀,若匹配则使用该 sidebar 对象。这使我需要把多级 sidebar 放在前而根目录放在最后。还好v1.x 文档对此有警告open in new window

团队使用的vuepress-theme-hopeopen in new window主题中,sidebar 对象有以下字段:

  • title:规定显示的文字
  • link:表示点击该栏后跳转的位置
  • prefix:路径前缀
  • children:子对象

一个配置示例为:

sidebar: {
    "/": [
        "/",
        {
            title: "教程系列",
            link: "/Learning-list/",
            prefix: "/Learning-list/",
            collapsable: false,
            children: ["git/", "OpenGL/", "Linux/", "如何浅层地使用pgp加密.md", ],
        },
    ],
},

上传问题

git push 时出现问题:ssh: connect to host github.com port 22: Connection timed out。代理无问题,可上 Github。

解决方法(二选一):

  1. 参考Github 官方解释open in new window,使用 443 端口
  2. 配置 git 全局代理

html 传参引入指定 js

目的:复用画图表的 html 文件。尝试:

  1. 给页面中的 iframe html 传参:
    <iframe src="/charts/animation.html?src=GBperprice"></iframe>
    
  2. 然后在 html script 中处理参数:
    function getParams(key) {
      var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
      var r = window.location.search.substr(1).match(reg);
      if (r != null) {
        return unescape(r[2]);
      }
      return null;
    }
    const addr = "/charts/" + getParams("src") + ".js";
    
  3. 并引入addr参数位置的 .js 文件。未解决!
    HTML
    ...
    <!-- <script type="text/javascript" src=addr></script> 
        无效。script 无法使用 JavaScript 变量。 -->
    <script type="module">
      // import {data} from addr; 报错,其将 addr 识别为 "addr" 而非 String 变量
      import(addr); // 无效
    </script>
    ...
    

pangu 插件安装失败

试图安装 vuepress-plugin-panguopen in new window 失败。官方文档稀烂,缺乏维护,只有 vuepress1.x 的 js 配置,而我使用 ts ;由于并未学习,面对各种报错显得很无力。(有生之年必学)

解决方法: 突然想到了我加黑幕的方法,直接将 js 引入每个页面的 head。 config.ts:

head: [
  ["link", { rel: "stylesheet", href: "/styles/head.css" }],
  ["script", { src: "/styles/pangu.min.js" } ],
],

其中/styles/pangu.min.js内是https://cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.jsopen in new window的内容。但是这样一来便引入了以下问题:

无法加载 pangu 问题

未解决!

使用此方法添加的 pangu.min.js 在 head 中被注入,存在加载次序问题,在浏览器上无法正常运行。我尝试使用 enhanceApp.jsopen in new window 将其添加到文档末尾解决这个问题:

.vuepress/enhanceApp.js:

export default ({
  Vue, // VuePress 正在使用的 Vue 构造函数
  router, // 当前应用的路由实例
}) => {
  const pangujs = document.createElement("script");
  pangujs.src = "./styles/pangu.min.js";
  pangujs.async = true;
  pangujs.defer = true;
  document.body.appendChild(pangujs);
  console.log("pangu installed"); // test
};

但是失败了,console.log 并未执行,说明 .vuepress/enhanceApp.js 未被自动加载。我也尝试了在 config.ts 中加入 enhanceAppFiles: resolve(__dirname, 'enhanceApp.js')[1],无效。

ps. 现在已使用 Prettier 格式化代码,其会自动添加空格,曲线救国。

端口拒绝访问

listen EACCES: permission denied 0.0.0.0:8080

解法:解决 windows(hyper-v) 端口随机占用

试图迁移至 vitepress

vitepress 其实是 VuePress 的一个分支,其具有更快的渲染速度与更高的自由度(?),因此我尝试将此 blog 迁移至 vitepress。结果——如你所见,失败了。但是,此配置过程中也学到了一些东西。

  1. 安装好 vitepress 并配置。其配置有些许不同:

    • navbar 改为 nav,并且其与 sidebar 接受参数的语法不同。
    • vitepress 以 index.md 作为默认页面,而非 readme.md.
    • 考虑抄抄官方open in new window,有一些好的理念。
  2. 安装插件。

    1. 搜索插件:vitepress 内置open in new window,并且其功能爆杀 VuePress。
    2. 数学公式插件,npm install markdown-it markdown-it-mathjax3。详细配置可以抄这里open in new window,完美解决遇到的问题。
    3. 评论插件:vitepress-plugin-comment-with-giscusopen in new window,非常简单,但是首页无法显示评论,搞了好久没法解决。
  3. 全局 css:在 .vitepress/theme/styles/ 中放入任何想要的 css 文件,然后在 theme/index.ts 下 import 就行了。可惜没法这样引入 js,pangu.js 还是无法使用。

  4. 无法加载 public 中的资源。无论 img 还是 html 用 iframe 引入都不行。

    • iframe 404,用法 <iframe frameborder="no" src="/charts/sports_distance.html" width="100%" height="304"></iframe>,报错 GET http://localhost:5173/charts/sports_distance.md?import&t=1689086185464 net::ERR_ABORTED 404 (Not Found),看起来是把后缀强制上了 .md。。我在官方文档看到了关于 pathname:// 的解释open in new window,但是并没有什么卵用。
  5. 无法 build,preview。我是真的很不理解。

    1. npm run docs:build 报错

      ✓ building client + server bundles...
      build error:
      ReferenceError: window is not defined
      at file:///D:/program/vitepress/docs/.vitepress/.temp/app.js:4675:3
      ...

    但是我也没用什么组件,找不到解法。 2. npm run docs:preview 报错

    failed to start server. error:
    Error: ENOENT: no such file or directory, open 'D:\program\vitepress\docs.vitepress\dist\404.html'

    这就很好理解了,毕竟 dist 还是残缺的。不过至少有个理论能用的 preview 已经很不错了,都可以杀 VuePress(

最后附上我尝试的 config.ts 代码留念 x
import { defineConfig } from "vitepress";
import mathjax3 from "markdown-it-mathjax3";
const customElements = ["mjx-container"];
export default defineConfig({
  lang: "zh-CN",
  title: "绝对值_x的博客",
  description: "没什么有价值的内容的,真的!",
  lastUpdated: true,
  ignoreDeadLinks: true,
  themeConfig: {
    logo: "https://cdn.staticaly.com/gh/lxl66566/lxl66566.github.io/images/logo.jpg",
    nav: nav(),
    sidebar: sidebar(),
    socialLinks: [
      {
        icon: "github",
        link: "https://github.com/lxl66566/lxl66566.github.io",
      },
    ],
    search: {
      provider: "local",
    },
    externalLinkIcon: true,
  },
  markdown: {
    config: (md) => {
      md.use(mathjax3);
    },
  },
  vue: {
    template: {
      compilerOptions: {
        isCustomElement: (tag) => customElements.includes(tag),
      },
    },
  },
});
function nav() {
  return [
    {
      text: "编程",
      link: "/coding/",
    },
    {
      text: "文章",
      link: "/articles/",
    },
    {
      text: "闲聊",
      link: "/gossip/",
    },
    {
      text: "随笔",
      link: "/essay.md",
    },
  ];
}
function sidebar() {
  return {
    "/gossip/": [
      {
        text: "闲聊",
        link: "/gossip/",
        items: [{ text: "author", link: "/gossip/author" }],
      },
    ],
  };
}

尝试更好的搜索

如上所述,VuePress 拥有极为垃圾的默认搜索机制,而官方推荐的第三方服务(algolia)需要经过严格审查。因此我看到了能够本地索引的flexsearchopen in new window,继续找到了:

参考:liuli-moe/to-the-starsopen in new window

更换主题

20230712 由于开头所述原因,更换了 VuePress Theme Hopeopen in new window 主题。迁移过程比我想象的时间要少。该主题有如下优势:

  • 自动检测 Broken links
  • Markdown 增强:
    • 自带 TEXTEX 支持
    • 任务列表
    • 脚注支持
    • 容器扩展
    • 图片扩展
  • 更适用于博客的首页
  • 无障碍图标
  • 自动明暗主题
  • 内容加密

反正就是非常牛逼。

不过还有一些问题(功能改进)没有解决:

  • 比如我想在 navbar 上加一个 telegram 的跳转链接。已解决
  • 主页评论区寄了。明明都是 gisgus 的服务,配置一模一样,也是按照 pathname 查找,但是原先的评论就是找不回来。

起因:想给导航栏添加一个 Telegram 的链接。由于 VuePress Theme Hope 就有,可以直接抄。

  1. 写(抄)一个组件open in new window,替换链接。
  2. client.ts手动注册open in new window
  3. theme.ts引入open in new window

添加 rss 订阅

官方说open in new window是说支持,还内置,但是并不能用...首先 VuePress Theme Hope 文档的描述就比插件文档描述少了东西,比如 hostname。其次我配置好以后并不知晓如何获取 rss.xml,官方示例使用默认主题配置,使用外部导入的插件,没有参考意义。

后来发现 dev 没法使用,但是 build 后在 dist 内会生成 rss.xml,就可以订阅了。

添加订阅图标

模仿 telegram 图标 添加。首先替换链接,再去找个 rss 的 svg,替换 <path d=...> 内容;替换 viewBox 内容(没错,我踩坑了)即可。不熟悉 svg 是这样的

自动部署

使用 pnpm 指令 pnpm create vuepress-theme-hope my-docs 创建模版项目后,自动生成的 .github/workflows/deploy-docs.yml 并不能在 Github actions 中成功构建,报错:

Error: Error: No pnpm version is specified.
Please specify it by one of the following ways:
- in the GitHub Action config with the key "version"

解法可以参考 pnpm 文档open in new window,加一条 version: 8 即可。

hope theme template build error

20230807,使用 pnpm 指令 pnpm create vuepress-theme-hope my-docs 创建模版项目后,执行 pnpm docs:build 会报错。原因是依赖未更新,Github 上的依赖更新未同步至 npmjs create-vuepress-theme-hopeopen in new window

解法:在 package.json 中将 vue 版本改为 ^3.3.4 并执行 pnpm i 更新依赖。

妈的,这些 bugs Github 都修了,npmjs 一直不更新是几个意思呢?

图片防爆

  • 已撤销

此博客使用 CDN 引入图片。然而即使是老牌 CDN 也可能会有不稳定的时候,想着加个防爆链接,当 CDN 爆了以后 img 从另一个链接加载。(refopen in new window)

<img src="image.jpg" onerror="this.src='other link'" />

而 markdown 内的图片格式可以用markdown enhancement: attropen in new window添加 attr。然后踩了坑:

  1. 首先大括号 {} 需要紧跟在图片的 ) 后,不能有空格。。(然而官网示例是给的空格)
  2. 其次,添加的 attr 不允许出现大写字母。。。(这确实是标准,但是一般浏览器遇到大写会自动纠正 (refopen in new window))

最后还是决定不加了,毕竟防爆用的原始链接是 raw.githubusercontent.com 下的,本身就被墙了;而且还没有考虑可能出现的的死循环问题。

Google Analystics

ps. 当天发现 cloudflare pages 自带 Web Analytics,白干。

想看看我的博客的访问数据,但是不能直接用一个简单计数器,否则我自己对我的博客访问最多,会污染数据。于是使用 Google 家的免费服务。

跟随官网操作open in new window,账号和媒体资源名称随便填。输入博客网址,然后会给你一段 html 代码让你写进网页。

很容易想到在 config.ts 中写 head 项,把 script 载入每个博客页面。这里是官网的说明open in new window

写的时候犹豫了一下 async 要怎么写,稍作尝试就写出来了。示例:

...
head: [
  [
    "script",
    {
      async: true,
      src: "https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxx",
    },
  ],
  [
    "script",
    {},
    `<!-- Google tag (gtag.js) -->
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-xxxxxxxx');`,
  ],
],
...

其实 cloudflare 是有自己的 Web Analytics 的,但是我对比了一下,感觉还是 Google 的更先进点。

静态资源引用错误

build 报错

✖ Compiling with vite - failed in 1.80s
Error: [vite]: Rollup failed to resolve import "/images/essay/20220619.png" from "D:/program/lxlsblog/src/.vuepress/.temp/pages/essay/2022.html.vue". This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to build.rollupOptions.external

第二句提示报错,发现是 public 资源改位置了而文章里没改,没引用到。

局部注册组件

主题文档open in new window是有描述如何局部注册组件的,但是我之前尝试了几次都失败了。

第一个报错发生在 import { getDirname, path } from "@vuepress/utils"; 时,系统提示找不到 @vuepress/utils。由于主题默认采用 pnpmnode_modules 的布局与传统的不同,因此确实无法找到 @vuepress/utils。后来自己手动装了才能用(pnpm install)。

第二个问题是我的 export default 后面跟的是一个 defineUserConfig({...}),返回一个 UserConfig 对象。我尝试直接 defineUserConfig({alias:{...},...}) 会报类型错误,毕竟是 ts,这个函数本来就不能接受未知参数。后来学了点 ts/js,发现只需要借助中间变量即可。

const temp = defineUserConfig({...});
temp.alias = {...};
export default temp;

尝试将 plot 放入 vue 组件

这是一次失败的尝试,我将改动放在了 vueplotfailed1 分支open in new window内。我本以为写了一些组件的我能够胜任这项任务,事实证明我还是太天真了。

在经历了各种调试以后,我发现 @antv/g2plot 的官方调用方式是:

const bar = new Bar("container", {
  data,
  xField: "sales",
  yField: "year",
  ...
});

其中第二个参数(option) 是一个自定义的类型,而不是一个 Object;它的第一个参数是一个 Array,而后面却是一堆键值对。这就导致了我没法向第一个 data 传参:如果我用 this.data,则会被报错 expected ':';如果我 const temp = this.data;{data,...}temp 又不能跟随 this.data 的变化。

处理 darkmode

起因是我在博客中放了一张黑色文字 svg,但是图片默认不反色,因此黑暗主题下完全看不到。因此我想写一点 css 使其在黑暗模式下自动反色。

翻了点文档发现了个 scss exampleopen in new window,对着其和 GPT 抄了以后发现无论如何都无法反色。(尝试了一堆邪道,@if 啊,$isDarkmode 啊,#{hope-config.$dark-selector} 啊)

img[type="image/svg+xml"] {
  html[data-theme="dark"] {
    filter: invert(1);
  }
}

后来进群问(没错,theme-hope 有群了),说 html 选择器要放外面。于是发现我抄漏了一个 &,这个符号就是指定父元素用的。

然后加了 & 还是没用,我又尝试了一下其他 scss 官方示例,但是都是可以正常工作的。所以这一定是我的问题。

然后发现这个 type 并不是 img 自带的属性。。我一直以为这选择器能自动判断 type 来着。后来就可以了。下面是最终的 scss:

img[src$=".svg"] {
  html[data-theme="dark"] & {
    filter: invert(1);
  }
}

带给我一个教训:折腾之前先系统学习(scss 语法)。


  1. refopen in new window ↩︎

上次编辑于: