From 647ce4ef4238d22ef53dcf1c5be2c62089b0cb66 Mon Sep 17 00:00:00 2001 From: imbant <13634731015@sina.cn> Date: Tue, 14 Jan 2025 09:44:04 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20imbant/b?= =?UTF-8?q?log@c5d571406fc11cbc09eb230acb146f40b7429dae=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index.html" | 2 +- 2024/12/31/LSP2/index.html | 26 ++++---- about/index.html | 2 +- index.html | 2 +- sitemap.txt | 10 +-- sitemap.xml | 62 +++++++++---------- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git "a/2024/11/12/\345\234\250-VS-Code-\344\270\255\350\260\203\350\257\225\345\222\214\350\277\220\350\241\214-Go-\347\250\213\345\272\217/index.html" "b/2024/11/12/\345\234\250-VS-Code-\344\270\255\350\260\203\350\257\225\345\222\214\350\277\220\350\241\214-Go-\347\250\213\345\272\217/index.html" index ea320ff..7793690 100644 --- "a/2024/11/12/\345\234\250-VS-Code-\344\270\255\350\260\203\350\257\225\345\222\214\350\277\220\350\241\214-Go-\347\250\213\345\272\217/index.html" +++ "b/2024/11/12/\345\234\250-VS-Code-\344\270\255\350\260\203\350\257\225\345\222\214\350\277\220\350\241\214-Go-\347\250\213\345\272\217/index.html" @@ -43,4 +43,4 @@

1
2
3
4
5
6
{
"type": "go",
"request": "launch",
"mode": "debug",
++ "console": "internalConsole"
}

参考 Stack Overflow,也可以在 args 中配置标准输入重定向。

-
GoVS Code单元测试
LSP 与 VS Code 插件开发(二)语义构建
\ No newline at end of file +
VS CodeGo单元测试
LSP 与 VS Code 插件开发(二)语义构建
\ No newline at end of file diff --git a/2024/12/31/LSP2/index.html b/2024/12/31/LSP2/index.html index e521459..efab43b 100644 --- a/2024/12/31/LSP2/index.html +++ b/2024/12/31/LSP2/index.html @@ -3,7 +3,7 @@ gtag('js', new Date()); gtag('config', 'G-ZM9NGRYKWS'); -

LSP 与 VS Code 插件开发(二)语义构建

上一章我们讲到,语言服务器的输入是源码,而输出是结构化的数据。代码编辑器(客户端)某个位置显示什么颜色,鼠标悬浮到某个位置提示什么信息,都由客户端向语言服务器请求,获取数据后,渲染到用户界面。

+

LSP 与 VS Code 插件开发(二)语义构建

上一章我们讲到,语言服务器的输入是源码,而输出是结构化的数据。代码编辑器(客户端)某个位置显示什么颜色,鼠标悬浮到某个位置提示什么信息,都由客户端向语言服务器请求,获取数据后,渲染到用户界面。

因此语言服务器需要编译源码,构建语义模型,为客户端提供智能编程服务

所谓的 编译 是怎么回事?它和编译器是什么关系?本章会和大学里的编译原理知识有些关系,但保证比课本上的更有趣、更好玩!

语言服务器与编译器的关系

先回顾一下编译原理的基本流程:
词法分析 -> 语法分析 -> 语义分析 -> 中间代码生成 -> 代码优化 -> 目标代码生成 -> ...

@@ -46,21 +46,21 @@

容错

此外,两者的容错处理也是不一样的。当源码中出现了错误:
编译器会停止编译,通过标准输出等方式抛出编译错误,自然也没有目标产物的输出了,当然,一行代码的改动可能引起数个文件的错误,如果只遇到一个错误就停止编译,也不利于 debug,往往会尝试尽可能多的抛出错误;
而用户会持续不断的编码,你可以想一下,输入编写一行代码时,可能只有输入了最后一个分号 ; 后,编译才会通过,而这期间语言服务器则会持续工作,进程不会停止,而是收集 Diagnostic,也就是诊断信息,客户端根据这些信息,在代码编辑器上显示红色或者橙色的波浪线。

-

通常来说,编译器能顺利编译通过的工程,语言服务器也不应出现诊断\。反过来,代码编辑器中没有波浪线,理论上编译也是能过的。
碰到代码编辑器中标红,但能编译通过的情况倒是还好,如果代码编辑器没问题,但编译时报错,那就痛苦了。这种一般都是由于编译器和语言服务器没有统一编译标准导致的,例如两种的编译配置不同,同样一段代码,语言服务器认为是 warning,但编译器认为是 error,甚至是两者的语言版本不同(比如 python2 和 python3)。
另外,像 VS Code 这样的编辑器都支持插件,可能除了语言官方的语言服务器,还有别的(例如 lint 工具)在同时工作,这也会导致代码编辑器里看到的诊断比编译输出的多。从这个角度上,编译器和语言服务器的一致性也是工程化的一个重要问题。

+

通常来说,编译器能顺利编译通过的工程,语言服务器也不应出现诊断。反过来,代码编辑器中没有波浪线,理论上编译也是能过的。
碰到代码编辑器中标红,但能编译通过的情况倒是还好,如果代码编辑器没问题,但编译时报错,那就痛苦了。这种一般都是由于编译器和语言服务器没有统一编译标准导致的,可能是两者编译配置不同,同样一段代码,语言服务器认为是 warning,但编译器认为是 error,甚至是两者的语言版本不同(比如 python2 和 python3)。
另外,像 VS Code 这样的编辑器都支持插件,可能除了语言官方的语言服务器,还有别的(例如 lint 工具)在同时工作,这也会导致代码编辑器里看到的诊断比编译输出的多。从这个角度上,编译器和语言服务器的一致性也是工程化的一个重要问题。

+

这里可以看到,语言服务器的工作和运行时是无关的。换句话说,使用记事本写的 Hello World,没有语言服务器参与,经过编译器编译后,同样可以执行,而语言服务器提供的只是更好的编码体验,也就是 DX(developer experience)。

总的来说,编译器面向运行时一次性执行,要求最终正确性和可执行性,而语言服务器在用户编码时持续服务,要求及时性和友好性。

-

这里可以看到,语言服务器的工作和运行时是无关的。换句话说,使用记事本写的 Hello World,经过编译器编译后,同样可以执行,而语言服务器提供的只是更好的编码体验。

使用同一种语言构建

上一章提到,语言服务器与编译器往往是同一种编程语言构建的程序。现在你应该更理解了,在编译原理前端,两者的逻辑高度相似,往后才开始异化。使用同一种语言,甚至在同一个工程中,能最大的复用代码,减少维护成本。这也是促成语言服务器架构的原因之一。
事实上很多语言或是编译器内置语言服务器,例如 DenoTypeScript ,或是在内置工具链中就有语言服务器,例如 Go 和 Gopls、Rust 和 RLS。

当然,语言服务器的实现也并不仅是官方一种,VS Code 就受不了 PHP 解析器不能容错,直接新写了一个语言服务器

-

深入理解语法分析与语义分析

刚才提到了语法分析和语义分析,这里再举几个例子详细说明下。

+

深入理解语法与语义

刚才提到了语法分析和语义分析,这里再举几个例子详细说明下。

十六进制颜色字面量

假设我们要设计一门新的编程语言,支持十六进制的颜色字面量值。方案如下:
语法:定义为井号 # 后跟多个十六进制字符(0-9, a-f, A-F)。
语义:仅长度为 3 (rgb)、4(rgba)、6(rrggbb)或者 8(rrggbbaa)的十六进制序列视为合法颜色值。

-

从语法上没有约束十六进制字符数量的好处在于,语法规则宽松,便于解析和扩展,并且容错性友好。
一套语法描述可能复用于编译器、语言服务器、lint 工具等多个软件,而语义实现则各不相同。因此语法设计应该更宽松和易扩展。

+

从语法上没有约束十六进制字符数量。好处在于语法规则宽松,便于解析和扩展,并且容错友好。
一套语法描述可能复用于编译器、语言服务器、lint 工具等多个软件,而由于软件功能不同,语义实现则各不相同。因此语法设计应该更宽松和易扩展。

1
2
3
4
5
6
7
8
9
10
合法,白色
#fff

语法错误,z不是十六进制字符,
#zzz

语义错误,长度不对
#ff
#fffff
#ffffffffffffffffff

类型推导和显式类型声明

再举一个变量定义的例子

1
var a = 5
-

a 的值是 5,类型是整数。这里没有显式的声明 a 的类型,因此是通过等号右边的表达式的类型推导出来的。
右值是一个字面量,从词法分析可以通过正则匹配之类的方法得知它是一个 token,比如叫 INT_DIGIT。接着语法分析时,得知 INT_DIGIT 就是一个普通的字面量表达式。然后语义分析时,就知道一个整数字面量表达式的类型是整数,这是编程语言运行时就定义好的,无需额外的语法声明的(typeof 5 == "int")。
与之对应的,如果给 a 加了显式的类型声明:

+

a 的值是 5,类型是整数。这里没有显式的声明 a 的类型,因此是通过等号右边的表达式的类型推导出来的。
右值是一个字面量,词法分析时可以通过正则匹配之类的方法得知它是一个 token,比如叫 INT_DIGIT。接着语法分析时,得知 INT_DIGIT 就是一个普通的字面量表达式。然后语义分析时,就知道一个整数字面量表达式的类型是整数,这是编程语言运行时就定义好的,无需额外的语法声明的(typeof 5 == "int")。
与之对应的,如果给 a 加了显式的类型声明:

1
var a int = 5

那么语法上就是通过等号左边的 int token,在语义上查找符号表得知是整数类型。接着和右值类型比较,发现是一致的,这样就通过了类型检查。

@@ -75,28 +75,28 @@

语法错误更快出现

语义错误通常比语法错误更晚出现,因为语法错误出现在语法分析阶段,而语义错误在后一个语义分析阶段。

+

语法错误更快出现

语义错误通常比语法错误更晚出现,因为语法错误出现在语法分析阶段,而语义错误在之后的语义分析阶段。

通常编译单个文件,已经能得到完整的语法错误信息,而语义错误可能需要等整个工程的编译才能完全收集到。

-

例如,有些编程语言里支持“严格模式”,用来增强类型检查、避免隐式错误等。它在语法上可能就是一行字符串字面量或者魔法注释,例如 "use strict" 或者 // @ts-check。它们自身没有语法错误,但是会影响后续成千上万行代码的语义分析,带来数个语义错误。

-

这里有一个提高语言服务器性能的方法:
将语言服务器拆分成两个,一个面向语法,一个面向语义。
语法服务器很轻量,只负责词法分析、语法分析,有语法错误时立即反馈诊断。另外也可以提供一些完全基于语法的,和语义无关的小功能,例如
显示颜色
语义服务器更重,负责全部的语义构建和服务。
将语法诊断和其他小功能从语义服务器中剥离,可以降低语义服务器的开销,也能让轻量的功能更快的反馈给用户。

+

例如,有些编程语言里支持“严格模式”,用来增强类型检查、避免隐式错误等。它在语法上可能就是一行字符串字面量或者魔法注释,例如 "use strict" 或者 // @ts-check。它们自身没有语法错误,但是加上这行代码会影响后续成千上万行代码的语义分析,带来数个语义错误。

+

这里有一个提高语言服务器性能的方法:
将语言服务器拆分成两个,一个面向语法,一个面向语义。
语法服务器很轻量,只负责词法分析、语法分析,有语法错误时立即反馈诊断。另外也可以提供一些完全基于语法的,和语义无关的小功能,例如显示颜色
语义服务器更重,负责全部的语义构建和服务。
将语法诊断和其他小功能从语义服务器中剥离,可以降低语义服务器的开销,也能让轻量的功能更快的反馈给用户。
当然,这不是说语义服务器就不做词法、语法分析了,依然会做,甚至尝试容错,但会更专注在和语义相关的功能上。

Vue 的语言服务器就是这么做的。

语义模型

这里展示一下我做的基于 Node 的语言服务器,编译这段代码后得到的语义模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
graph test {
func A() {
for i = 0, 10, 1 {
if true {
LogInfo(i)
}
}
var a = 1
while true {
a++
}
}

func B() {

}
}

-

这是一门自研的 DSL 语言,其具体的语义就不做讨论了,但可以看到,在 Node 内存中,我的语义模型是一个大的对象,graphfuncforifwhile 关键字分别开辟了新的作用域,它们层层嵌套,形成一颗树结构。
既然是树结构,深度优先遍历算法就是可行的。第 4 行的 if 语句,要从根节点开始经过 root -> func A -> for -> if 几个语法节点,才能访问的到。
鼠标移动到第 5 行的 LogInfo 上,就要经过上述的深度优先搜索,根据鼠标位置的行列号,一层一层查找语义模型,得知此位置的语义是一个函数名,悬浮提示出函数签名,按 F12 还能跳转到函数声明的地方。
这个在树结构上层层查找的过程,有点类似语法分析中由上至下的递归下降分析法,从非终结符开始,递归展开,直到终结符;或者反过来,从终结符开始,递归折叠,直到非终结符。但两者还是有本质区别的,语法分析是为了构建语法树,而语义分析是基于语法树,构建语义模型。只不过从实现上,我的语义模型也是一个树结构的,毕竟是基于语法,两者的树结构也是相似的。

+

这是一门自研的 DSL 语言,其具体的语义就不做讨论了,但可以看到,在 Node 内存中,我的语义模型是一个大的对象,graphfuncforifwhile 关键字分别开辟了新的作用域,它们层层嵌套,形成一颗树结构。
既然是树结构,深度优先遍历算法就是可行的。第 4 行的 if 语句,要从根节点开始经过 root -> func A -> for -> if 几个语法节点,才能访问的到。
鼠标移动到第 5 行的 LogInfo 上,就要经过上述的深度优先搜索,根据鼠标位置的行列号,一层一层查找语义模型,得知此位置的语义是一个函数名,悬浮提示出函数签名,按 F12 还能跳转到函数声明的地方。
这个在树结构上层层查找的过程,有点类似语法分析中由上至下的递归下降分析法,从非终结符开始,递归展开,直到终结符;或者反过来,从终结符开始,递归折叠,直到非终结符。但两者还是有本质区别的,语法分析是为了构建语法树,而语义分析是基于语法树,构建语义模型。只不过从实现上,这个语义模型也是一个树结构的,毕竟是基于语法,两者的结构也是相似的。

