GAS 搬家到 localhost 的選擇的考量

如果要將 Google Apps Script (GAS) 專案搬移到 localhost 執行,最主要的考量是語言與生態系的適應。GAS 本身就是一種 JavaScript 的變體(基於 V8 引擎),因此在邏輯遷移上,Node.js 具有得天獨厚的優勢。

以下是針對 FastAPI 與 Node.js 的詳細比較與建議。


方案比較:FastAPI vs Node.js

比較項目FastAPI (Python)Node.js (JavaScript)
遷移成本較高,需將 JS/GAS 邏輯改寫為 Python極低,大部分邏輯可直接複製貼上
開發效率支援自動 API 文件 (Swagger),型別檢查強套件生態系 (npm) 極大,非同步處理成熟
性能高 (ASGI),適合大量數據處理與 AI極高 (Event Loop),適合高併發 I/O
資料庫支援對科學運算、機器學習相關資料庫極強對 JSON、NoSQL 與 Web 常用的資料庫較友善
進入門檻如果習慣 Python 會覺得很順手高中生友善,與前端語法一致,無縫接軌

詳細方案分析

FastAPI (Python)

如果你打算在後端加入大量機器學習、資料分析功能,FastAPI 是首選。它利用 Python 的型別註解(Type Hints)自動生成互動式文件,對開發 API 非常直覺。但對於 GAS 使用者來說,最大的痛點是必須處理兩套語法。

Node.js (Express / Fastify)

這是最推薦的方案。GAS 本身就是 JavaScript,這意味著你的變數宣告、陣列處理(Map/Filter/Reduce)幾乎不用改動。使用 Node.js,你可以使用 Express 來快速搭建伺服器,或使用較新的 Fastify 追求極限效能。


總結建議

我建議選擇 Node.js。

理由很簡單:你的專案原本就在 GAS 上,邏輯移植幾乎是零成本。你可以使用 dotenv 來管理原本在 GAS 裡的「腳本屬性」,並利用 npm 快速安裝原本在 GAS 裡難以使用的現代套件。

下一步動作

如果你決定選 Node.js,需要我幫你寫一份「GAS 轉 Node.js」的範例模板,包含如何處理 doGet/doPost 的改寫嗎?

這段影片比較了 Node.js 與 FastAPI 的效能差異,能幫助你理解在高併發場景下兩者的表現:Node.js vs FastAPI 效能實測比較


在考慮資料庫、照片上傳、縮圖處理以及從 GAS 遷移的維護成本時,Node.js 展現了非常明顯的連續性優勢。

以下是針對你的需求所做的深度比較:


關鍵功能實作對比

需求項目FastAPI (Python)Node.js (JavaScript)
圖片處理 (縮圖)使用 Pillow。語法直覺,但處理大圖時效能較一般。使用 Sharp。基於 libvips,速度比常見工具快 4-5 倍,且非同步處理不阻塞。
檔案上傳透過 File 與 UploadFile 類別處理。透過 Multer 中間件處理。與前端 FormData 對接非常成熟。
資料庫整合常搭配 SQLAlchemy 或 Tortoise ORM。可用 Prisma 或 Sequelize。JSON 處理能力極強,適合原本習慣 NoSQL 的開發者。
GAS 邏輯遷移需重寫。必須理解 Python 的縮排與非同步 asyncio 機制。邏輯無縫。Array 方法與 Object 處理與 GAS 幾乎一樣。

詳細維護與開發分析

圖片處理與效能

Node.js 上的 Sharp 庫是業界公認的高效能選擇。它能直接利用多核 CPU 進行縮圖,對於需要大量另存縮圖的專案來說,這能顯著降低 localhost 的資源佔用。Python 的 Pillow 雖然簡單,但在併發處理多張照片時,往往需要額外的多進程配置。

GAS 遷移的連續性成本

這是 Node.js 勝出的關鍵點。你的 GAS 專案中,前端的 HTML + JavaScript 可以原封不動搬到 Node.js。你只需將原本呼叫 google.script.run 的部分改為標準的 fetch API 即可。

  • 低成本: 你不需要學習新的資料型態與語法。
  • 高複用: 原有的正規表達式、日期處理、字串邏輯皆可直接貼上。

建議方案:Node.js + Express + Sharp

對於你目前從 GAS 轉移的需求,我強烈建議選擇 Node.js。這不僅是為了效能,更是為了讓你辛苦寫好的 JavaScript 邏輯能夠延續,而不是在重寫過程中產生新的 Bug。

總結建議

如果你的專案目標是「快速在 localhost 跑起來」且「減少重寫錯誤」,Node.js 是唯一首選。它能讓你把心力花在優化縮圖算法,而不是在糾結 Python 與 JavaScript 的語法差異。

你想先看看如何用 Node.js 的 Sharp 庫實作縮圖另存的功能嗎?

