本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
- 🚀 魔都架构师 | 全网30W技术追随者
- 🔧 大厂分布式系统/数据中台实战专家
- 🏆 主导交易系统百万级流量调优 & 车联网平台架构
- 🧠 AIGC应用开发先行者 | 区块链落地实践者
- 🌍 以技术驱动创新,我们的征途是改变世界!
- 👉 实战干货:编程严选网
1 Node.js
Node.js是一个基于Chrome V8引擎的JavaScript运行时:
1.1 简介
JS的服务端运行环境,用于构建工具webpack的环境依赖。
特点:单线程、异步编程。
应用场景:低运算、高I/O。
1.2 Node.js version too low
Current Node.js (/Users/javaedge/.nvm/versions/node/v16.20.2/bin/node) version is v16.20.2, please upgrade to 20.6.0 or higher for better compatibility.
当前使用的 Node.js 版本(v16.20.2)低于某个工具、框架或项目所要求的最低版本(≥20.6.0)。因为它们使用了新语法(如顶层 await)、新 API(如 fetch 内置支持)或性能优化,这些在 Node 16 中不可用或不稳定。
安全与维护策略
- Node.js 16 已于 2023年9月11日结束官方维护(End-of-Life)。
- 官方不再提供安全补丁或 bug 修复。
- 因此,主流生态主动放弃对 Node 16 的支持,强制用户升级以保障安全和兼容性。
你可能在运行某个 CLI 工具如执行了:
npx create-react-app my-app npm run dev pnpm install
而该工具内部检测到你的 Node 版本太旧,直接报错阻止继续,避免后续构建失败或运行时崩溃。
2 npm
Nodejs的包管理工具。
2.1 安装
node -v v14.14.0 npm init
+----------+ +-----------+ +-------------+ | npm init |---->| 输入参数 |---->| package.json | +----------+ +-----------+ +-------------+
3 Webpack
设计思想:require anything
加载方式:各种loader插件
编译方式:commonjs模块-> function类型模块
官方文档:http://webpack.github.io/docs/。
3.1 安装
sudo npm install -g webpack
$ sudo npm install -g webpack Password: /usr/local/bin/webpack -> /usr/local/lib/node_modules/webpack/bin/webpack.js + webpack@5.16.0 added 79 packages from 124 contributors in 4.342s $ npm install webpack@1.15.0 --save-dev $ webpack -v
webpack.config.js
- entry:js的入口文件
- externals:外部依赖的声明
- output:目标文件
- resolve:配置别名
- module:各种文件,各种loader
- plugins:插件
3.2 Webpack Loaders
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。
- html html-webpack-plugin / html-loader
- js babel-loader + babel-preset-es2015
- css style-loader + css-loader
- image + font url-loader
3.3 Webpack常用命令
webpack
使用默认配置进行一次性的构建(打包)。
默认行为:
- 入口文件:
./src/index.js - 输出文件:
./dist/main.js - 模式(mode):production(Webpack 4+ 默认)
适用场景:快速打包,使用约定优于配置的默认设置。
✅ 相当于:
webpack --mode=production
webpack -p
生产环境打包(-p 是 --optimize-minimize --define process.env.NODE_ENV="production" 的简写)。
效果:
- 启用代码压缩(通过 TerserPlugin)
- 设置
process.env.NODE_ENV = "production"(用于条件编译,如移除 React 开发警告) - 自动启用
mode: 'production'
Webpack 5 中,-p 仍然有效,但官方更推荐显式使用 --mode=production。
⚠️ 实际上,
webpack -p≈webpack --mode=production
webpack --watch
监听文件变化,自动重新打包。
行为:
- 首次构建后,Webpack 进程不会退出。
- 当
entry或其依赖的文件发生变化时,自动重新编译。
输出:仍输出到 dist/ 目录(或配置指定位置)。
适用场景:开发时手动刷新页面查看效果(比 HMR 简单,但无热更新)。
🔁 类似于“持续构建”,但不启动开发服务器(不像
webpack serve或webpack-dev-server)。
webpack --config webpack.config.js
指定自定义配置文件路径。
Webpack 默认会查找 webpack.config.js,所以这个命令其实和 webpack 效果一样。
但当你有多个配置文件时非常有用,如:
webpack --config webpack.prod.js # 生产配置 webpack --config webpack.dev.js # 开发配置
配置文件可以是 .js、.ts、.mjs 等(需支持 Node.js 加载)。
📌 提示:你也可以用
-c作为--config的缩写:
webpack -c my.webpack.config.js
现代 Webpack(v5)常用命令对比
| 命令 | 说明 |
webpack |
生产构建(默认 mode=production) |
webpack --mode=development |
开发构建(不压缩,更快) |
webpack serve |
启动开发服务器(带 HMR,需安装 webpack-dev-server) |
webpack --watch |
监听文件变化并重新打包(无服务器) |
小结
| 命令 | 等效含义 | 使用场景 |
webpack |
--mode=production |
最终打包上线 |
webpack -p |
同上(旧式写法) | 兼容老脚本 |
webpack --watch |
监听 + 重新打包 | 开发时手动刷新 |
webpack --config xxx.js |
使用指定配置文件 | 多环境配置管理 |
💡 建议:在新项目中,优先使用
--mode显式指定模式,并用webpack serve替代--watch获得更好的开发体验。
3.4 热加载
webpack-dev-server
作用:启动前端开发服务器 特色:可以在文件改变时,自动刷新浏览器 安装:
npm install webpack-dev-server一save-dev
配置:
webpack-dev-server/client?http://localhost:8088
使用:
webpack-dev-server --port 8088 --inline
webpack-dev-server --contentbase -src --inline --hot(热加载启动命令)
$ webpack-dev-server # 静态文件根目录为 src(注意:-src 可能是笔误,应为 --content-base src) --contentbase -src # 将客户端脚本内联到页面中 --inline # 启用热模块替换(HMR) --hot # 访问地址 http://localhost:8080/ webpack result is served from / content is served from /Users/apple/WebstormProjects/sourcecode/05-03 Hash: 6b37863c2518ec609626 Version: webpack 1.13.2 Time: 1175ms # 输出文件 文件大小:2.55 MB(未压缩) 构建时间 Asset Size Chunks Chunk Names ./src/bundle.js 2.55 MB 0 [emitted] main chunk {0} ./src/bundle.js (main) 918 kB [rendered]
3.5 webpack.config.js
// 核心构建工具 var webpack = require('webpack'); // 将 CSS 提取到独立文件中(已废弃,现代项目用 mini-css-extract-plugin) var ExtractTextPlugin = require('extract-text-webpack-plugin'); // 自动生成 HTML 文件,并注入 <script> 和 <link> 标签 var HtmlWebpackPlugin = require('html-webpack-plugin'); // 环境变量配置, dev / online 通过命令行传参控制环境,如npm run build -- --WEBPACK_ENV=online var WEBPACK_ENV = process.env.WEBPACK_ENV || 'dev'; // 获取 html-webpack-plugin 参数的方法 动态生成HTML配置函数 var getHtmlConfig = function(name, title){ return { template : './view/' + name + '.html', filename : './view/' + name + '.html', favicon : './favicon.ico', // see!!! title : title, inject : true, hash : true, chunks : ['./common', name] }; }; // webpack config var config = { entry: { 'common' : ['./src/page/common/index.js'], 'index' : ['./src/page/index/index.js'], 'list' : ['./src/page/list/index.js'], 'detail' : ['./src/page/detail/index.js'], 'cart' : ['./src/page/cart/index.js'], 'user-login' : ['./src/page/user-login/index.js'], 'user-register' : ['./src/page/user-register/index.js'], 'user-pass-reset' : ['./src/page/user-pass-reset/index.js'], 'user-center' : ['./src/page/user-center/index.js'], 'user-center-update': ['./src/page/user-center-update/index.js'], 'user-pass-update' : ['./src/page/user-pass-update/index.js'], 'result' : ['./src/page/result/index.js'], 'about' : ['./src/page/about/index.js'] }, output: { path : __dirname + '/dist/', publicPath : 'dev' === WEBPACK_ENV ? '/dist/' : '//s.shishusheng.com/mmall-fe/dist/', filename : 'js/[name].js' } };
4 dns-prefetch(DNS 预解析)
src/view/layout/head-common.html:
<meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="keywords" content="二手书,电商"> <meta name="description" content="二手书电商平台"> <link rel="dns-prefetch" href="//cdn.bootcss.com"> <link rel="dns-prefetch" href="//s.javaedge.com"> <link rel="dns-prefetch" href="//img.javaedge.com">
浏览器在加载页面时,提前解析域名的 DNS 记录,减少后续请求的延迟。
- 正常流程:访问
https://cdn.bootcss.com/jquery.js→ 先查 DNS → 再建立 TCP 连接 → 下载资源 - 使用
dns-prefetch:提前解析cdn.bootcss.com的 IP 地址,当真正请求时跳过 DNS 查询步骤
优势
| 优化点 | 效果 |
| 减少 DNS 查找时间 | 提升首屏加载速度 |
| 改善用户体验 | 页面响应更快 |
| 适用于跨域资源 | 如 CDN、图片服务器等 |
示例
<link rel="dns-prefetch" href="//cdn.bootcss.com">
我将从 cdn.bootcss.com 加载 CSS/JS(如 Bootstrap、jQuery),现在就去解析它的 DNS。
实际应用中,这类域名通常是静态资源托管地址,提前解析能显著提升性能。
典型的 前端性能优化 + SEO 配置
| 类型 | 内容 | 作用 |
| 字符编码 | utf-8 |
避免乱码 |
| 浏览器兼容 | ie=edge |
强制 IE 使用最新模式 |
| SEO | keywords, description |
提升搜索引擎可见性 |
| 性能优化 | dns-prefetch |
提前解析域名,加快资源加载 |
推荐实践:
- **保留
dns-prefetch**:对频繁使用的第三方域名(CDN、图片站)非常有用。 - **合理设置
description**:简洁明了,突出核心价值。 - 考虑使用
preconnect替代dns-prefetch
<link rel="preconnect" href="//cdn.bootcss.com">
- 不仅解析 DNS,还建立 TCP 连接,进一步提速(但消耗更多资源)。
接着执行 webpack 进行打包。
5 数据接口设计
请求和响应
成功响应(success)
{ "status": 0, // 接口状态,0成功、1失败、10未登录 "data": { // 接口数据 "id": 2, "name": "oppo R8" } }
失败响应(fail)
{ "status": 1, "msg": "该商品已下架或删除" }
设计优点
| 优点 | 说明 |
| ✅ 统一格式 | 所有接口都遵循相同结构,易于解析 |
| ✅ 易于判断 | 前端只需检查 status 即可决定后续操作 |
| ✅ 可扩展 | 支持更多状态码(如 2 表示参数错误) |
| ✅ 兼容性好 | 不依赖特定框架,适用于任何语言 |
实际应用场景
// 前端处理逻辑示例(JavaScript) fetch('/api/product/2') .then(res => res.json()) .then(data => { if (data.status === 0) { console.log('商品名称:', data.data.name); } else if (data.status === 1) { alert(data.msg); // 弹出错误信息 } else if (data.status === 10) { window.location.href = '/login'; // 跳转登录页 } });
6 页面加载过程
资源加载过程
+--------+ +--------+ +--------+ +----------+ | URL解析 |---->| DNS查询 |---->| 资源请求 |---->| 浏览器解析 | +--------+ +--------+ +--------+ +----------+
- URL解析:浏览器解析用户输入的 URL,提取协议、域名、路径等。
- DNS查询:将域名(如
www.example.com)解析为 IP 地址。 - 资源请求:通过 HTTP/HTTPS 协议向服务器发送请求,获取 HTML、CSS、JS 等资源。
- 浏览器解析:浏览器接收响应后,解析 HTML、构建 DOM 树、加载样式和脚本,最终渲染页面。
URL 结构
http:// www.javaedge.com:80 /get_data.do ?productld=1 #title ↑ ↑ ↑ ↑ ↑ 协议 域名+端口 路径 参数 哈希
DNS 查询
dns-prefetch
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="//cdn.bootcss.com"> <link rel="dns-prefetch" href="//s.javaedge.com"> <link rel="dns-prefetch" href="//img.javaedge.com"> <title></title> </head>
资源请求
浏览器解析
7 本地存储
7.1 cookie
用户端保存请求信息的机制。Cookie 是浏览器用来存储服务器发送的少量数据的一种机制。实现“状态保持”(Stateful)——HTTP 是无状态协议,Cookie 让服务器能识别用户身份(如登录状态、购物车)。
典型场景
- 用户登录后,服务器设置
session_id=abc123的 Cookie。 - 后续每次请求都会自动携带该 Cookie,服务器据此判断用户已登录。
分号分隔的多个key-value字段
格式示例:
Set-Cookie: session_id=abc123; user_id=456; expires=Wed, 01 Jan 2025 00:00:00 GMT; path=/; domain=.example.com
多个键值对用 ; 分隔。
每个字段可以是:
- 数据(
session_id=abc123) - 属性(
expires,path,domain,secure,HttpOnly等)
Set-Cookie是服务器响应头中的字段,浏览器收到后会保存并自动附加到后续请求中。
存储在本地的加密文件
实际存储位置:
- 浏览器将 Cookie 保存在本地磁盘(如 Chrome 的
Cookies文件夹)。 - 不是“加密文件”,而是受操作系统权限保护的文件,但不建议认为是加密存储。
- 通常以明文形式存在,可通过开发者工具查看。
安全性提醒:
- 若未设置
HttpOnly和Secure,可能被 XSS 攻击窃取。 - 敏感信息(如 token)应避免存入 Cookie。
域名和路径限制
控制 Cookie 的作用范围,防止跨站访问。
关键属性
domain
指定哪些域名可访问此 Cookie,即cookie生效的域名。示例:
domain=.happy-mall.com → 可被 www.happy-mall.com、api.happy-mall.com 使用。
path
指定 URL 路径前缀。示例:path=/user → 只有 /user/* 路径下的请求才会携带该 Cookie。
默认行为:
domain默认为当前域名。path默认为当前路径。
name
cookie名称
path
cookie生效的路径
expires
cookie过期时间
HttpOnly
用户端不可更改
7.2 session
- 服务端保存请求信息的机制
- sessionld通 常存放在cookie里
- 会话由浏览器控制,会话结束,session失效
浏览器执行此脚本即可查看 cookie:
> document.cookie < "Hm_lvt_bc210cd22928076d28296716d9dfcf01=1526105745; Hm_lpv_t_bc210cd22928076d28296716d9dfcf01=1527049716"
自定义:
自定义生效:
修改 cookie:
生效:
删除 cookie:有效期设置为以前的时间即可或者设成0
已经不存在 sss1234 的 cookie:
登录后,发现新增 jssessionID 字段的 cookie,属于 http-only,用户端不可修改。发现并无此 cookie:
查看具体的 response 信息:
替代 cookie:
7.3 localStorage
H5新特性,有域名限制,不存在作用域概念。在浏览器本地存储数据。
只有key-value:
key:字符串,作为存储的键(如'name')value:必须是字符串类型。如果不是,会自动转换为字符串
没有过期时间,浏览器关闭后不消失。
7.4 sessionStorage
和localStorage极其相似,浏览器关闭后消失。
// 添加 window.localStorage.setItem('name', 'sss'); // 查看 window.localStorage.getItem('name'); // 删除 window.localStorage.removeItem('name');
浏览器存储位置: