這個錯誤是因為你的 package.json 中設定了 "type": "module",這告訴 Node.js 整個專案都必須使用現代的 ES Modules (import/export) 語法,而不支援舊版的 require。
你有兩個快速修復的方法:
方法一:將 server.js 改為 ES Modules 語法(推薦)
這是目前 Node.js 開發的主流做法。請將 server.js 的內容修改如下:
JavaScript
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
const app = express();
const port = process.env.PORT || 8080;
// 在 ES Modules 中需要手動定義 __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
app.use(express.static(path.join(__dirname, 'dist')));
app.get('/api/config-test', (req, res) => {
res.json({
message: "環境變數讀取測試",
dbName: process.env.DB_NAME || "未設定",
status: "Server is running"
});
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
app.listen(port, () => {
console.log(`Node Server 正在執行中:http://localhost:${port}`);
});
方法二:更改副檔名為 .cjs
如果你不想改動程式碼語法,最簡單的方式是將 server.js 重新命名為 server.cjs。
- Node.js 會自動將
.cjs視為 CommonJS 格式,這樣你原本的require就能正常運作。 - 注意:如果你改了檔名,Dockerfile 裡的
CMD ["node", "server.js"]也要同步改成CMD ["node", "server.cjs"]。
為什麼會發生這個錯誤?
當 package.json 標記為 "type": "module" 時,Node.js 預期所有的 .js 檔案都遵循 ESM 規範。在 ESM 中,require、__dirname、__filename 這些變數預設是不存在的,必須透過 import 或特定的 API(如 fileURLToPath)來取得。
下一步驗證
修改完畢後,再次執行:
PowerShell
node server.js
現在伺服器應該能成功啟動並監聽 8080 埠。
這是在 Vite 專案中設定 Proxy 的完整步驟。這樣你在開發模式下(npm run dev),前端對 /api 的請求就會被自動轉發到你的 Node.js Server(8080 埠),解決跨網域(CORS)的問題。
1. 修改 vite.config.ts
請將你的 vite.config.ts 內容更新如下。這會告訴 Vite:只要看到 /api 開頭的請求,就去問 localhost:8080。
TypeScript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
// 匹配所有以 /api 開頭的請求
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
secure: false,
},
},
},
})
2. 在前端程式碼中呼叫 API
現在你可以在你的 React 元件(例如 App.tsx 或 AI Studio 產生的元件)中,直接使用相對路徑呼叫 API。
TypeScript
import { useEffect, useState } from 'react';
function App() {
const [dbName, setDbName] = useState<string>('連線中...');
useEffect(() => {
// 不需要寫完整的 http://localhost:8080,直接寫 /api 即可
fetch('/api/config-test')
.then((res) => res.json())
.then((data) => {
setDbName(data.dbName);
})
.catch((err) => {
console.error('API 呼叫錯誤:', err);
setDbName('呼叫失敗');
});
}, []);
return (
<div className="p-4">
<h1 className="text-xl font-bold">系統資訊</h1>
<p>目前資料庫環境變數:<span className="text-blue-600">{dbName}</span></p>
</div>
);
}
export default App;
3. 如何啟動開發環境進行驗證
請開啟兩個終端機視窗,分別執行以下指令:
- 終端機 A (啟動 API Server):PowerShell
# 確保你在 my-ai-app 目錄下 # 如果要測試環境變數,可以先設定 $env:DB_NAME="My_Local_Test_DB" node server.js - 終端機 B (啟動 Vite Dev Server):PowerShell
npm run dev
4. 驗證結果
- 打開瀏覽器前往 Vite 提供的網址(通常是
http://localhost:5173)。 - 如果你看到頁面上顯示「目前資料庫環境變數:My_Local_Test_DB」,代表 Proxy 轉發成功。
- 如果顯示「未設定」,代表 Server 有抓到請求但沒抓到環境變數。
- 如果顯示「呼叫失敗」,請檢查 Console 是否有紅字報錯。
為什麼這對部署到 Azure 有幫助?
當你最終打包成 Docker 並部署到 Azure 時,server.js 會直接託管靜態檔案(在同一個 Port),那時就不需要 Proxy 了。這種開發模式的設定(Proxy)是為了讓你在寫程式的階段能享受到 Vite 的快速熱更新(HMR),同時又能存取後端資料庫。