为什么写这篇:2018 年 VSCode 已经超越 Sublime 成为前端编辑器霸主,Emmet 缩写让写 HTML 像写"补全指令"一样快。同年 Node.js 作者 Ryan Dahl 公开了 Deno——“一种更安全、更现代的 JS/TS 运行时”。本文是这两件事的速查手册。
适用读者:刚开始用 VSCode 写 HTML 的同学;对 Deno 好奇但没动手的 Node 开发者。
前置知识:会装 VSCode 扩展;知道 Node.js 是什么。
目录
- VSCode 写 HTML 的 5 个高效快捷键
- HTML5 骨架补全原理
- VSCode 必装前端扩展
- Deno 是什么
- Deno 安装与 REPL
- Deno 的 TypeScript 原生支持
- Deno vs Node:6 大差异
- Deno 的安全沙箱
- 示例:写一个 Deno HTTP Server
1. VSCode 写 HTML 的 5 个高效快捷键
VSCode 内置 Emmet——Tab 键触发缩写 → 展开为代码片段。
| 快捷输入 | 展开为 | 用途 |
|---|
! + Tab | HTML5 完整骨架 | 新建 HTML 文件第一行 |
html:5 + Tab | 同上 | 等价于 ! |
div*5 + Tab | 5 个 div | 批量创建同元素 |
ul>li*3 + Tab | ul 包 3 个 li | 嵌套批量 |
div.classname + Tab | <div class="classname"></div> | 带 class 的元素 |
Why ! 工作:VSCode 把 ! 映射到 html5.json 这个 Emmet snippet 文件——触发后插入 DOCTYPE、html、head、body 全部标签。
1
2
3
4
5
6
7
8
9
10
| <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
|
1.1 常用 Emmet 缩写速记
1
2
3
4
5
6
7
8
9
| 元素名 → <元素名></元素名>
元素#id → <元素 id="id"></元素>
元素.class → <元素 class="class"></元素>
元素[attr=val] → <元素 attr="val"></元素>
元素{文字} → <元素>文字</元素>
元素*数量 → 重复 N 次
父>子 → 嵌套
兄+弟 → 平级
()(群组) → 分组
|
实际案例:
1
| .container>ul.list>li.item*5>a[href="#"]{链接$}
|
展开:
1
2
3
4
5
6
7
8
9
| <div class="container">
<ul class="list">
<li class="item"><a href="#">链接1</a></li>
<li class="item"><a href="#">链接2</a></li>
<li class="item"><a href="#">链接3</a></li>
<li class="item"><a href="#">链接4</a></li>
<li class="item"><a href="#">链接5</a></li>
</ul>
</div>
|
2. HTML5 骨架补全原理
! 触发的是 VSCode 内置的 HTML language server + Emmet engine:
- 输入
! - 编辑器提示候选
- 按
Tab 接受 - Emmet 把
! 解析为 HTML5 模板,插入到光标位置
小贴士:可以在 文件 → 首选项 → 用户代码片段 → html.json 自定义模板,比如默认加 <meta name="author">、改 lang=“zh-CN” 等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| {
"html:zh": {
"prefix": "!zh",
"body": [
"<!DOCTYPE html>",
"<html lang=\"zh-CN\">",
"<head>",
" <meta charset=\"UTF-8\">",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
" <title>${1:文档标题}</title>",
"</head>",
"<body>",
" $0",
"</body>",
"</html>"
]
}
}
|
3. VSCode 必装前端扩展
| 类别 | 扩展 | 用途 |
|---|
| 核心 | ESLint | 代码检查(与项目内 .eslintrc 联动) |
| Prettier | 自动格式化 |
| EditorConfig for VS Code | 跨编辑器代码风格(缩进/EOL) |
| HTML/CSS | Live Server | 一键起本地 HTTP 服务器,文件改动自动刷新 |
| Auto Rename Tag | 改开始标签自动改结束标签 |
| CSS Peek | 从 HTML 跳到 CSS 定义 |
| JS/TS | JavaScript (ES6) code snippets | ES6 代码片段 |
| TypeScript Vue Plugin (Volar) | Vue 3 + TS 类型提示 |
| 框架 | Volar(Vue) / ES7+ React/Redux/React-Native snippets | 框架支持 |
| Git | GitLens | 行内 blame、commit 历史 |
| 工具 | Path Intellisense | 路径自动补全 |
| TODO Highlight | 高亮 TODO / FIXME |
| REST Client | 像 Postman 一样在 VSCode 里发 HTTP |
| vscode-icons | 文件夹/文件图标美化 |
轻量原则:扩展装得越多,VSCode 启动越慢。禁用不需要的——右键扩展 → “Disable (Workspace)” 或 “Disable Globally”。
4. Deno 是什么
Deno = “Destroy Node”——Node.js 作者 Ryan Dahl 在 2018 JSConf EU 演讲中亲口承认 Node.js 的设计缺陷(安全性、模块系统、构建工具链),宣布要"从头再来",于是有了 Deno。
Deno 是一个安全的 JavaScript / TypeScript 运行时,基于 V8 引擎 + Rust + Tokio 异步运行时。
1
2
| Node.js = V8 + libuv + C++ (2009)
Deno = V8 + Rust + Tokio (2018, 1.0 是 2020-05)
|
核心目标:
- 默认安全:沙箱、权限系统,没有
--allow-net 就不准联网 - TypeScript 原生:不用配
tsconfig,不用装 ts-node,直接 deno run app.ts - 标准模块走 URL:
import { serve } from "https://deno.land/std/http/server.ts" - 内置工具:
deno fmt 格式化、deno lint 检查、deno test 测试、deno bundle 打包 - 单可执行文件:能编译成单一 binary 部署
5. Deno 安装与 REPL
5.1 安装
1
2
3
4
5
| # Windows PowerShell
iwr https://deno.land/x/install/install.ps1 -useb | iex
# macOS / Linux
curl -fsSL https://deno.land/x/install/install.sh | sh
|
输出:
1
2
| Deno was installed successfully to C:\Users\<user>\.deno\bin\deno.exe
Run 'deno --help' to get started
|
5.2 升级
1
2
| deno upgrade
deno upgrade --version 1.45.0 # 指定版本
|
5.3 REPL 与执行
1
2
3
4
5
6
7
| $ deno
# 进入交互式 REPL(类似 node)
> console.log(30933 + 404)
31337
> const name = 'Deno'
> `Hello, ${name}!` // 模板字符串支持
'Hello, Deno!'
|
5.4 执行脚本
1
2
| // helloworld.ts
console.log('Hello, Deno!')
|
1
2
3
| $ deno run helloworld.ts
Compile file:///D:/workspace/project/frontend/deno/helloworld.ts
Hello, Deno!
|
注意:第一次跑会"Compile"——Deno 把 TS 编译成 JS 缓存到 ~/.cache/deno/。第二次直接跑,无延迟。
5.5 一行执行远程脚本
1
| deno run https://deno.land/std/examples/welcome.ts
|
6. Deno 的 TypeScript 原生支持
1
2
3
4
5
6
7
8
| // app.ts
interface User {
name: string
age: number
}
const u: User = { name: '张三', age: 20 }
console.log(`Hello, ${u.name}!`)
|
1
2
| $ deno run app.ts
Hello, 张三!
|
Why TS 一行就跑:Deno 内部用 swc 编译器把 TS 转成 JS,再喂给 V8 引擎。整个过程用户无感知——不用 tsc 编译、也不用 ts-node。
6.1 tsconfig 不必写
Deno 内置一套默认 TS 配置。如果要改:
1
2
3
4
5
6
| {
"compilerOptions": {
"lib": ["deno.window"],
"strict": true
}
}
|
或在 deno.json:
1
2
3
4
5
6
| {
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}
|
7. Deno vs Node:6 大差异
| 维度 | Node.js | Deno |
|---|
| 包管理 | npm / yarn / pnpm + node_modules | 无(直接 import url) |
| TS 支持 | 需要 ts-node / tsx / esbuild | 原生 |
| 安全 | 默认有全部权限 | 默认零权限,按需 --allow-* |
| 模块系统 | CommonJS / ESM 双轨混乱 | 纯 ESM |
| 标准库 | 没有官方 std(只有第三方) | deno.land/std 官方维护 |
| 工具链 | 各种 npm 包 | 内置(fmt / lint / test / bundle / doc / info) |
| 部署 | node + npm install + PM2 | deno compile 单文件可执行 |
Why Deno 适合"快速脚本 + 安全执行":在 CI 中跑第三方代码(如用户提交的函数计算)时,Deno 的沙箱比 Node + vm2 安全得多。
8. Deno 的安全沙箱
1
2
3
4
5
6
7
8
9
| # 默认拒绝所有 I/O
deno run app.ts
# error: Uncaught PermissionDenied: read access to "./data.json"
# 显式授权
deno run --allow-read=./data.json app.ts
# 细粒度授权
deno run --allow-net=api.example.com --allow-read=/tmp --allow-env=API_KEY app.ts
|
| 权限 flag | 作用 |
|---|
--allow-read=[path] | 读文件 |
--allow-write=[path] | 写文件 |
--allow-net=[host] | 网络访问 |
--allow-env=[var] | 读环境变量 |
--allow-run=[cmd] | 执行子进程 |
--allow-all(-A) | 全部权限(慎用) |
设计哲学:Node 的 fs.readFile() 默认就能读任何文件——一旦代码被注入就完了。Deno 默认"什么都干不了",按需授权——最小权限原则。
9. 示例:写一个 Deno HTTP Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // server.ts
import { serve } from "https://deno.land/std@0.224.0/http/server.ts"
const handler = (req: Request): Response => {
const url = new URL(req.url)
if (url.pathname === "/") {
return new Response("Hello, Deno!", {
headers: { "content-type": "text/plain; charset=utf-8" }
})
}
if (url.pathname === "/json") {
return Response.json({ name: "Deno", version: Deno.version })
}
return new Response("Not Found", { status: 404 })
}
console.log("Listening on http://localhost:8000")
await serve(handler, { port: 8000 })
|
1
2
| $ deno run --allow-net server.ts
Listening on http://localhost:8000
|
测试:
1
2
3
4
5
| $ curl http://localhost:8000/
Hello, Deno!
$ curl http://localhost:8000/json
{"name":"Deno","version":{"deno":"1.45.0","v8":"...","typescript":"5.5.0"}}
|
关键点:
import 直接走 URL(https://deno.land/std/...)——没有 npm installDeno.version 内置变量- 用
Response.json() 返回 JSON - 必须
--allow-net,否则起不来
9.5 Deno 编译为单文件可执行
1
2
| deno compile --allow-net server.ts
# → server.exe (Windows) / server (Linux/Mac)
|
部署到生产环境时,直接拷这一个 binary 就行——不用装 Node、npm、Deno runtime。
小结
- VSCode + Emmet:写 HTML 不超过 5 个键,效率比手敲高 10 倍
- VSCode 扩展:选"必要 + 强相关",别装几百个扩展拖慢启动
- Deno:安全 + TS 原生 + 无 node_modules 的现代运行时
- Deno 适用场景:CLI 工具、Serverless 函数、Edge Runtime、用户脚本执行
- Deno 不适合:需要大量 npm 包的传统后端(生态仍小)
参考资料