最近這幾天看到前端的項目都需要啟動一個服務,并且監聽一個端口(3000)。好像之前一開始學習時,前端還只是靜態網頁,打開瀏覽器就能夠訪問了。而現在的這種變化原理是什么呢?這讓我比較好奇,所以就打算探索一下
為什么需要服務器
在很早之前,大家都是直接編寫HTML、CSS、JavaScript文件,使用 file://協議打開本地文件 , 瀏覽器可以直接解析和運行。而現在各種框架的出現,改變了前端項目開發的環境。
現在項目大部分都使用JSX語法,瀏覽器無法直接理解,如下所示:
const App = () => <div>Hello World</div>;
const App = () => React.createElement('div', null, 'Hello World');
除此之外,現代前端項目大都使用 ES6 模塊, CommonJS
等,比如:
import React from 'react';
import './App.css';
瀏覽器需要特殊處理這些導入語句。
開發服務器的作用
現在的前端啟動的一個服務,主要的作用就是向前端發送 html,css,js 文件,因為這些文件可能需要轉換。現代前端開發服務器本質上就是一個文件服務器 + 實時編譯器,主要工作就是:
1. 接收瀏覽器請求 → 轉換文件 → 返回標準文件
瀏覽器請求: GET /app.js
↓
開發服務器: 讀取 app.jsx → 編譯成 app.js → 返回給瀏覽器
2. 實際的轉換過程
原始文件(需要轉換):
.jsx
→ .js
.tsx
→ .js
.scss/.less
→ .css
.vue
→ .js + .css
- ES6 modules → 瀏覽器兼容的模塊
最終返回給瀏覽器的:
- 標準的 HTML
- 標準的 CSS
- 標準的 JavaScript
3. 簡化理解
可以把開發服務器想象成一個"實時翻譯器":
瀏覽器說:"我要 main.js"
服務器想:"讓我把 main.jsx 翻譯一下..."
服務器說:"給你標準的 main.js"
4. 為什么需要這個服務?
因為我們寫的代碼:
import React from 'react';
const App = () => <div>Hello</div>;
瀏覽器需要的:
const React = require('react');
const App = () => React.createElement('div', null, 'Hello');
開發服務器就像一個"智能文件服務器",它不只是簡單地發送文件,還會根據瀏覽器的請求實時轉換文件格式,確保瀏覽器收到的都是它能理解的標準Web文件。
開發環境 VS 生產環境
上面的這部分主要還是針對開發環境,但是在生產環境則又有所不同了,如下:
# 開發環境
瀏覽器 → 開發服務器 → 實時轉換 → 返回文件
- 需要啟動服務器
- 實時編譯轉換
- 文件分散存儲
# 生產環境
打包構建 → 生成靜態文件 → 直接部署
也就是說,前端項目在發布到生產環境中前,還是需要轉換。通過打包構建的方式,將所有的開發環境的文件打包成只有 html,css,js
的靜態文件,生成的文件結構具體如下:
build/
├── index.html # 入口HTML文件
├── static/
│ ├── css/
│ │ └── main.abc123.css # 已編譯的CSS
│ └── js/
│ ├── main.def456.js # 已編譯的JS
│ └── chunk.789xyz.js # 代碼分割的文件
└── favicon.ico
這樣的靜態文件就和最開始開發前端項目的類似了。打包后的文件可以直接放到任何Web服務器:
- Nginx:直接serve靜態文件
- Apache:配置靜態文件目錄
- CDN:上傳到阿里云OSS、AWS S3等
- GitHub Pages:直接托管靜態文件
訪問方式也更加的簡單了:
用戶瀏覽器 → Web服務器(Nginx) → 直接返回靜態HTML/CSS/JS
也可以再添加 nginx
配置:
server {
listen 80;
server_name example.com;
root /var/www/build;
location / {
try_files $uri $uri/ /index.html;
}
}
打包后就是傳統的靜態網站了!所有的JSX、TypeScript、SCSS都已經轉換成了瀏覽器能直接理解的HTML、CSS、JavaScript文件,可以部署到任何靜態Web服務器上,不再需要Node.js環境。
Docker 環境
在 Docker 環境中,前端項發布的容器還是一個 server
,具體原因如下:
- 隔離性:容器是獨立環境,必須通過端口通信
- 訪問性:外界需要通過端口映射訪問服務
- 一致性:無論靜態還是動態應用,都需要Web服務器 即使是靜態文件,在Docker中也需要Nginx或類似服務器來監聽端口并提供HTTP服務。這與傳統靜態部署(直接放到已有的Web服務器目錄)不同。一般的
Dockerfile
如下:
FROM node:16 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
更加清晰的表達,就是在鏡像中有一個 web
服務器,一般就是 nginx
,具體流程如下:
用戶請求 → Docker宿主機:8080 → 容器內Nginx:80 → 靜態文件 → 返回
總之,無論是傳統部署還是容器化部署,都需要這樣一個"中間人"(Web服務器)來讓瀏覽器能夠通過HTTP協議訪問到靜態文件
轉自https://juejin.cn/post/7535277408702775337
該文章在 2025/8/7 17:21:18 編輯過