普通视图
Python迭代器与生成器全解析:让你的代码高效又优雅!
WebSocket断链后确保渲染内容时效性的完整解决方案:
前端实现客户端扫码登录的全流程解析及实战案例
组件扩展接口设计秘籍大公开:以Select组件为例
🚀🚀🚀 AI 助手好写,太好写了,分分钟写出来,不用一周,三分钟!
耗时十分钟,做了一个 uniapp 灵感泡泡机
JavaScript 垃圾回收与内存泄漏
react中hooks-你真的会用useState吗?
npm 【workspace】【npm link】【安装本地包】【类库开发调试】
前言
当我们在开发类库时,往往会在实际项目中引入开发中的类库,来调试实际使用的效果。并且最好是需要类库改变后,能够自动、实时的在项目中反馈。
npm有三种方法实现不发布npm包,就在本地像npm i
安装一样去使用它,如下:
特性 | 工作空间(Workspaces) | 本地路径依赖 (file: ) |
npm link |
---|---|---|---|
依赖管理方式 | 单仓库多包(monorepo) | 跨项目文件引用 | 全局符号链接 |
版本控制 | 由根 package.json 统一管理 |
各自维护版本,可能冲突 | 忽略版本,直接引用源码 |
修改传播 | 实时生效(无需重新安装) | 实时生效 | 实时生效 |
依赖结构 | 扁平化(共享根 node_modules ) |
嵌套结构(可能导致重复安装) | 全局链接,可能与其他项目冲突 |
生产环境兼容性 | 完全兼容(发布独立包) | 需替换为 npm 包版本 | 不可用(必须替换为 npm 包) |
适用场景 | 大型项目内部模块协作 | 临时引用本地包 | 频繁开发的本地包 |
下面我们就来分别介绍它们的使用
1.前置条件
首先我们建立一个项目目录,后面的案例都按照这个目录操作
├─ app/ # app项目
│ ├─ index.js
│ └─ package.json
├─ lib1/ # sub项目
│ ├─ index.js
│ └─ package.json
1.本地路径依赖 and
npm link
本地依赖开发非常简单,直接将依赖指向本地地址即可。它其实最终也是执行的npm link
,相对于"scripts"
项的脚本一样
// app/package.json
{
"dependencies":{
"lib-name1":"../lib1",// lib目录必须是一个npm项目
}
}
执行npm i
,npm就会自动把./lib目录链接到app/node_modules
下,然后像普通模块一样引入即可
// app/index.js
import m from "lib-name1";
然后我们看看npm link
的使用方式,直接在app/目录的命令行中执行
app> npm link ../lib1; //在app/node_modules中的文件名由../lib1/package.json中的name项决定
你可以查看app/node_modules目录,可以看到本地路径依赖
和npm link
最终都是在其内部生成了一个目录链接符
2.workspace
建立一个新的目录结构
├─ app/ # app项目
| ├─ index.js
| ├─ package.json
| |
| ├─ pack1/
| | ├─ index.js
| | └─ package.json #s 引入lib1
| |
| └─ packages/
| └─ pack2/
| ├─ index.js
| └─ package.json #s 引入lib2
│
├─ pack0/
├─ index.js
└─ package.json #s 引入lib0
然后配置workspace
// app/package.json
{
"workspace":[
"../pack0",
"./pack1",
"./packages/*", // 引入./packages/目录下所有项目
]
}
workspace最终也是建立一个"npm link"目录链接,但是它与npm link
和本地路径依赖
不一样的是,workspace如果配置的是在当前根目录
内的项目作为依赖,那么所有的依赖都是统一安装到根目录
的node_module
下进行复用,即便你是在依赖项
中执行npm i
也不会安装到workspace
项目中的node_module
如果配置的workspace
项目,根目录
外,则无法复用。依赖项会安装到workspace
项目的node_modules中。
在上面的目录结构执行完npm i
之后,包安装位置结果如下
|-app/node_modules
| |- lib1
| |- lib2
|-pack0/node_modules
|- lib0
3.结论
不论是库还是单体项目,都推荐使用workspace进行包管理!
Edge Runtime 与 Serverless Runtime
一、基本定义
类型 | 定义 |
---|---|
Serverless Runtime | 指在云服务(如 AWS Lambda)上运行的无状态函数,按请求触发,运行在**中心化服务器(Region)**中。 |
Edge Runtime | 指代码运行在**CDN 边缘节点(Edge Node)**的沙箱环境中,靠近用户,延迟更低,使用 Web 标准 API 执行。 |
二、底层运行原理对比
特性 | Serverless Runtime | Edge Runtime |
---|---|---|
运行环境 | Node.js、支持 CommonJS/ESM | 基于 V8 引擎(非 Node.js),无 Node 核心模块 |
执行位置 | 云 Region 中心服务器(如 AWS us-east-1) | 离用户最近的 CDN 边缘节点(如东京、新加坡) |
触发方式 | 按请求启动(有冷启动) | 按请求启动(极低冷启动) |
资源限制 | 内存大、运行时间长 | 内存小、执行时间短 |
支持 API | Node.js API 全支持,如 fs 、http 、crypto
|
仅支持 Web 标准 API,如 fetch 、Request 、Response
|
文件系统访问 | ✅ 支持 | ❌ 不支持 |
数据库连接 | ✅ 支持直连 MySQL/MongoDB 等 | ⚠️ 不推荐(无 TCP 支持、无连接池) |
三、启动与响应性能对比
对比项 | Serverless | Edge |
---|---|---|
启动时间 | 50ms ~ 800ms(冷启动) | <10ms(近似无冷启动) |
运行时长限制 | 通常几分钟(如 AWS Lambda 最长 15 分钟) | 通常几秒(如 Cloudflare Worker 最多 30 秒) |
并发能力 | 支持高并发(自动扩展) | 支持极高并发(且无需冷启动) |
本地模拟支持 | ✅ 可用 next dev 本地模拟 |
⚠️ 本地模拟困难、需平台支持(如 Vercel CLI) |
四、应用场景对比
场景类型 | Serverless Runtime | Edge Runtime |
---|---|---|
SSR 页面渲染 | ✅ 推荐,支持数据库、缓存等复杂逻辑 | ⚠️ 不推荐,因不支持数据库直连 |
国际化重定向 | ✅ 可做,但慢 | ✅ 非常推荐,极快 |
登录鉴权 | ✅ 推荐 | ✅ 推荐(如 JWT 验证) |
A/B 实验 | ✅ 推荐 | ✅ 推荐(执行速度快) |
数据库操作 | ✅ 推荐 | ❌ 不推荐 |
静态资源预处理 | ❌ 无意义 | ✅ 可拦截 CDN 请求处理逻辑 |
CDN 边缘响应 API | ❌ 慢 | ✅ 最佳选择 |
页面 Layout Server Components(App Router) | ✅ 支持 | ✅ 支持,需 export const runtime = 'edge'
|
五、Next.js 中的使用方式
1. Serverless(默认)
适用于任何 API 路由、SSR 页面:
// 默认 Node.js Runtime
export async function GET(req: Request) {
// 可以连接数据库、使用 fs、进行 SSR 等
}
2. Edge Runtime
在 middleware.ts
、API 路由或 page.tsx
中启用:
export const runtime = 'edge';
export async function GET() {
return new Response('Hello from Edge!');
}
六、与平台的关系
平台 | Serverless Runtime | Edge Runtime |
---|---|---|
Vercel | ✅ 默认支持 | ✅ 强力支持(推荐平台) |
Cloudflare Workers | ❌ 不支持 | ✅ 支持(原生) |
Netlify Functions | ✅ 支持 | ✅ 支持(部分) |
AWS Lambda | ✅ 支持 | ✅ 需使用 Lambda@Edge |
阿里云函数计算 | ✅ 支持 | ⚠️ 支持有限 |
自建 Node.js 服务 | ✅ 支持 | ❌ 不支持 Edge |
七、优缺点总结
✅ Serverless Runtime 优势
-
支持数据库连接、文件操作
-
更强的计算能力和执行时长
-
更灵活,调试方便
❌ Serverless Runtime 缺点
- 冷启动慢(尤其是首次)
- 距离用户远,延迟高
- 无法处理 CDN 级别请求
✅ Edge Runtime 优势
- 毫秒级冷启动
- 离用户更近,延迟极低
- 非常适合轻量请求、前置逻辑、边缘缓存判断
❌ Edge Runtime 缺点
- 无法访问 Node 核心模块
- 无法直连数据库
- 无文件系统、不适合重计算任务
总结建议
场景 | 推荐运行时 |
---|---|
页面 SSR + 数据库渲染 | ✅ Serverless |
登录状态校验 / token 验证 | ✅ Edge |
CDN 边缘路由拦截(如国际化) | ✅ Edge |
复杂 API 接口处理 | ✅ Serverless |
页面 Layout 的快速响应组件 | ✅ Edge(App Router) |
实战例子
登录校验(middleware.ts + Edge)
export function middleware(request) {
const token = request.cookies.get('token')
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
国际化跳转
export function middleware(req) {
const lang = req.headers.get('accept-language')
const url = req.nextUrl
if (!url.pathname.startsWith('/zh')) {
url.pathname = '/zh' + url.pathname
return NextResponse.redirect(url)
}
}
突破浏览器最小字号限制:前端超小字号实现技巧
一. 使用SVG文本呈现文字
<svg width="100%" height="20">
<text x="50%" y="10" font-size="7" font-family='SourceHanSansCN-bold' fill="#a62f1c" font-weight="600" text-anchor="middle">{{ gift.txt }}</text>
</svg>
- 使用
x="50%"
和text-anchor="middle"
实现文字水平居中
二. 使用 transform: scale()缩小文字
.txt {
font-size: 12px;
transform: scale(0.8);
}
- font-size的大小取决于浏览器限制的最小字体
AI回答:
突破浏览器最小字号限制的方法主要有以下几种:
- 使用CSS的
transform: scale()
属性:通过将字体大小设置为一个较大的值,然后使用transform: scale()
属性进行缩放,可以实现小于12px的字体效果。例如,将字体大小设置为20px,然后通过0.5倍缩放来实现10px的字体效果。这种方法适用于块级元素和行内块元素,但需要注意缩放属性会影响元素的布局和样式12。 - 使用SVG文本:对于需要在图标或徽标中显示非常小的文本,可以考虑使用SVG(可缩放矢量图形)来呈现文本。SVG文本不受浏览器最小字体大小的限制,可以直接设置所需的字体大小4。
- 修改Chrome浏览器设置:可以通过调整Chrome浏览器的设置来禁用最小字体大小限制。在Chrome地址栏输入
chrome://settings/
,然后搜索“字体”或“外观”,尝试调整相关设置。但这种方法可能因Chrome版本和操作系统而异,且不保证所有用户都会进行相同的设置45。
这些方法的优缺点如下:
-
CSS缩放:
- 优点:代码简洁,文本可选中,兼容性好。
- 缺点:影响布局和样式,大量文本缩放会影响渲染性能。
-
SVG文本:
- 优点:不受浏览器最小字体大小限制,适合特定场景。
- 缺点:需要使用SVG,不适合所有文本内容。
-
修改浏览器设置:
- 优点:操作简单,直接。
- 缺点:只对当前用户的浏览器生效,不适用于所有用户45。
zoom
CSS 中的 zoom
属性用于缩放元素的大小,包括其内容、边框和内边距。它类似于 transform: scale()
,但有一些关键区别。以下是关于 zoom
的详细说明和使用方法。
1.基本用法
zoom
属性接受一个数值或百分比,表示元素的缩放比例。
.example {
zoom: 1.5; /* 放大到 150% */
}css
-
zoom: 1
:默认大小(无缩放)。 -
zoom: 0.5
:缩小到 50%。 -
zoom: 200%
:放大到 200%。
2.与 transform: scale()
的区别
特性 | zoom |
transform: scale() |
---|---|---|
兼容性 | 仅部分浏览器支持(如 IE、Edge) | 所有现代浏览器支持 |
布局影响 | 会重新计算布局,影响其他元素 | 不会影响布局,仅视觉缩放 |
性能 | 性能较差 | 性能较好 |
缩放中心 | 默认从左上角缩放 | 可以通过 transform-origin 设置中心点 |
3.使用 zoom
的场景
-
兼容旧版浏览器:如果需要支持 IE 或旧版 Edge,可以使用
zoom
。 -
简单缩放:如果不需要复杂的布局控制,
zoom
是一个简单的解决方案。
4.示例
放大元素
.zoom-in {
zoom: 1.5; /* 放大到 150% */
}css
缩小元素
.zoom-out {
zoom: 0.75; /* 缩小到 75% */
}css
结合百分比
.zoom-percent {
zoom: 200%; /* 放大到 200% */
}css
5.注意事项
-
兼容性问题:
-
zoom
不是标准属性,现代浏览器(如 Chrome、Firefox)不支持。 - 如果需要跨浏览器兼容,建议使用
transform: scale()
。
-
-
布局影响:
-
zoom
会重新计算元素的布局,可能导致页面其他元素的位置发生变化。
-
-
性能问题:
-
zoom
的性能较差,尤其是在复杂页面中。
-
6.替代方案:transform: scale()
如果不需要支持旧版浏览器,建议使用 transform: scale()
。
.example {
transform: scale(1.5); /* 放大到 150% */
transform-origin: 0 0; /* 设置缩放中心点 */
}css
-
transform-origin
:设置缩放的中心点,默认是元素中心。
7.结合 JavaScript 动态缩放
通过 JavaScript 动态设置 zoom
或 transform: scale()
。
<div id="box" style="width: 100px; height: 100px; background: red;"></div>
<button onclick="zoomIn()">放大</button>
<button onclick="zoomOut()">缩小</button>
<script>
const box = document.getElementById('box');
function zoomIn() {
box.style.zoom = (parseFloat(box.style.zoom) || 1) + 0.1;
}
function zoomOut() {
box.style.zoom = (parseFloat(box.style.zoom) || 1) - 0.1;
}
</script>html
8.响应式缩放
通过媒体查询实现响应式缩放。
@media (max-width: 600px) {
.responsive-zoom {
zoom: 0.8; /* 在小屏幕上缩小到 80% */
}
}css
总结
-
zoom
是一个简单的缩放属性,但兼容性和性能较差。 - 现代开发中,建议使用
transform: scale()
作为替代方案。 - 如果需要支持旧版浏览器(如 IE),可以结合
zoom
和transform: scale()
实现兼容性。