shadow 机制

有了这个形象的树形结构,我们就可以从新的角度理解编程语言中的 shadow 机制。
shadow 机制通常指在当前作用域和外层作用域中,同名变量的优先级问题。

1
2
3
4
5
6
7
8
9
10
11
func A() {
var foo = 0
while (true) {
var foo = 1
if true {
var foo = 2

foo += 10
}
}
}
-

第 8 行的 foo 变量最终的值会是 12,也就是改变了第 6 行的 foo,即使外层还有两个同名变量。
在语义分析阶段,第 8 行是一个加法赋值语句,右值是 10,左值是一个符号 x。为了找到这个符号的语义,语言服务器会就近当前位置的语义模型的作用域开始寻找,也就是 if 开辟的作用域中,发现符号表中有一个 foo,它的语义是 int 类型的变量。这样,第 8 行的 foo 符号就是一个变量的语义了,也许会变成 variable 的蓝色;而它的定义位置,根据符号表,得知在第 6 行,按 F12 跳转到定义,光标就会跳转到第 6 行。
另外,得知第 8 行 foo 的语义后,还会做一系列的语义检查,常见的编程语言可能会检查:

+

第 8 行的 foo 变量最终的值会是 12,也就是改变了第 6 行的 foo,即使外层还有两个同名变量。
在语义分析阶段,第 8 行是一个加法赋值语句,右值是 10,左值是一个符号 x。为了找到这个符号的语义,语言服务器会从语义模型中当前光标位置的就近作用域开始寻找,也就是 if 开辟的作用域中,发现符号表中有一个 foo,它的语义是 int 类型的变量。这样,第 8 行的 foo 符号就是一个变量的语义了,也许会变成 variable 的蓝色;而它的定义位置,根据符号表,得知在第 6 行,按 F12 跳转到定义,光标就会跳转到第 6 行。
另外,得知第 8 行 foo 的语义后,还会做一系列的语义检查,常见的编程语言可能会检查:

    -
  1. foo 是可写的局部变量,可以被赋值
  2. +
  3. foo 是可写的局部变量,可以作为左值
  4. foo 是个整数,可以做加法赋值
  5. 右值是个整数字面量,和左值的类型相同,可以赋值

shadow 机制对于自动补全也有积极意义:在 if 代码块中,输入 fo,语言服务器应该仅列出一个 foo 变量,忽略外层的两个。让我们给最外层的 foo 改名叫 foo001

-
1
2
3
4
5
6
7
8
9
10
11
func A() {
var foo001 = 0
while (true) {
var foo = 1
if true {
var foo = 2

foo += 10
}
}
}
+
1
2
3
4
5
6
7
8
9
10
11
12
func A() {
-- var foo = 0
++ var foo001 = 0
while (true) {
var foo = 1
if true {
var foo = 2

foo += 10
}
}
}

这时候就会补全 if 中的 foo 和外层的 foo001,而不会再出现 while 中的 foo

diff --git a/about/index.html b/about/index.html index 06128da..744d58a 100644 --- a/about/index.html +++ b/about/index.html @@ -11,7 +11,7 @@

我在各个平台的昵称为:imbAnt,前缀取自 imbalance,在游戏领域意为 awesome。后缀取自高中绰号「蚂蚁」。

即刻:imbant

GitHub: @imbant

-

Email: 13634731015@sina.cn

+

Email: 13634731015@sina.cn

灰机 Wiki:@Imbant

\ No newline at end of file diff --git a/index.html b/index.html index bedec42..f7d8477 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ gtag('js', new Date()); gtag('config', 'G-ZM9NGRYKWS'); -

Hi 👋,欢迎访问我的博客


我是一名前端开发者,VS Code 插件和语言服务器开发者

我目前在开发基于 LSP 的 语言服务器,也在维护用 Go 构建的编译器

这里查看更多关于我的更多信息


我希望通过这个博客记录技术知识,提升影响力。如果你感兴趣,可以看看这些文章:

我为 VS Code 贡献了代码:这篇文章登上了阮一峰的科技爱好者周刊

LSP 与 VS Code 插件开发 第一章:记录我对 LSP 和语言服务器开发系列文章

怎么让 favicon 动起来:发现了吗,本网站的 favicon 会动



LSP 与 VS Code 插件开发(二)语义构建

上一章我们讲到,语言服务器的输入是源码,而输出是结构化的数据。代码编辑器(客户端)某个位置显示什么颜色,鼠标悬浮到某个位置提示什么信息,都由客户端向语言服务器请求,获取数据后,渲染到用户界面。

+

Hi 👋,欢迎访问我的博客


我是一名前端开发者,VS Code 插件和语言服务器开发者

我目前在开发基于 LSP 的 语言服务器,也在维护用 Go 构建的编译器

这里查看更多关于我的更多信息


我希望通过这个博客记录技术知识,提升影响力。如果你感兴趣,可以看看这些文章:

我为 VS Code 贡献了代码:这篇文章登上了阮一峰的科技爱好者周刊

LSP 与 VS Code 插件开发 第一章:记录我对 LSP 和语言服务器开发系列文章

怎么让 favicon 动起来:发现了吗,本网站的 favicon 会动



LSP 与 VS Code 插件开发(二)语义构建

上一章我们讲到,语言服务器的输入是源码,而输出是结构化的数据。代码编辑器(客户端)某个位置显示什么颜色,鼠标悬浮到某个位置提示什么信息,都由客户端向语言服务器请求,获取数据后,渲染到用户界面。

因此语言服务器需要编译源码,构建语义模型,为客户端提供智能编程服务


阅读全文

在 VS Code 中调试和运行 Go 程序

习惯了 VS Code,使用 GoLand 总是不顺手。这里总结一些在 VS Code 中调试和运行 Go 程序的方法。

准备工作

必不可少的是 Go 插件。安装后可以做一些基础配置:


阅读全文

我为 VS Code 贡献了代码

今天发现我提给 VS Code 的 PR 被官方感谢了。深受鼓舞!


阅读全文

LSP 与 VS Code 插件开发(一)语言服务器架构

背景

我是一名语言服务器开发者、VS Code 插件开发者。
我开发了这款插件。它集成了一个基于 LSP 的语言服务器,可以为自研编程语言提供智能编程功能。


阅读全文

RubyConf China 2023 笔记

周末参加了 RubyConf China 2023,很奇妙的一段体验!作为一个前端,在同样是脚本语言的 Ruby 会议上听到了 React18,WebAssembly,Rust,Rails,LSP 这些概念,也会有些内容对比到 ts 或者 js,会有“原来 Ruby 程序员是这样思考的”的想法。虽然 Ruby 代码看不懂,拓宽视野还是让我耳目一新。


阅读全文

从源码看 Vue 组件销毁后触发其事件

从一个 bug 说起

记录一个 Vue 组件事件的边界情况。项目中有一个组件,是一个面板,可以通过拖拽改变自身尺寸,也可以被关闭。


阅读全文

怎么让 favicon 动起来

博客一直缺一个 favicon,在标签栏里和其他网页放在一起,就显得很丑,一看就是半成品网页。