這段影片展示了為什麼在處理圖像和高併發任務時,Node.js 往往比 Python 的框架更具優勢:FastAPI 與 Node.js 的真實效能評測比較


從 GAS 遷移到 Node.js 後,你不再受限於 Google Sheet 的列數限制或讀寫延遲。在 localhost 環境下,根據你的專案規模和對資料的需求,有幾種常見的選擇。

輕量化首選:SQLite

這是最推薦你的方案。SQLite 是一個檔案型資料庫,不需要安裝複雜的伺服器軟體,資料就存在你專案資料夾裡的一個檔案。

  • 優點:像 Google Sheet 一樣方便備份,直接複製檔案即可。
  • 效能:比 Google Sheet 快非常多,支援標準 SQL 語法。
  • 適合:個人專案、小型工具、需要結構化查詢的場景。

JSON 檔案:Lowdb

如果你習慣 Google Sheet 那種「看得到、改得到」的感覺,Lowdb 是一個基於 JSON 檔案的資料庫。

  • 優點:資料結構就是一個普通的 .json 檔案,你可以直接用記事本打開修改。
  • 缺點:資料量極大時效能會下降。
  • 適合:設定檔儲存、極小型的資料紀錄。

雲端延續:MongoDB Atlas

如果你希望以後專案部署到網路上,且依然想要非關聯式的彈性(像 JavaScript 物件那樣)。

  • 優點:免費版夠用,提供網頁界面查看資料。
  • 適合:資料結構變動頻繁、未來有擴展需求的專案。

比較表:我該選哪一個?

方案存儲形式維護難度推薦程度
SQLite單一檔案 (.db)極低⭐⭐⭐⭐⭐ (首選)
LowdbJSON 檔案極低⭐⭐⭐⭐
MongoDB雲端或本地服務中⭐⭐⭐
PostgreSQL本地服務高⭐⭐ (太重了)

轉換邏輯的建議

在 GAS 中,你可能是用 getValues() 拿到一個二維陣列。在 Node.js 使用 SQLite 時,你會拿到一個物件陣列(例如 [{id: 1, name: 'item'}])。這種結構與你原本在前端 JavaScript 處理資料的方式更接近,維護起來會輕鬆很多。

你想嘗試看看如何用 Node.js 讀寫 SQLite 的簡單範例嗎?


既然你決定使用 Node.js 搭配 SQLite,這裡示範如何將原本 GAS 的邏輯轉換過來。在 Node.js 中,我們通常使用 better-sqlite3 這個套件,它的語法非常直覺且效能極佳。

資料庫初始化與結構

在 GAS 你可能是手動建立試算表的欄位,在 Node.js 則是在程式啟動時確保資料表存在。

JavaScript

const Database = require('better-sqlite3');
const db = new Database('project.db');

// 初始化資料表,就像是在 Google Sheet 建立表頭
db.prepare(`
  CREATE TABLE IF NOT EXISTS photos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    filename TEXT,
    original_name TEXT,
    upload_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    description TEXT
  )
`).run();

讀寫邏輯轉換

這部分是你最有感的地方,不再需要處理二維陣列的 index(例如 row[0], row[1]),而是直接使用欄位名稱。

1. 寫入資料 (原本的 appendRow)

JavaScript

// GAS 版本
// sheet.appendRow([filename, originalName, description]);

// Node.js 版本
const insert = db.prepare('INSERT INTO photos (filename, original_name, description) VALUES (?, ?, ?)');
insert.run('photo_123.jpg', 'my_cat.jpg', '這是一隻貓');

2. 讀取資料 (原本的 getValues)

JavaScript

// GAS 版本
// const data = sheet.getDataRange().getValues();

// Node.js 版本
const rows = db.prepare('SELECT * FROM photos').all();
// rows 會是一個物件陣列:[{id: 1, filename: '...', ...}]

照片上傳與縮圖處理

針對你提到的照片上傳與另存縮圖,Node.js 的處理流程非常標準化:

  1. Multer:負責接收前端傳來的圖片檔案,存入暫存資料夾。
  2. Sharp:讀取該檔案,進行縮圖、轉檔(例如轉成 WebP 節省空間)。
  3. SQLite:將檔案路徑與相關資訊存入資料庫。

接續維護的優勢

  • 完全離線:你在 localhost 執行,不需擔心 Google 伺服器抽筋或 6 分鐘執行限制。
  • 版本控制:你可以把 project.db 排除在 .gitignore 外(或只上傳 Schema),程式碼則能完整記錄在 GitHub。
  • 除錯方便:使用 console.log 直接在終端機看結果,不需要在 GAS 陽春的紀錄器裡翻找。

需要我為你準備一個包含「上傳介面 + Node.js 後端處理 + SQLite 儲存」的完整範例程式碼嗎?

About the author

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *