解决 Eslint 和 Prettier 的冲突

当项目同时使用 Eslint 和 Prettier 时,往往格式化时会有冲突,导致最终格式化效果不对。发现问这个问题的人还不少,所以这里记录一下解决办法,需要的时候发给人看。 其实解决方案很成熟,就是用到两个插件,eslint-config-prettier 和 eslint-plugin-prettier。 当你的项目已经安装了 eslint 和 prettier 后,也有了各自的配置文件后,安装以上两个插件: pnpm add eslint-config-prettier eslint-plugin-prettier -D 然后在你的 eslint 配置文件中的 extends 中最后加上一个 plugin:prettier/recommended: { // ... "extends": [ // 一些别的配置 "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:vue/vue3-essential", // 将这个添加到最后 "plugin:prettier/recommended" ] } 如果使用的是 vscode 编辑器,注意要安装这两个插件: 同时加上这一段配置,可以在项目中添加配置文件 .vscode/settings.json,文件内容如下: { "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode" } 此时重启编辑器,可以做到完美格式化代码。要注意的是,此时不要在 eslint 配置文件中加上代码风格相关的配置,这样可能又会跟 prettier 冲突。上面的配置可以做到让 eslint 检查代码错误,让 prettier 格式化。所以要改变代码风格,请到 prettier 中修改。

三月 5, 2024 · 1 分钟 · 66 字 · 瓶子

换了一个黑暗模式切换动画

前阵子折腾博客,使用 Nuxt3 开发静态博客,开发过程还算顺利,但是部署过程不顺利,总感觉有什么东西没搞清楚,官网文档也写得真烂,半成品也不想用,先搁置着吧。如果使用 SSG 的部署方式,直接用 Hugo 也没什么不好,索性再回归到 Hugo 上来。不过我把之前开发的黑暗模式切换动画搬过来了,效果还不错。 博客左上角暗黑模式切换可看效果。主要依赖 View Transition API 中的 startViewTransition 方法实现动画的过度。这算是一个比较新的东西,兼容性并不是很好,如下: 具体修改过程就不记录了,每个主题都不一样,在网上搜下相关教程都能改。不过有一点需要强调下,如果使用类名切换来实现暗黑模式切换的,类名需要加在 html 标签上才能完美生效,这个我踩了坑,因为本主题的暗黑类名是加在 body 标签上的,导致我切换过程不完整生效,后来修改到 html 标签上就好了。 说点题外话,没想好博客后面怎么弄,评论区也先关闭了。博客应该以内容为主,而我总想着先设计一个好看的,符合自己审美的界面博客,但是又没怎么输出内容,有点本末倒置了。后面我应该会在博客上多记录一些有意义的内容,再去考虑重新设计个人博客界面,当然前提是我还有精力。

一月 31, 2024 · 1 分钟 · 24 字 · 瓶子

理解前端框架中的运行时和编译时

本文主要阐述前端框架中的运行时和编译时的区别。首先说明本文内容参考书籍 《Vue.js 设计与实现》,并加以自己的理解创作。有错误的地方还请指出。 运行时 运行时就是指代码实际执行时的阶段。前端代码是在浏览器中执行的,换言之,如果一个框架的代码可以直接在浏览器中执行,那它就是一个纯运行时的框架。 举个例子,假设我们设计了一个框架,它提供一个 Render 函数,用户使用时,为该函数提供一个描述 DOM 树形结构的参数对象,然后 Render 函数根据该对象递归地将数据渲染成 DOM 元素。假设规定要传入的对象结构如下: const obj = { tag: "div", children: [ { tag: "span", children: "hello world!", }, ], }; 对象中有两个属性:tag 代表标签名称,children 可以是数组(代表子节点)也可以是文本(代表文本子节点)。然后实现 Render 函数: function Render(obj, root) { const el = document.createElement(obj.tag); if (typeof obj.children === "string") { const text = document.createTextNode(obj.children); el.appendChild(text); } else if (obj.children) { obj.children.forEach((child) => Render(child, el)); } root.appendChild(el); } 现在可以在浏览器环境中调用 Render 函数:...

八月 11, 2023 · 1 分钟 · 212 字 · 瓶子

TypeScript 中 any 和 unknown 的区别

本文简单记录一下 any 和 unknown 的区别。 相同点:any 和 unknown 可以是任何类的父类,即任何类型的变量都可以赋值给 any 类型的变量或者 unknown 类型的变量,例: // any let anyVal: any; anyVal = 1; anyVal = "hello"; anyVal = true; anyVal = null; anyVal = undefined; anyVal = []; anyVal = {}; anyVal = function () {}; // unknown let unknownVal: unknown; unknownVal = 1; unknownVal = "hello"; unknownVal = true; unknownVal = null; unknownVal = undefined; unknownVal = []; unknownVal = {}; unknownVal = function () {}; 不同点...

四月 7, 2023 · 1 分钟 · 156 字 · 瓶子

新的脚本,自动部署 Hugo 博客至服务器

之前写过一篇 通过 Github Actions 实现 Hugo 博客的自动构建部署,现在感觉部署脚本写的有点复杂了,所以重新写了一个脚本,简化了不少,内容如下: name: Auto Deploy on: push: branches: - main pull_request: jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: "0.110.0" extended: true - name: Build run: hugo --minify - name: Rsync Deployments Action uses: Burnett01/rsync-deployments@5.2.1 with: switches: -avzr --delete path: ./public/ remote_path: # 填服务器部署目录 remote_host: # 填服务器IP地址 remote_port: # 填端口号,一般就是 22 remote_user: # 填服务器用户名 remote_key: ${{ secrets....

三月 19, 2023 · 1 分钟 · 90 字 · 瓶子