对于开发一直是属于一个什么都懂一点但是都不具体了解的一个水平,最近看到b站一个叫李勃老师的视频适用于AI时代的全栈教学做的很好,对于AI时代的开发者来说我个人认为是一个不可多得的好教程,用时短且能快速了解知识,并且不仅有视频也配备了对应的文字网站。https://xn--ygr25xpohxwz.com/zero-to-fullstack

学习之余我意识到一个问题,就是这样简单地看过知识之后自己都理解了,但是又很容易忘记,所以特地写了一个专门记录一些阅读时重点的笔记,以供后续翻阅。

2.3互联网是怎么工作的

访问一个网页的整个网络路径:

浏览器访问域名——DNS解析域名——找到IP并访问——访问方式HTTP/S(对应端口80/443)——对应服务器端口监听并返回文件(可用nginx)——浏览器渲染文件(前后端)

  • 其中DNS解析域名,找到IP并访问又有其自己的深层的计算机网络的协议;

  • 服务器监听端口和nginx又设计到具体的nginx配置;

这里简单带过一下nginx的知识,配置入口时nginx.conf

nginx启动的时候,只直接读 nginx.conf 这一个文件。其他你看到的所有目录(conf.d/sites-enabled/ 等等),都是 nginx.confinclude 指令”包含”进来的。

这个配置文件里面住要配置了一些全局指令,events块和http/s{}块:比如最外层的

worker_processes auto;
pid /run/nginx.pid;

分别代表:

  • worker_processes auto:开几个工作进程,auto 表示和 CPU 核数一致。
  • pid:进程 ID 写到哪个文件,给 systemctl 这类系统工具用。

重点是http块中的

include /etc/nginx/mime.types;
default_type application/octet-stream;


include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

这里说明了一些文件是怎么被读进来的,就是通过一个主模块然后逐步引入的。

到这里你应该能把整张图在脑子里拼起来:

