chore: migrate project to monorepo

This commit is contained in:
cqh963852 committed 2025-07-17 10:35:02 +08:00
1 parent 47dd739a28
commit 9195a387b2
125 files changed
+1478 -1364

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

-7
View File
@@ -1,7 +0,0 @@
{
"label": "高级教程",
"position": 6,
"link": {
"type": "generated-index"
}
}
-138
View File
@@ -1,138 +0,0 @@
---
sidebar_position: 6
---
# 面向前端的协同编程探索
低代码,无代码等概念已经不再新鲜。同时协同编程也会被经常提到。
虽然协同编程只是一个组合词 `协同` + `编程`,但是要做的事情远没有这么简单。
> 协同编程
>
> - 编辑 —— 协同编辑
> - 构建 —— 预置的构建方案
> - 运行 —— 在目标环境运行
## 编辑
编辑在传统的编辑器的基础上要求更高,需要协同编辑。
- 离线编辑
### 编辑器
- prosemirror
- codemirror
- monaco-editor
### 协同算法
- OT
- @codemirror/collab
- CRDT
- yjs
- automerge
相关文章
偏向数学理论
https://www.zxch3n.com/crdt-intro/design-crdt/
偏向实现细节
https://zhuanlan.zhihu.com/p/265074361
### 多窗口库
- https://github.com/caplin/FlexLayout
- https://github.com/ticlo/rc-dock
- https://github.com/golden-layout/golden-layout
- https://github.com/nomcopter/react-mosaic
- https://github.com/idealjs/layout-manager
## 构建
### 构建工具
- esbuild
- swc
- webpack https://github.com/webpack/playground 已过时
### 文件系统
- 虚拟文件系统
- memfs
- memory
- filer
- indexdb
- memory
- unionfs
- 文件系统
- FileSystem
- unionfs
## 运行
- dynamic import
- IIFE (Immediately Invoked Function Expression)
- iframe
使用了 `构建` + `运行` 的平台
- codesandbox
- codepen
- stackblitz
## 既要也要的矛盾
- 离线优先 与 CAP
传统分布式软件中分区容错性被看的很重要。离线优先也可以被视作分区容错的子集。
但是离线优先的设计带来了无法在协同编程中解决的问题。
### 场景
A B C 三人,P2P 协同编程。
存在一段错误的代码
```js
let = "A"
username = "C"
```
当三人同时开始修复此问题时,A出现离线情况。
B C 二人协同修复得到的结果
```js
let username = "A"
username = "C"
```
A 离线修复结果
```js
let username = "A"
username = "C"
```
看上去 A 与 B C 是一致的。但是在 CRDT 与 OT 算法中,并不是。最终 A 恢复连接,得到的结果是
```js
let usernameusername = "A"
username = "C"
```
对于协同编程来说,协同的好处是规避冲突。但是这种场景下,冲突被放大。
而这种情况在 git 的方案内,不会发生冲突。
-7
View File
@@ -1,7 +0,0 @@
{
"label": "全栈基础",
"position": 3,
"link": {
"type": "generated-index"
}
}
-8
View File
@@ -1,8 +0,0 @@
{
"label": "完整指南",
"position": 3,
"link": {
"type": "generated-index"
}
}
-7
View File
@@ -1,7 +0,0 @@
{
"label": "访问HTML网页的流程",
"position": 1,
"link": {
"type": "generated-index"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

-75
View File
@@ -1,75 +0,0 @@
---
sidebar_position: 1
---
# 访问 HTML 网页的流程
我们将通过 `http-server` 来模拟访问 HTML 网页的过程,从浏览器、网络和服务器这几个方面详细介绍。
## 创建index.html
1. 对于创建`index.html`文件,可以参考[使用VScode](https://idealjs.github.io/full-stack-tutorial/docs/web/hello_world/use_vscode)文档
2. 在`index.html`文件输入内容,可以参考[第一个页面(hello world)](https://idealjs.github.io/full-stack-tutorial/docs/web/hello_world/first_page)文档
## 安装http-server
运行以下命令进行安装,其中`-g`代表全局安装
```
npm install -g http-server
```
## 启动http-server
### 1.进入文件夹
安装完成并创建好`index.html`文件后,就可以通过以下命令进入包含`index.html`文件的文件夹
```
cd ~/test
```
### 2.启动服务
在控制台运行以下命令来启动服务
```
http-server
```
启动成功后,命令行会输出以下网址
![网址](./console.png)
这时,你可以在浏览器中输入 `http://127.0.0.1:8080` 或者`http://localhost:8080` 来访问你的网页
## 无痕模式
用户可以使用以下快捷键,打开无痕窗口
```
Ctrl+Shift+N
```
按下`F12`,进入检查
![无痕模式](./image.png)
## 先决条件
- 你需要已经安装并启动 `http-server`。
## 浏览器的工作步骤
### 1. 建立 TCP 连接
浏览器会向 `127.0.0.1:8080` 发送建立 TCP 连接的请求。服务器收到请求后,会确认客户端的身份,然后向客户端回复消息,从而建立起服务器与客户端之间的连接。
### 2. 发送 GET 请求
浏览器会向服务器发送一个路径为 `/` 的 GET 请求。
![请求路径](./get.png)
## 服务器的工作步骤
### 1. 查找文件
当服务器接收到浏览器的请求后,就像一位仓库管理员,会在众多文件中查找 `index.html` 文件。
![文件](./index.png)
### 2. 生成 HTTP 响应
服务器找到文件后,会对其进行处理,将其转换为适合在网络中传输的 HTTP 响应,如同把货物包装好以便运输。
### 3. 发送响应
服务器会通过之前与浏览器建立的“运输通道”(TCP 连接),将生成的 HTTP 响应发送给浏览器。
## 渲染页面
### 1. 接收资源并渲染
- 浏览器接收到资源后解析HTML、CSS和JavaScript
- 浏览器根据解析结果构建页面结构
### 2. 显示页面
页面渲染完成后,就会展示给用户。
-7
View File
@@ -1,7 +0,0 @@
{
"label": "react的入门",
"position": 4,
"link": {
"type": "generated-index"
}
}
-198
View File
@@ -1,198 +0,0 @@
---
sidebar_position: 2
---
# 如何使用react+ts编写前端todo list
本文将编写一个简单的前端todo list应用,从进入项目后,逐步实现增加,删除,筛选的功能
## 先决条件
1. 已创建react ts工程
>**提示**
若未创建react ts工程,可以参考[使用vite创建react ts工程](https://github.com/idealjs/full-stack-tutorial/blob/main/docs/react/react_ts.md)文档
## 项目初始化
打开react ts工程
## 编写todo list结构及功能
在`App.tsx`中,通过以下代码,设计结构并实现todo list的功能
```
//导入依赖
import React, { useState } from 'react'
import './App.css'
//定义全局变量,用于生成新数组的id
let nextId = 4
function App() {
//定义数组
const [products, setProducts] = useState([
{ name: '吃饭', completed: false, id: 1 },
{ name: '睡觉', completed: true, id: 2 },
{ name: '打豆豆', completed: true, id: 3 },
])
const [inputValue, setinputValue] = useState('')
//在input中输入的值
const handleInputValue = (event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setinputValue(value)
console.log('当前的值', value);
}
//在输入框中按下回车键的事件
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (inputValue === '') {
return
}
if (event.key === 'Enter') {
const newProduct = {
name: inputValue.trim(),
completed: false,
id: nextId++
}
setProducts([...products, newProduct]);
setinputValue('')
console.log(`按下回车键的值:${inputValue}`);
}
}
//切换completed的状态
const CompleteStatus = (id:number)=>{
setProducts(
products.map((product) =>
product.id === id ? {...product,completed: !product.completed} : product)
)
}
//筛选功能的实现
const [filter,setFilter] = useState<'all'|'active'|'completed'>('all')
const onShow = products.filter((product) => {
if(filter === 'active'){
return !product.completed
}else if(filter === 'completed'){
return product.completed
}else{
return true
}
})
const count = products.filter((product) => !product.completed).length
//渲染组件
return (
<>
<div>
<h1>TODO LIST</h1>
<input
className="input-todo"
type='text'
placeholder='您想做点什么'
onChange={handleInputValue}
onKeyDown={handleKeyDown}
value={inputValue}
></input>
<ul>
{/* {TodoItem} */}
{onShow.map(product => (
<li key={product.id}>{product.name}{' '}
<span className={`icon-complete ${product.completed ? 'icon-complete-active' : ''}`}
onClick={() => CompleteStatus(product.id)}
>
</span>{' '}
<button onClick={() => {
setProducts(products.filter((a) => a.id !== product.id));
}}>删除</button>
</li>
))}
</ul>
<div>
<span>还有<span>{count}</span>个未完成</span>
<div className='filter-btn-group'>筛选
<button onClick={()=> setFilter('all')}>全部</button>
<button onClick={()=> setFilter('active')}>未完成</button>
<button onClick={()=>setFilter('completed')}>已完成</button>
</div>
</div>
</div>
</>
)
}
export default App
```
## 设计todo list的样式
在`App.css`中,通过以下代码,设计todo list的样式
```
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
.icon-complete{
display: inline-block;
width: 20px;
height: 20px;
border: solid 1px #ddd;
border-radius: 50%;
}
.icon-complete-active::after{
content: '√';
color: green;
}
```
## 运行项目
按下快捷键`Ctrl + ~`,打开终端,输入以下命令,运行项目
```
npm run dev
```
![运行结果](./result2.png)
-33
View File
@@ -1,33 +0,0 @@
---
sidebar_position: 1
---
# 使用vite创建react ts工程
React 应用程序是由组件组成的。一个组件是 UI(用户界面)的一部分,它拥有自己的逻辑和外观。组件可以小到一个按钮,也可以大到整个页面。
## 项目初始化
### 1. 创建react+ts项目
按下快捷键`Ctrl + ~`,打开终端,运行以下命令
```
npm create vite@latest
```
根据提示,输入项目名字并选择react,再选择TypeScript
### 2. 打开项目
运行以下命令,进入项目
```
cd react-ts-test1
```
### 3. 安装依赖
运行以下命令,安装依赖
```
npm install
```
### 4. 运行项目
输入以下命令,运行项目
```
npm run dev
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

-7
View File
@@ -1,7 +0,0 @@
{
"label": "vite的入门",
"position": 2,
"link": {
"type": "generated-index"
}
}
-35
View File
@@ -1,35 +0,0 @@
---
sidebar_position: 1
---
# vite的入门
vite 是一个现代化的前端构建工具,旨在提供快速的开发体验和高效的生产构建。
## 什么是vite
访问网站 https://vitejs.cn/vite3-cn/guide/
## 创建vanilla ts工程
### 打开终端
使用快捷键`Ctrl+ ~` 打开终端
### 创建项目
1. 输入以下命令,创建项目
```
npm create vite@latest
```
2. 根据提示,输入名字并选择vanilla,再选择typescript
3. 输入以下命令,进入项目
```
cd vanilla-ts-test
```
4. 输入以下命令安装依赖
```
npm install
```
5. 输入以下命令运行项目
```
npm run dev
```
@@ -1,7 +0,0 @@
{
"label": "vanilla ts工程",
"position": 3,
"link": {
"type": "generated-index"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

@@ -1,200 +0,0 @@
---
sidebar_position: 1
---
# 如何使用html+ts编写前端todo list
## 先决条件
1. 已创建vanilla ts工程
>**提示**
若未安装vanilla ts工程,可以参考[vite的入门](https://github.com/idealjs/full-stack-tutorial/blob/main/docs/vite/vite.md)文档
## 项目初始化
打开vanilla ts工程
## 编写HTML结构
在`index.html`中,通过以下代码,编写todo list的样式和基本结构
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.icon-complete {
display: inline-block;
width: 20px;
height: 20px;
border: solid 1px #ddd;
border-radius: 50%;
}
.icon-complete-active {
border-color: green;
text-align: center;
}
.todo-item {
margin-bottom: 5px;
}
.icon-complete-active::after {
content: "√";
color: green;
}
.item-complete .todo-text {
color: #999;
text-decoration: line-through;
}
</style>
</head>
<body>
<div>
<input class="input-todo" type="text" placeholder="您想做点什么?">
<ul class="todo-list">
<li class="todo-item">
<span class="icon-complete" onclick="onClickCompleteBtn(0)"></span>
<span class="todo-text">吃饭</span>
<button class="btn-complete">完成</button>
<button class="deleted" onclick="deleteItem(0)">删除</button>
</li>
<li class="item-complete todo-item">
<span class="icon-complete icon-complete-active" onclick="onClickCompleteBtn(1)"></span>
<span class="todo-text">睡觉</span>
<button class="btn-complete">完成</button>
<button class="deleted" onclick="deleteItem(1)">删除</button>
</li>
<li class="item-complete todo-item">
<span class="icon-complete icon-complete-active" onclick="onClickCompleteBtn(2)"></span>
<span class="todo-text">打豆豆</span>
<button class="btn-complete">完成</button>
<button class="deleted" onclick="deleteItem(2)">删除</button>
</li>
</ul>
<div>
<span>还有<span class="active-num">1</span>个未完成</span>
<div class="fliter-btn-group">
筛选:
<button class="filter-btn filter-btn-all" data-complete="all">全部</button>
<button class="filter-btn filter-btn-active" data-complete="false">未完成</button>
<button class="filter-btn filter-btn-completed" data-complete="true">已完成</button>
<button class="btn-clear">清空</buttosn>
</div>
</div>
</div>
<script src="./src/main.ts">
</script>
</body>
</html>
```
## 编写TypeScript逻辑
在`main.ts`中,编写以下代码,实现todo list的功能
```
//定义接口TodoItem
interface TodoItem {
name: string;
completed: boolean;
}
//初始化数组
let list: TodoItem[] = [
{ name: '吃饭', completed: false },
{ name: '睡觉', completed: true },
{ name: '打豆豆', completed: true },
];
//监听在输入框中按下回车键的事件
document.querySelector('.input-todo')!.addEventListener('keyup', function (e: Event) {
const event = e as KeyboardEvent;
const target = event.target as HTMLInputElement;
if (!target.value?.trim()) {
return;
}
if (event.key === 'Enter') {
const name = target.value;
const item: TodoItem = { name, completed: false };
list.push(item);
render(list);
target.value = '';
}
});
//实现筛选功能
document.querySelectorAll('.filter-btn').forEach((el) => {
el.addEventListener('click', filterCompletedStatus);
});
function filterCompletedStatus(e: Event) {
const target = e.target as HTMLElement;
const completed = target.dataset.complete;
if (completed === 'all') {
render(list);
return;
}
const newList = list.filter((item) => item.completed === (completed === 'true'));
renderTodoList(newList);
}
document.querySelector('.btn-clear')!.addEventListener('click', () => {
list = [];
render(list);
});
//切换completed的状态
function onClickCompleteBtn(index: number) {
list[index].completed = !list[index].completed;
render(list);
}
//渲染数组
function render(list: TodoItem[]) {
UpdateActiveNum();
renderTodoList(list);
}
//统计筛选中未完成功能数量
function UpdateActiveNum() {
const completedNum = list.filter((item) => !item.completed).length;
document.querySelector('.active-num')!.innerHTML = completedNum.toString();
}
//实现删除功能
function deleteItem(index: number) {
list.splice(index, 1);
render(list);
}
//渲染html
function renderTodoList(list: TodoItem[]) {
let html = '';
list.forEach((item, index) => {
const itemClass = item.completed ? 'item-complete todo-item' : 'todo-item';
const spanClass = item.completed ? 'icon-complete icon-complete-active' : 'icon-complete';
html += `<li class="${itemClass}">
<span onclick="onClickCompleteBtn(${index})" class="${spanClass}"></span>
<span>${item.name}</span>
<button class="btn-complete">完成</button>
<button class="deleted" onclick="deleteItem(${index})">删除</button>
</li>`;
});
document.querySelector('.todo-list')!.innerHTML = html;
}
```
## 运行项目
按下快捷键`Ctrl + ~`,打开终端,输入以下命令,运行项目
```
npm run dev
```
![运行效果](./result.png)
-32
View File
@@ -1,32 +0,0 @@
---
sidebar_position: 1
---
# 引言
写这个的想法源自于,最开始学习编程时,无法入门的痛苦。
入门一个职业,不是几天就可以做到的。但也不是的几个月的培训那么长。
软件工程更多讲究实践,而不是理论,所以希望读者能够实践多于阅读,如果某些章节实践过,可以直接跳过去。
我希望可以通过十几篇文章,让任何有兴趣的人入门前端工程师这个职业。
## 路线图
文章方面,希望一天可以产出一篇文章,通过两个星期。让入门变成简单的事情。
网站建设方面,准备采用 docusaurus 框架,架设一个文档网站。
需要更新的部分
1. 创建 vite vanilla-js 工程。
- 单独链接到快速创建命令篇。
2. 按步引入 react 包。
3. 快速创建命令,与执行效果。
4. 工具篇,添加 vscode git graph 插件的介绍
5. 高级篇
1. 纯函数、副作用。
2. 数据流,系统行为,数据副本(数据孤岛)。
6. 快速开始 -> 简单服务 补充 npx 命令相关。链接到工具篇
-7
View File
@@ -1,7 +0,0 @@
{
"label": "操作指南",
"position": 4,
"link": {
"type": "generated-index"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

-8
View File
@@ -1,8 +0,0 @@
{
"label": "docker工具",
"position": 7,
"link": {
"type": "generated-index"
}
}
-48
View File
@@ -1,48 +0,0 @@
---
sidebar_position: 1
---
# docker的安装与验证
docker是一种开源平台,用于开发、部署和运行应用程序。
## 先决条件
1. 确保您的系统是windows专业版
2. 已安装了wsl2
>**提示**
如果没有安装wsl2,可以参考[安装wsl文档](https://learn.microsoft.com/zh-cn/windows/wsl/install)
## docker的安装
### 1. 开启windows功能
通过控制面板,开启Hyper-v和适用于windows子系统功能
![控制面板](./1.png)
![启动windows功能](./2.png)
### 2. 下载并安装docker
下载docker最安全的路径就是去官网,安装时要注意勾选`wsl`选项,安装成功后跳过登录docker Hub账号
```
https://docs.docker.com/desktop/install/windows-install/
```
## 配置Docker镜像
安装docker后,进入docker,开始配置镜像
![设置页面](./6.png)
![Docker Engine](./7.png)
配置镜像添加以下内容
```
"registry-mirrors":["https://docker.m.daocloud.io","https://docker.1panel.live"]
```
## 验证Docker
运行以下命令,测试Docker是否正确安装并运行
```
docker run hello-world
```
当输出`Hello from Docker`命令时,表明Docker安装正确
![验证Docker](./8.png)
-64
View File
@@ -1,64 +0,0 @@
---
sidebar_position: 1
---
# Docker启动数据库
使用Docker启动PostgreSQL数据库
## 先决条件
1. 已安装Docker
2. 以wsl为开发环境
## 拉取 PostgreSQL 镜像
在wsl中,运行以下命令来拉取 `PostgreSQL` 镜像:
```
sudo docker pull postgres
```
## 创建文件并启动容器
### 1. 创建`docker-compose.yml`文件
运行以下命令,创建`docker-compose.yml`文件
```
touch docker-compose.yml
```
### 2. 编写文件
在`docker-compose.yml`文件中,写入以下内容:
```
version: '3.9'
services:
db:
image: postgres
restart: always
shm_size: 128mb
environment:
POSTGRES_PASSWORD: example
ports:
- "5432:5432"
adminer:
image: adminer
restart: always
ports:
- 7897:8080
```
### 3. 启动`PostgreSQL`数据库
运行以下命令启动`PostgreSQL`数据库:
```
docker-compose up --build
```
### 4. 验证启动
运行以下命令`ps`,当STATUS出现`up`的时候,容器就表示启动成功
```
docker ps
```
![运行容器](./5.png)
### 5. 连接到PostgreSQL数据库
运行以下命令,连接到PostgreSQL数据库:
```
docker exec -it my-postgres psql -U postgres
```
-7
View File
@@ -1,7 +0,0 @@
{
"label": "Prisma工具",
"position": 10,
"link": {
"type": "generated-index"
}
}
-85
View File
@@ -1,85 +0,0 @@
---
sidebar_position: 1
---
# Next.js + Prisma + Docker构建全栈
通过使用Next.js、Prisma和Docker来构建一个全栈应用。
## 先决条件
1. 已安装Node.js 18+
2. Prisma Postgres数据库
3. Next.js项目
4. 已安装Docker
5. 确认已启动数据库
>**提示**
如果不知道怎么启动数据库,可以参考使用 [Docker启动数据库](https://github.com/idealjs/full-stack-tutorial/blob/main/docs/docker/start.md)文档
## 项目初始化
- 打开Next.js项目
### 1. 安装并初始化Prisma
我们需要安装Prisma客户端,运行以下代码
```
npm install prisma --save-dev
```
然后,项目初始化Prisma,运行以下命令:`init`
```
npx prisma init
```
这时会出现新目录,里面包含`schema.prisma`文件
### 2.定义表结构
#### 2.1 编辑`schema.prisma`文件
在`prisma/schema.prisma`文件中定义数据库表结构,添加以下内容:
```
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
```
#### 2.2 配置`.env`文件
打开`.env`文件,配置PostgreSQL数据库连接字符串。例如
```
DATABASE_URL="postgresql://postgres:example@localhost:5432/postgres"
```
### 3. 数据库migration
配置完后,可以使用以下命令将架构应用到数据库中:`prisma migrate dev`
```
npx prisma migrate dev --name init
```
### 4. 使用Prisma Studio验证数据
#### 4.1 启动Prisma Studio
运行以下命令启动`Prisma Studio`:
```
npx prisma studio
```
#### 4.2 验证数据
在`Prisma Studio`中,可以查看`User`表的数据,通过添加、编辑或修改记录,验证表是否正确
![添加记录](./verify1.png)
![添加成功](./verify2.png)
### 5. 在Next.js中使用Prisma
#### 5.1 设置Prisma客户端
运行以下命令,创建一个新目录并在其添加一个新文件`lib/prisma.ts`
```
mkdir -p lib && touch lib/prisma.ts
```
在`lib/prisma.ts`文件中添加以下代码:
```
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const globalForPrisma = global as unknown as { prisma: typeof prisma }
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
export default prisma
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

-7
View File
@@ -1,7 +0,0 @@
{
"label": "参考资料",
"position":5,
"link": {
"type": "generated-index"
}
}
-7
View File
@@ -1,7 +0,0 @@
{
"label": "vscode插件异常",
"position": 1,
"link": {
"type": "generated-index"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

-39
View File
@@ -1,39 +0,0 @@
---
sidebar_position: 1
---
# 如何处理vscode安装插件异常
让我们通过以下步骤来解决插件安装失败
## 1. 检查网络是否异常
在浏览器中输入以下网址,看是否能访问,若能则不存在网络问题
```
https://marketplace.visualstudio.com
```
如果一切正常,您应该在`https://marketplace.visualstudio.com`有一个Extensions for Visual Studio Code的页面。
![vscode扩展页面](./marketplace.png)
## 2. 防火墙阻止
当我们第一次启动调试功能的时候,正常情况vscode会弹出防火墙阻止的界面
![防火墙](./code.png)
## 3. 设置代理
![设置图片](./setting.png)
![json图片](./json.png)
在`setting.json`中添加以下代理
```
"http.proxy": "http://127.0.0.1:7897",
"https.proxy": "http://127.0.0.1:7897",
"http.proxyAuthorization": null,
"http.proxyStrictSSL": false
```
## 4. clash配置
如果以上步骤都解决不了,需要查看以下`clash`的配置是否完成
## 5. 配置恢复
当需要安装的插件安装完成后,就可以上面的代理配置给注释了
Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

@@ -1,7 +0,0 @@
{
"label": "Alias命令",
"position": 2,
"link": {
"type": "generated-index"
}
}
-41
View File
@@ -1,41 +0,0 @@
---
sidebar_position: 1
---
# Linux alias
在Linux中,`alias`是一个用于创建命令别名的内置命令;通过`alias`,可以把常用的命令或命令组合设置为简短的别名,从而简化操作。
## 使用方法
### 1. 创建别名
运行以下命令:
```
alias 别名='命令'
```
例如:
```
alias ll='ls -l'
```
在命令行中输入`ll`就相当于输入`ls-l`
### 2. 永久别名
在`~/.bashrc`或者`~/.zshrc`文件中配置以下内容:
```
alias ll='ls -l'
```
### 3. 查看别名
在命令行中输入以下命令:
```
alias
```
### 4. 删除别名
在命令行中输入以下命令:
```
unalias 别名
```
例如:
```
unalias ll
```
这样ll别名就会被删除
-7
View File
@@ -1,7 +0,0 @@
{
"label": "工具",
"position": 5,
"link": {
"type": "generated-index"
}
}
-50
View File
@@ -1,50 +0,0 @@
# nvm
- Node.js是用于服务器端JavaScript运行,适合高性能、实时应用
- NVM用于管理多个Node.js版本,便于在不同项目间切换
## 先决条件
1. 确保安装了Ubuntu
## 安装NVM
### 1. 安装cURL
在wsl中,运行以下命令:`install`
```
sudo apt-get install curl
```
### 2. 安装nvm
通过curl安装nvm,运行以下命令
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
```
### 3. 配置环境变量
在`~/.bashrc`文件中配置以下内容:
```
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```
### 4. 验证nvm安装
若要验证安装,输入以下命令:`command -v nvm`;如果安装成功则返回nvm,如果收到"找不到命令"或无响应,关闭当前终端,重新打开,然后重试。
```
command -v nvm
```
### 5. 列出当前安装的Node版本
查看当前安装的版本号,输入以下命令:`nvm ls`
```
nvm ls
```
![nvm](./nvm.png)
### 6. 安装Node.js(LTS)版本
这里我选择安装当前稳定的LTS版本,安装输入以下命令:`install --lts`
```
nvm install --lts
```
### 7. 验证Node.js安装
查看当前安装的版本号,输入以下命令:`version`
```
node --version
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

-97
View File
@@ -1,97 +0,0 @@
---
sidebar_position: 1
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
# Git
git 是一个代码管理工具,可以追踪代码的提交记录。这是每个软件工程师必备工具,没有之一。
## 安装
工欲善其事,必先利其器。
<Tabs
defaultValue="win"
values={[
{ label: "win", value: "win" },
{ label: "ubuntu", value: "ubuntu" },
{ label: "mac", value: "mac" },
]}
>
<TabItem value="win">
下载地址 https://git-scm.com/
</TabItem>
<TabItem value="ubuntu">
大部分linux系统都自带git,打开控制台输入 git --version 查看 git 版本
</TabItem>
<TabItem value="mac">
mac系统自带git,打开控制台输入 git --version 查看 git 版本
</TabItem>
</Tabs>
## 使用
通常一个项目会对应一个 git 仓库,每次提交代码都会记录到 git 仓库中,这样就可以追踪代码的提交记录。
用图形化的工具来看的话,会呈现出如下图
![预览效果](./post-1-1.png)
### 克隆
克隆可以理解为将代码仓库复制了一份。
以此代码仓库为例,实际操作一下
```
git clone https://github.com/idealjs/full-stack-tutorial.git
```
后面的地址我们可以在 github 上看到,但是需要选用 https 的地址。
因为 ssh 地址需要做一些配置,所以先用 https 的地址克隆。
被克隆的仓库,我们通常叫他 **远程仓库**。或者源仓库。
![预览效果](./post-1-2.png)
### 拉取代码
刚克隆下的代码可能是最新的,但是过一段时间如果有人推送了新的提交到远程仓库,那么本地仓库如何同步远程仓库呢。
输入如下命令
```
git pull
```
### 推送代码
修改后的代码,想要共享给其他人,要如何做?
在 git 中,可以推送的东西只有修改记录。
而修改记录是不会因为文件被更改,就自动生成的,我们需要通过 git 工具把文件修改记录下来。
用如下命令把所有的修改都记录下。
```
git add .
```
然后提交到本地仓库
```
git commit -m "test"
```
最后把新的提交记录推送到远程仓库
```
git push
```
-7
View File
@@ -1,7 +0,0 @@
{
"label": "Web基础",
"position": 2,
"link": {
"type": "generated-index"
}
}
-7
View File
@@ -1,7 +0,0 @@
{
"label": "垃圾桶",
"position": 5,
"link": {
"type": "generated-index"
}
}
-32
View File
@@ -1,32 +0,0 @@
---
sidebar_position: 10
---
# React 入门
学完了 1+1,我们可以开始学习微积分了。(🐶 保命)
## 安装 Node 环境
参考上一章
- [传送门](https://idealjs.github.io/full-stack-tutorial/docs/post-8#%E6%9C%AC%E5%9C%B0%E6%9E%84%E5%BB%BA%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA)
## 创建一个 React 工程
我们使用 create react app 手脚架快速创建工程,其中包含大量的工具,但是没有必要每个都了解。
1. 找一个空的文件夹,打开控制台(按住 shift,右键打开控制台),输入如下命令。
```
npx create-react-app my-app
```
视网络状况,可能需要 30s - 1min ,如果过久的话,建议不要等了。
2. 进入到项目文件夹中,启动项目
```
cd my-app
npm start
```
-36
View File
@@ -1,36 +0,0 @@
---
sidebar_position: 2
---
# 信息时代
信息时代有很多获取信息的方式。
通过网页,或者特定的软件,或者其他的方式(非人类的获取方式比如:爬虫)。
网页需要通过一个特定软件才能打开(浏览器),之后人与浏览器交互,浏览器将信息传递给用户。
得益于浏览器跨平台的特性, 工程师们可以实现出只要一处编写,即可处处显示的软件 —— 是软件工程师们在影响世界 —— 这也是为什么信息时代是从网页开始的
## 网页的本质
网页本质是一个文档,文件,一段描述,一段文字。它被记录下来,由浏览器解析,并表达。
有点像是 DNA 是人的遗传信息,蛋白质是表达。 —— 最初的网页没有办法交互,只能显示字。(连颜色都没有,和蛋白质比起来弱爆了)
描述网页的语言不断更新,浏览器也不断的由工程师们更新。
目前使用最多的描述网页的语言是 HTML5
它看起来像是下面的代码块(实际还要复杂点)
```
<div>
我是一块
<div>
我是里面的一块
</div>
</div>
```
所以学会 HTML5 的规则,你就可以让浏览器写出具有简单排版的文字。
-57
View File
@@ -1,57 +0,0 @@
---
sidebar_position: 3
---
# 现代的网页
现代的网页并不复杂 —— 不只是文字 —— 有漂亮的外观,可以响应用户的操作。
## 漂亮的外观(CSS3)
组成一个漂亮的外观,首先需要骨架 —— HTML5,然后是化妆 —— CSS3
HTML5 中有一些默认的规则,可以让文字变得有层级结构,像是 Word 中的标题,独占一行,并行显示。学会这些规则,就可以进行简单的排版了。
CSS3 像是 Word 样式。颜色,背景颜色,行间距。学会 CSS3 的规则,不仅可以让排版更炫酷,还可以做动画效果,以及各种特殊的交互效果。
> 学会 HTML5 + CSS 可以不用 Word 了呢。—— 只是编辑体验有点糟糕。所以我还是喜欢用 Markdown 编辑文档,还可以使用 HTML 增强
## 有趣的灵魂(JS)
有趣的灵魂应该是 200 多斤吧。—— 我是说我自己。
网页的作用不仅仅是展示,也会响应用户的操作。也可以根据不同的用户给出不同的响应 —— 动态网页。不能区分用户给出不同反应的,叫做静态网页
响应用户的操作,则需要软件工程师编写一些逻辑,编写这个逻辑的语言,叫做 JavaScript(简称 JS)。
### JS 在网页中如何运行
回到代码的本质,其实是在规则下描述一段事情。
浏览器中有一个用于解释执行 JS 的引擎。
在浏览器打开网页时,把各种 JS 脚本(文件形式的,或者文字形式的)丢给 JS 引擎,由引擎解释执行。
下面这个代码片段就是一个 Hello World
```
<script>
function sayHello() {
alert("Hello World");
}
</script>
<button onClick="sayHello()">点击<button>
```
`<script></script>` 标签中的代码,就是 JS 代码。它定义了一个 sayHello 函数。
JS 引擎会记住这个函数。
`<button></button>` 是 H5 的一个标签,表示这里显示一个按钮。
`onClick="sayHello()"` 表示,这个按钮被点击时,会让 JS 引擎执行一段代码 —— `sayHello()`
## 下一节
下一节开始我们会完整的写一个 Hello World 网页。并开始 HTML5 CSS3 JS 的入门。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

-43
View File
@@ -1,43 +0,0 @@
---
sidebar_position: 4
---
# HTML5 Hello World
在学习一样新技术的时候,写一个 Hello World 是最简单的。
用最少的知识量,让程序完整的跑起来,就是 Hello World 的目的。
本篇的完整代码,可以在这里找到:
- [examples/post-4/hello.html](https://github.com/idealjs/full-stack-tutorial/blob/main/examples/post-4/hello.html)
## 查看这个网页
查看这个 Hello World 很简单,只需要把这个 hello.html 文件下载到计算机。然后用浏览器打开就可以了。
![预览效果](./post-4-1.png)
## 简单分析代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>Hello World</div>
</body>
</html>
```
通过上面的 Hello World 可以看出来一些 HTML5 的语法规则。
- 标签需要闭合 —— `<div/>` 或这样的 `<div></div>`
- 标签有独特的含义 —— `<xxx></xxx>`, `<div></div>` 是 HTML5 的块标签
具体的标签规则,可以参考 [HTML5 标签](http://www.w3chtml.com/html5/tag/)。(实际工作中,用到的种类没有列出来的这么多)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

-52
View File
@@ -1,52 +0,0 @@
---
sidebar_position: 5
---
# CSS3 快速入门
上一节,入门了 HTML5。了解了 HTML5 的 Hello World 后,我们可以开始学习 CSS3 了。
目标很简单,给 Hello World 加上一个颜色,并且再加一个背景色。
本篇的完整代码,可以在这里找到:
- [examples/post-5/hello.html](https://github.com/idealjs/full-stack-tutorial/blob/main/examples/post-5/hello.html)
## 查看这个网页
查看这个 Hello World 很简单,只需要把这个 hello.html 文件下载到计算机。然后用浏览器打开就可以了。
![预览效果](./post-5-1.png)
## 简单分析代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div style="color: red; background-color: green">hello world</div>
</body>
</html>
```
和上一节有区别的地方在于
```
<div style="color: red; background-color: green">hello world</div>
```
多了一组 style 属性,`style="color: red; background-color: green"`
其中的 `color` `bacogound-color` 是 CSS3 的属性,`red` `green` 值。并且需要用 `;` 分隔。
可以参考下图片
![预览效果](./post-5-2.png)
这里我们只展示了 CSS3 的一种写法。未来为大家介绍更多的写法。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

-63
View File
@@ -1,63 +0,0 @@
---
sidebar_position: 6
---
# JS Hello World
继续学习 Hello World。
Web 由 HTML5 + CSS3 + JS 构成。本节将介绍 JS 的 Hello World。
> 用最少的知识量,让程序完整的跑起来,就是 Hello World 的目的。
本篇的完整代码,可以在这里找到:
- [examples/post-6/hello.html](https://github.com/idealjs/full-stack-tutorial/blob/main/examples/post-6/hello.html)
## 查看这个网页
查看这个 Hello World 很简单,只需要把这个 hello.html 文件下载到计算机。然后用浏览器打开就可以了。
![预览效果](./post-6-1.png)
## 简单分析代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script>
window.onload = () => {
alert("hello world");
};
</script>
</head>
<body></body>
</html>
```
我们需要关注的是如下代码块,其余部分是 HTML5 的标签,想了解的话,可以查看[HTML5 Hello World](https://idealjs.github.io/full-stack-tutorial/docs/post-4)。
```html
<script>
window.onload = () => {
alert("hello world");
};
</script>
```
形式上,被 `<script></script>` 包裹住的内容就是 JS 脚本。
这个脚本会在浏览器解析到这个标签时执行。
- `window.onload = xxx` 是在做一个赋值操作。
将一个函数赋值给 `onload` 属性。而浏览器在加载`hello.html` 文档结束时,会运行 `onload` 函数。
- `() => { alert("hello world"); }` 称作匿名的箭头函数,具体可以查阅 JS 文档。
- `alert("hello world");` 是 JS 调用了浏览器提供的函数 `alert` 其中参数,我们填入了 `"hello world"` 字符串
-19
View File
@@ -1,19 +0,0 @@
---
sidebar_position: 7
---
# 模块和库
软件工程领域存在大量的模块和库,目的是为了更方便的维护软件。
在前端领域中,经过多年的实践,得出了 —— 构建的实践方式。
构建即,编写时采用 A 的方式,经过构建后得到 B 的产物。
前端的构建后产物依旧是 HTML + CSS + JS。
而编写时的方式有很多,比如比较流行的 Webpack(构建+打包)+ Typescript (JS 的超集)+ React/Vue
React/Vue 的组成比较复杂。也正是这些复杂的部分,推进了这些库的诞生。
用一句话来概括,当你需要一些可以减少开发量,减少维护难度的库时,可以采用 React/Vue
Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

-77
View File
@@ -1,77 +0,0 @@
---
sidebar_position: 8
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
# Node 入门
在继续学习前端的库之前,我们需要打断一下。
我们需要一些补充知识做我们的手脚架。
前文提到过,现代化的前端工程通过构建的方式,得到我们需要的产物。
而构建怎么执行,执行在哪里也是一个复杂的问题。
## 构建如何执行
- 语言语法转换
如:typescript 转换为 javascript。高级语言特性转换为兼容语句。
- 资源打包
如:图片,样式,打包成文件资源。
## 构建的执行位置
- 人工执行
简单的单机部署网站,我们可以使用人工部署的方式。
任选一台机器,进行构建,然后将构建产物复制到提供对外服务的服务器上。
- 自动执行
由特殊的构建软件监听,然后在配置好机器/容器中构建。
两种方案都需要一个机器,或者环境来构建。
接下来简单介绍本地环境的搭建
## 本地构建环境搭建
- 安装 Node
node 的版本很多,入门建议使用 官网的 LTS 版本。
![node 官网截图](./post-8-1.png)
<Tabs
defaultValue="win"
values={[
{ label: "win", value: "win" },
{ label: "linux", value: "linux" },
{ label: "mac", value: "mac" },
]}
>
<TabItem value="win">
windows 就直接安装吧。(没错,下载,安装)。装完记得重启电脑,环境变量在重启后才生效。
https://nodejs.org/en/
</TabItem>
<TabItem value="linux">
使用 nvm 安装和管理不同版本的 node
https://github.com/nvm-sh/nvm#install--update-script
</TabItem>
<TabItem value="mac">
使用 nvm 安装和管理不同版本的 node
https://github.com/nvm-sh/nvm#install--update-script
</TabItem>
</Tabs>
-80
View File
@@ -1,80 +0,0 @@
---
sidebar_position: 9
---
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
# Hello Node JS
假如安装好了 Node,如何验证安装好了?或者我怎么使用它?
## 验证是否安装成功
打开一个控制台
<Tabs
defaultValue="win"
values={[
{ label: "win", value: "win" },
{ label: "ubuntu", value: "ubuntu" },
{ label: "mac", value: "mac" },
]}
>
<TabItem value="win">
在开始菜单上右键,点击windows 终端(管理员)
</TabItem>
<TabItem value="ubuntu">
Ctrl+Alt+T
</TabItem>
<TabItem value="mac">
找到terminal app,然后打开。
</TabItem>
</Tabs>
输入
```
node -v
```
然后你会看到你安装的 node 版本。
例如,我的版本
```
v14.18.0
```
## 使用
> 用最少的知识量,让程序完整的跑起来,就是 Hello World 的目的。
本篇的完整代码,可以在这里找到:
- [examples/post-9/hello.js](https://github.com/idealjs/full-stack-tutorial/blob/main/examples/post-9/hello.js)
在有 hello.js 的文件夹下打开控制台(在文件夹下按住 shift 鼠标右击),并且输入
```sh
node hello.js
```
如果碰到了如下错误,那么可能是当前文件夹下没有 hello.js 这个文件。
```
internal/modules/cjs/loader.js:905
throw err;
^
Error: Cannot find module 'xxx/xxx/hello.js'
```
正常运行的话,会显示如下
```
hello world
```
-7
View File
@@ -1,7 +0,0 @@
{
"label": "快速开始 React",
"position": 3,
"link": {
"type": "generated-index"
}
}
-21
View File
@@ -1,21 +0,0 @@
---
sidebar_position: 1
---
# 创建工程
使用 [Create React App](https://create-react-app.dev/docs/getting-started) 脚手架工具
创建工程
继续之前使用过的 hello_world 项目,输入命令
```
npx create-react-app my-app
```
> 受网络影响,这一步可能会等待较长时间。
![输入命令](./enter_command.png)
![预览图](./created_react.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

-13
View File
@@ -1,13 +0,0 @@
---
sidebar_position: 3
---
# 启动流程
React 的 App.js 和之前 hello_world 中的 index.html 有很大的不同
![不同](./difference.png)
这是因为 React 会把 App.js 作为组件挂载到页面视图上
![挂载](./what_happend.png)
-19
View File
@@ -1,19 +0,0 @@
---
sidebar_position: 2
---
# 启动项目
输入指令,切换到工程目录
```
cd my-app
```
输入指令,启动工程
```
npm start
```
![启动成功](./started_react.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

-12
View File
@@ -1,12 +0,0 @@
---
sidebar_position: 4
---
# 快速实践
项目
- 待办列表(Todo List)
## 待办列表
待办列表是一个经典的入门 App,通过待办列表可以学到 React 所提供的基础函数
Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

-7
View File
@@ -1,7 +0,0 @@
{
"label": "快速开始",
"position": 2,
"link": {
"type": "generated-index"
}
}
-26
View File
@@ -1,26 +0,0 @@
---
sidebar_position: 2
---
# 第一个页面(hello world)
```html title="hello-world/index.html"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>hello world</div>
</body>
</html>
```
![预览效果](./open_hello_world.png)
将文件在浏览器中打开,你将会看到 `hello world` 字样
![预览效果](./hello_world.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

-17
View File
@@ -1,17 +0,0 @@
---
sidebar_position: 2
---
# 简单的服务
打开控制台
![打开控制台](./open_terminal.png)
输入命令
```
npx http-server
```
![输入命令](./start_http_server.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

-13
View File
@@ -1,13 +0,0 @@
---
sidebar_position: 1
---
# 使用 VSCode
新建文件夹命名为 hello-world
![打开文件夹](./open_folder.png)
![打开后](./opened.png)
![新建文件](./new_file.png)
-7
View File
@@ -1,7 +0,0 @@
{
"label": "安装工具-win",
"position": 1,
"link": {
"type": "generated-index"
}
}
-17
View File
@@ -1,17 +0,0 @@
---
sidebar_position: 2
---
# 安装 nodejs
访问网站 https://nodejs.org/zh-cn/
点击下载长期维护版 并且安装
全默认选项安装
> 安装完成重启电脑,使环境变量生效。
## 为什么需要 nodejs
1. nodejs 可以用来启动简单的 http 服务
2. nodejs 可以用来构建模块化的工程
-13
View File
@@ -1,13 +0,0 @@
---
sidebar_position: 1
---
# 安装 vscode 编辑器
访问网站 https://code.visualstudio.com/
点击下载并且安装
## 下载速度慢
参考 https://zhuanlan.zhihu.com/p/112215618
-7
View File
@@ -1,7 +0,0 @@
{
"label": "更多",
"position": 8,
"link": {
"type": "generated-index"
}
}
-3
View File
@@ -1,3 +0,0 @@
# nodejs 与前端的关系
## nodejs 如何构建项目
-7
View File
@@ -1,7 +0,0 @@
{
"label": "更多示例",
"position": 3,
"link": {
"type": "generated-index"
}
}
View File
Whitespace-only changes.