diff --git a/sitemap.txt b/sitemap.txt index 788ddda..1519292 100644 --- a/sitemap.txt +++ b/sitemap.txt @@ -1,16 +1,13 @@ -https://imbant.github.io/blog/2020/05/08/%E5%91%BD%E4%BB%A4%E8%A1%8C%E9%80%89%E9%A1%B9%E6%A0%87%E5%87%86/ -https://imbant.github.io/blog/2024/11/12/%E5%9C%A8-VS-Code-%E4%B8%AD%E8%B0%83%E8%AF%95%E5%92%8C%E8%BF%90%E8%A1%8C-Go-%E7%A8%8B%E5%BA%8F/ https://imbant.github.io/blog/2023/03/16/%E5%A6%82%E4%BD%95%E5%8F%82%E4%B8%8E%E7%BC%96%E8%BE%91-mdn-%E4%B8%AD%E6%96%87%E9%A1%B5%E9%9D%A2/ https://imbant.github.io/blog/2019/12/11/%E5%AE%89%E5%8D%93%E5%BE%AE%E4%BF%A1-%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE-%E7%9B%B8%E5%85%B3%E8%B8%A9%E5%9D%91/ https://imbant.github.io/blog/2021/07/20/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%B7%A8%E5%88%86%E5%8C%85%E5%A4%8D%E7%94%A8%E4%BB%A3%E7%A0%81%E6%96%B9%E6%A1%88/ https://imbant.github.io/blog/2023/03/30/%E6%80%8E%E4%B9%88%E8%AE%A9-favicon-%E5%8A%A8%E8%B5%B7%E6%9D%A5/ https://imbant.github.io/blog/2019/08/11/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/ -https://imbant.github.io/blog/2021/05/01/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/ https://imbant.github.io/blog/1970/01/01/%E6%9A%82%E5%AD%98%E5%8C%BA/ +https://imbant.github.io/blog/2021/05/01/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/ https://imbant.github.io/blog/2022/04/15/%E6%BC%AB%E8%B0%88%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/ https://imbant.github.io/blog/2023/01/17/%E9%A1%B5%E9%9D%A2%E6%BB%9A%E5%8A%A8%E6%97%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B2%A1%E6%9C%89%E8%A7%A6%E5%8F%91%20mouseleave%20%E4%BA%8B%E4%BB%B6/ https://imbant.github.io/blog/about/index.html -https://imbant.github.io/blog/2024/12/31/LSP2/ https://imbant.github.io/blog/2019/08/09/Node-require-%E6%89%A7%E8%A1%8C%E7%BB%86%E8%8A%82/ https://imbant.github.io/blog/2020/04/10/Promise-%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A/ https://imbant.github.io/blog/2020/03/13/React-Diffing-%E7%AE%97%E6%B3%95/ @@ -25,6 +22,9 @@ https://imbant.github.io/blog/2023/07/25/%E4%BB%8E%E6%BA%90%E7%A0%81%E7%9C%8B%20 https://imbant.github.io/blog/2019/10/10/%E5%85%B3%E4%BA%8E-js-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/ https://imbant.github.io/blog/2021/09/28/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87%E4%B8%8E%E5%AE%9E%E7%8E%B0/ https://imbant.github.io/blog/2021/10/22/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E4%B8%8E%E8%B7%A8%E5%9F%9F/ +https://imbant.github.io/blog/2020/05/08/%E5%91%BD%E4%BB%A4%E8%A1%8C%E9%80%89%E9%A1%B9%E6%A0%87%E5%87%86/ +https://imbant.github.io/blog/2024/11/12/%E5%9C%A8-VS-Code-%E4%B8%AD%E8%B0%83%E8%AF%95%E5%92%8C%E8%BF%90%E8%A1%8C-Go-%E7%A8%8B%E5%BA%8F/ +https://imbant.github.io/blog/2024/12/31/LSP2/ https://imbant.github.io/blog/2020/03/24/TCP-%E8%BF%9E%E6%8E%A5%E7%9A%84%E7%BB%86%E8%8A%82%E8%AF%A6%E8%B0%88/ https://imbant.github.io/blog/2020/02/25/BrowserRouter-vs-HashRouter/ https://imbant.github.io/blog/2019/12/20/CSS-%E6%96%B9%E5%BC%8F%E8%A7%A3%E5%86%B3-iOS-%E5%BE%AE%E4%BF%A1%E6%A9%A1%E7%9A%AE%E7%AD%8B%E6%95%88%E6%9E%9C%E4%B8%8E-position-fixed-%E8%81%94%E5%8A%A8%E7%9A%84%E5%9D%91/ @@ -41,10 +41,10 @@ https://imbant.github.io/blog/2022/08/12/JS-%E5%AF%B9%E8%B1%A1%E5%88%B0%E5%8E%9F https://imbant.github.io/blog/2022/04/30/JS-%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%88%A4%E6%96%AD/ https://imbant.github.io/blog/2024/08/24/LSP1/ https://imbant.github.io/blog -https://imbant.github.io/blog/tags/Go/ https://imbant.github.io/blog/tags/LSP/ https://imbant.github.io/blog/tags/VS-Code/ https://imbant.github.io/blog/tags/%E8%AF%AD%E8%A8%80%E6%9C%8D%E5%8A%A1%E5%99%A8/ +https://imbant.github.io/blog/tags/Go/ https://imbant.github.io/blog/tags/%E6%9D%82%E8%B0%88/ https://imbant.github.io/blog/tags/React-Router/ https://imbant.github.io/blog/tags/CSS/ diff --git a/sitemap.xml b/sitemap.xml index 333c892..7a7dc28 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,7 +2,7 @@ - https://imbant.github.io/blog/2020/05/08/%E5%91%BD%E4%BB%A4%E8%A1%8C%E9%80%89%E9%A1%B9%E6%A0%87%E5%87%86/ + https://imbant.github.io/blog/2023/03/16/%E5%A6%82%E4%BD%95%E5%8F%82%E4%B8%8E%E7%BC%96%E8%BE%91-mdn-%E4%B8%AD%E6%96%87%E9%A1%B5%E9%9D%A2/ 2025-01-14 @@ -11,7 +11,7 @@ - https://imbant.github.io/blog/2024/11/12/%E5%9C%A8-VS-Code-%E4%B8%AD%E8%B0%83%E8%AF%95%E5%92%8C%E8%BF%90%E8%A1%8C-Go-%E7%A8%8B%E5%BA%8F/ + https://imbant.github.io/blog/2019/12/11/%E5%AE%89%E5%8D%93%E5%BE%AE%E4%BF%A1-%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE-%E7%9B%B8%E5%85%B3%E8%B8%A9%E5%9D%91/ 2025-01-14 @@ -20,7 +20,7 @@ - https://imbant.github.io/blog/2023/03/16/%E5%A6%82%E4%BD%95%E5%8F%82%E4%B8%8E%E7%BC%96%E8%BE%91-mdn-%E4%B8%AD%E6%96%87%E9%A1%B5%E9%9D%A2/ + https://imbant.github.io/blog/2021/07/20/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%B7%A8%E5%88%86%E5%8C%85%E5%A4%8D%E7%94%A8%E4%BB%A3%E7%A0%81%E6%96%B9%E6%A1%88/ 2025-01-14 @@ -29,7 +29,7 @@ - https://imbant.github.io/blog/2019/12/11/%E5%AE%89%E5%8D%93%E5%BE%AE%E4%BF%A1-%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE-%E7%9B%B8%E5%85%B3%E8%B8%A9%E5%9D%91/ + https://imbant.github.io/blog/2023/03/30/%E6%80%8E%E4%B9%88%E8%AE%A9-favicon-%E5%8A%A8%E8%B5%B7%E6%9D%A5/ 2025-01-14 @@ -38,7 +38,7 @@ - https://imbant.github.io/blog/2021/07/20/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%B7%A8%E5%88%86%E5%8C%85%E5%A4%8D%E7%94%A8%E4%BB%A3%E7%A0%81%E6%96%B9%E6%A1%88/ + https://imbant.github.io/blog/2019/08/11/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/ 2025-01-14 @@ -47,7 +47,7 @@ - https://imbant.github.io/blog/2023/03/30/%E6%80%8E%E4%B9%88%E8%AE%A9-favicon-%E5%8A%A8%E8%B5%B7%E6%9D%A5/ + https://imbant.github.io/blog/1970/01/01/%E6%9A%82%E5%AD%98%E5%8C%BA/ 2025-01-14 @@ -56,7 +56,7 @@ - https://imbant.github.io/blog/2019/08/11/%E6%8C%81%E7%BB%AD%E9%9B%86%E6%88%90/ + https://imbant.github.io/blog/2021/05/01/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/ 2025-01-14 @@ -65,7 +65,7 @@ - https://imbant.github.io/blog/2021/05/01/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/ + https://imbant.github.io/blog/2022/04/15/%E6%BC%AB%E8%B0%88%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/ 2025-01-14 @@ -74,7 +74,7 @@ - https://imbant.github.io/blog/1970/01/01/%E6%9A%82%E5%AD%98%E5%8C%BA/ + https://imbant.github.io/blog/2023/01/17/%E9%A1%B5%E9%9D%A2%E6%BB%9A%E5%8A%A8%E6%97%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B2%A1%E6%9C%89%E8%A7%A6%E5%8F%91%20mouseleave%20%E4%BA%8B%E4%BB%B6/ 2025-01-14 @@ -83,7 +83,7 @@ - https://imbant.github.io/blog/2022/04/15/%E6%BC%AB%E8%B0%88%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/ + https://imbant.github.io/blog/about/index.html 2025-01-14 @@ -92,7 +92,7 @@ - https://imbant.github.io/blog/2023/01/17/%E9%A1%B5%E9%9D%A2%E6%BB%9A%E5%8A%A8%E6%97%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B2%A1%E6%9C%89%E8%A7%A6%E5%8F%91%20mouseleave%20%E4%BA%8B%E4%BB%B6/ + https://imbant.github.io/blog/2019/08/09/Node-require-%E6%89%A7%E8%A1%8C%E7%BB%86%E8%8A%82/ 2025-01-14 @@ -101,7 +101,7 @@ - https://imbant.github.io/blog/about/index.html + https://imbant.github.io/blog/2020/04/10/Promise-%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A/ 2025-01-14 @@ -110,7 +110,7 @@ - https://imbant.github.io/blog/2024/12/31/LSP2/ + https://imbant.github.io/blog/2020/03/13/React-Diffing-%E7%AE%97%E6%B3%95/ 2025-01-14 @@ -119,7 +119,7 @@ - https://imbant.github.io/blog/2019/08/09/Node-require-%E6%89%A7%E8%A1%8C%E7%BB%86%E8%8A%82/ + https://imbant.github.io/blog/2020/03/09/React-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/ 2025-01-14 @@ -128,7 +128,7 @@ - https://imbant.github.io/blog/2020/04/10/Promise-%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A/ + https://imbant.github.io/blog/2023/08/21/RubyConf-China-2023-%E7%AC%94%E8%AE%B0/ 2025-01-14 @@ -137,7 +137,7 @@ - https://imbant.github.io/blog/2020/03/13/React-Diffing-%E7%AE%97%E6%B3%95/ + https://imbant.github.io/blog/2019/09/11/Token-Session-Cookie/ 2025-01-14 @@ -146,7 +146,7 @@ - https://imbant.github.io/blog/2020/03/09/React-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/ + https://imbant.github.io/blog/2024/10/29/VS-Code-Thankyou/ 2025-01-14 @@ -155,7 +155,7 @@ - https://imbant.github.io/blog/2023/08/21/RubyConf-China-2023-%E7%AC%94%E8%AE%B0/ + https://imbant.github.io/blog/2019/11/19/flex-box-%E4%B8%8B%E7%9A%84%E5%AE%BD%E5%BA%A6%E9%97%AE%E9%A2%98/ 2025-01-14 @@ -164,7 +164,7 @@ - https://imbant.github.io/blog/2019/09/11/Token-Session-Cookie/ + https://imbant.github.io/blog/2020/04/07/web-%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%BC%80%E5%8F%91%E8%B8%A9%E5%9D%91/ 2025-01-14 @@ -173,7 +173,7 @@ - https://imbant.github.io/blog/2024/10/29/VS-Code-Thankyou/ + https://imbant.github.io/blog/2023/03/03/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%86%99%E5%8D%9A%E5%AE%A2/ 2025-01-14 @@ -182,7 +182,7 @@ - https://imbant.github.io/blog/2019/11/19/flex-box-%E4%B8%8B%E7%9A%84%E5%AE%BD%E5%BA%A6%E9%97%AE%E9%A2%98/ + https://imbant.github.io/blog/2023/07/25/%E4%BB%8E%E6%BA%90%E7%A0%81%E7%9C%8B%20Vue%20%E7%BB%84%E4%BB%B6%E9%94%80%E6%AF%81%E5%90%8E%E8%A7%A6%E5%8F%91%E5%85%B6%E4%BA%8B%E4%BB%B6/ 2025-01-14 @@ -191,7 +191,7 @@ - https://imbant.github.io/blog/2020/04/07/web-%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%BC%80%E5%8F%91%E8%B8%A9%E5%9D%91/ + https://imbant.github.io/blog/2019/10/10/%E5%85%B3%E4%BA%8E-js-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/ 2025-01-14 @@ -200,7 +200,7 @@ - https://imbant.github.io/blog/2023/03/03/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%86%99%E5%8D%9A%E5%AE%A2/ + https://imbant.github.io/blog/2021/09/28/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87%E4%B8%8E%E5%AE%9E%E7%8E%B0/ 2025-01-14 @@ -209,7 +209,7 @@ - https://imbant.github.io/blog/2023/07/25/%E4%BB%8E%E6%BA%90%E7%A0%81%E7%9C%8B%20Vue%20%E7%BB%84%E4%BB%B6%E9%94%80%E6%AF%81%E5%90%8E%E8%A7%A6%E5%8F%91%E5%85%B6%E4%BA%8B%E4%BB%B6/ + https://imbant.github.io/blog/2021/10/22/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E4%B8%8E%E8%B7%A8%E5%9F%9F/ 2025-01-14 @@ -218,7 +218,7 @@ - https://imbant.github.io/blog/2019/10/10/%E5%85%B3%E4%BA%8E-js-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0/ + https://imbant.github.io/blog/2020/05/08/%E5%91%BD%E4%BB%A4%E8%A1%8C%E9%80%89%E9%A1%B9%E6%A0%87%E5%87%86/ 2025-01-14 @@ -227,7 +227,7 @@ - https://imbant.github.io/blog/2021/09/28/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87%E4%B8%8E%E5%AE%9E%E7%8E%B0/ + https://imbant.github.io/blog/2024/11/12/%E5%9C%A8-VS-Code-%E4%B8%AD%E8%B0%83%E8%AF%95%E5%92%8C%E8%BF%90%E8%A1%8C-Go-%E7%A8%8B%E5%BA%8F/ 2025-01-14 @@ -236,7 +236,7 @@ - https://imbant.github.io/blog/2021/10/22/%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E4%B8%8E%E8%B7%A8%E5%9F%9F/ + https://imbant.github.io/blog/2024/12/31/LSP2/ 2025-01-14 @@ -389,28 +389,28 @@ - https://imbant.github.io/blog/tags/Go/ + https://imbant.github.io/blog/tags/LSP/ 2025-01-14 weekly 0.2 - https://imbant.github.io/blog/tags/LSP/ + https://imbant.github.io/blog/tags/VS-Code/ 2025-01-14 weekly 0.2 - https://imbant.github.io/blog/tags/VS-Code/ + https://imbant.github.io/blog/tags/%E8%AF%AD%E8%A8%80%E6%9C%8D%E5%8A%A1%E5%99%A8/ 2025-01-14 weekly 0.2 - https://imbant.github.io/blog/tags/%E8%AF%AD%E8%A8%80%E6%9C%8D%E5%8A%A1%E5%99%A8/ + https://imbant.github.io/blog/tags/Go/ 2025-01-14 weekly 0.2