nginx.conf  (Nginx 启动只读这一个)
├─ 顶层:user / worker / pid / error_log
├─ events { ... } 并发参数
└─ http { ... } HTTP 服务全配置
├─ include mime.types
├─ include conf.d/*.conf
└─ include sites-enabled/* ← 我们要改的网站配置就是从这里被串进来的

最后我们看一下最重要的最后两行,

include /etc/nginx/conf.d/*.conf;  
include /etc/nginx/sites-enabled/*; ← 当前"启用中"的网站配置和这个对应的,还有一个当前“写出来“的网络配置,他是site-available/

看一眼它的内容:

cat /etc/nginx/sites-enabled/default

文件里有很多以 # 开头的行,这是 Nginx 的注释(不会被执行)。如果只看真正生效的部分,结构是这样的:这里我把注释直接写到代码块中

//一个server块等于一个网站,如果有多个server块说明这个nginx同时可以配置多个网站。
server {
//该网站监听哪个端口,80是http标准端口,浏览器输入http://IP,默认连80。
//default_server表示如果没有其他server块匹配时默认是这个服务块
listen 80 default_server;
//同一件事的ipv6版本
listen [::]:80 default_server;

//去哪里找文件。举几个例子:
- 用户访问 http://你的IP/about.html → Nginx 去找 /var/www/html/about.html
- 用户访问 http://你的IP/css/main.css → Nginx 去找 /var/www/html/css/main.css
//这里也可以修改的,比如我们可以修改成我们自己项目的地址,
比如:/home/ubuntu/mag1code;
root /var/www/html;

//当访问文件夹时的默认页
index index.html index.htm index.nginx-debian.html;

//响应哪个域名,_是占位符,表示什么域名都接受。
server_name _;

//location /表示对所有路径都用这条规则
location / {
try_files $uri $uri/ =404;
}
}

4.1现代前端第一步-模块化

这之前已经把一个html文件分成了单独的css与js文件,分别在html中通过<link rel:"stylesheet" href:"path">以及<script scr:"path">来获得调用,其中这里的script的引用地址不止可以是本地的文件,也可以是线上的url。

ES:是javascript的官方标准

模块化:在模块化之前,如果想要引用js一般都是按顺序挨个引用

<script src="js/cards.js"></script>   <!-- cards 跑的时候 anime 还没加载 -->
<script src="https://cdn.jsdelivr.net/npm/animejs@4/lib/anime.iife.min.js"></script>
<script src="js/score.js"></script>
<script src="js/nav.js"></script>

但经常这样使用你就会发现一个问题就是,不仅有时候有顺序要求,因为你可能在前面的脚本引用了后面的函数,对于脚本语言来说是回报错的。其次一直这样使用有时候会引起全局命名的重复,万一项目庞大命名重复之后,会产生一些很难解决的报错,让你修bug都修得烦人。

因此在2015年的ES6标准出来之后,引入了模块化的思想,对于每个文件都需要主动的export和import其他文件才能使用,比如:

## 原来的写法
(function () {
anime.animate(".card", {
opacity: [0, 1],
translateY: [24, 0],
delay: anime.stagger(120), // 每张卡错开 120ms
duration: 700,
ease: "outBack", // 弹性落地
});
})();

## 后来的写法
import { animate, stagger } from "https://cdn.jsdelivr.net/npm/animejs@4/+esm";

export function initCardsAnim() {
animate(".card", {
opacity: [0, 1],
translateY: [24, 0],
delay: stagger(120), // 每张卡错开 120ms,自动排好节奏
duration: 700,
ease: "outBack", // 弹性收尾,落地像有重量
});
}

原来的写法需要在html中在该card.js的上面先引用https://cdn.jsdelivr.net/npm/animejs@4/+esm,才可以。下面的写法就不需要,在需要用到的js中引用就可以了。

最后在之前的四条语句合并成了一个main.js文件:

import { initNav } from "./nav.js";
import { initCardsAnim } from "./cards.js";
import { initScoreAnim } from "./score.js";

initNav();
initCardsAnim();
initScoreAnim();

然后在html中只需要一行<script type:"module" src:"js/main.js"。就可以了。

4.2 vite、npm于前端构建

Node.js 就是”让 JavaScript 跳出浏览器、在你电脑上直接运行”的运行环境。 这句话解了我好长一段时间对nodejs到底是什么的疑惑,加深了记忆。此外nodejs也附赠了一个东西就是npm,npm是对应项目的,每个项目运行npm init之后回生成一个package.json文件,这个文件会记录npm都做了什么,安装了哪些包。安装的包一般都在项目的node_module文件夹下面。

我们通过npm安装一下vite,vite就是可以好比一个**脚手架(今天又有了新理解,之前也用过一些脚手架,今天又加了一个理解,脚手架就是帮助你在干活阶段的时候把活干完的东西,但是最后交付不会成为成品的一部分)**一样的东西。

vite都可以帮助做了什么呢?

  • 他在开发阶段可以帮助起一个本地测试的服务器,用来查看预览效果,更改代码保存后即时更新前端
  • build:打包成上线版本,可以让多个js/css文件整合成一个,这样网络访问请求的时候解决了每次请求一大堆文件的问题。

一条要记住的规矩:源代码 ≠ 运行的代码,这个例子也很常见,经常我们很多时候开发都需要用到脚手架,帮助我们最后的构建部署什么的。

最后一个点,既然有了npm,就用他来管理依赖。回头看 cards.jsscore.js 顶上那一行:

import { animate, stagger } from "https://cdn.jsdelivr.net/npm/animejs@4/+esm";

这是 之前 留下的写法。它能跑,但有两点并不踏实:

  • 每次打开页面,都要联网去 jsdelivr 那台别人的服务器拉取 anime——一旦没网、或那个网址哪天失效,动画就会失灵;
  • 网址里的 @4 指”最新的 4.x”,哪天它小版本一更新,页面可能毫无征兆地改变行为

但是有了npm之后就不一样了,我们可以通过npm把这些库装到本地,并且还能锁定版本,只需要一条npm install animejs

4.3React登场

**为什么选React不是Vue?**这在国内是一个好问题,vue在国内确实流行,

React 和 Vue 都是前端框架,解决的是同一类问题:怎么用组件组织界面,怎么让数据变化时界面跟着变化。

他们只是更像不同的方言,做的是同一件事,只是写法和习惯不同。所以理解其中一个再去学习另一个会理解很快。

其次React的生态以及AI时代下的使用范围比Vue在全球范围内广很多。

框架是什么?其实就是管一套事的规则,React 是一个前端框架,它管的是 UI 组件 这一摊事。

后面我们讲后端时,还会遇到 Web 框架。那时框架管的就是另一摊事:请求怎么进来、路由怎么分发、接口怎么返回。

把框架理解成“规则”,而不是“魔法”,后面你看整个软件世界都会清楚很多。

React 这套规则的核心是:

把一块界面定义成一个组件。

安装React安装一个react很简单,也只需要通过npm install react react-dom

这两个包就是react的核心,但是只安装react还不够,你还需要让vite这个构造工具知道react并翻译他,所以还需要下载一个插件

npm install -D @vitejs/plugin-react下载之后也只是挂在了node_module下,想要启用还需要配置vite,在根目录新建

## vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
plugins: [react()],
});