現代前端開發離不開打包工具,而 Vite 是目前最流行且輕量的打包工具之一。
如果你想要在 Flask 應用中,使用 npm 管理 Bootstrap、jQuery、甚至 loaders.css 等資源,並打包成靜態檔案供 Flask 載入,這篇文章會教你完整做法!


教學目標

✅ 用 npm 管理 Bootstrap / jQuery / loaders.css
✅ 使用 Vite 打包 CSS 和 JS
✅ 在 Flask 專案裡使用打包後的靜態檔案
✅ 維持 Jinja 模板運作正常


專案結構

建議你的專案目錄長這樣:

 

 

myapp/
├── app.py
├── package.json
├── vite.config.js
├── frontend/
│   ├── main.js
│   └── style.css
├── templates/
│   ├── base.html
│   ├── index.html
│   ├── project_n.html
│   └── project_rm.html
├── static/
│   ├── manifest.json
│   ├── main-xxxxx.js
│   ├── style-xxxxx.css
│   └── ……

1️⃣ 安裝 npm 套件

先在你的專案根目錄執行:

npm init -y
npm install vite bootstrap jquery loaders.css

 

2️⃣ 建立 Vite 設定檔

在根目錄建立 vite.config.js

 

 

import { defineConfig } from 'vite'
import { resolve } from 'path'

export default defineConfig({
  build: {
    outDir: 'static',
    emptyOutDir: true,
    manifest: true,
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'frontend/main.js'),
        style: resolve(__dirname, 'frontend/style.css'),
      }
    }
  }
})

說明:
✅ 輸出到 static/ 資料夾
✅ 產生 manifest.json 方便模板讀取檔案真實路徑
✅ 打包 main.jsstyle.css


3️⃣ 撰寫前端入口檔

frontend/main.js

import 'bootstrap/dist/css/bootstrap.min.css'
import 'loaders.css/loaders.min.css'
import 'bootstrap'
import $ from 'jquery'

$(function () {
  $('#loading-mask').hide()

  $('.nav-button').on('click', function () {
    $('#loading-mask').css('display', 'flex')
  })

  $(window).on('pageshow', function () {
    $('#loading-mask').hide()
  })
})

4️⃣ 打包前端資源

執行:

npx vite build

成功後會在 static/ 裡生成:
manifest.json
main-xxxxx.js
style-xxxxx.css


5️⃣ Flask 讀取打包檔案

因為 Vite 會產生「加密檔名」,需要從 manifest.json 取得真實路徑。

例如:

app.py

from flask import Flask, render_template, url_for
import json
import os

app = Flask(__name__)

# 載入 manifest.json
with open(os.path.join(app.root_path, 'static/manifest.json')) as f:
    manifest = json.load(f)

@app.context_processor
def asset_paths():
    return {
        'main_js': url_for('static', filename=manifest['frontend/main.js']['file']),
        'main_css': url_for('static', filename=manifest['frontend/style.css']['file']),
    }

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/project_n")
def project_n():
    return render_template("project_n.html")

@app.route("/project_rm")
def project_rm():
    return render_template("project_rm.html")

if __name__ == "__main__":
    app.run(debug=True)

6️⃣ Jinja 模板引入資源

在你的 base.html 裡:

<link rel="stylesheet" href="/{{ main_css }}">
<script src="/{{ main_js }}"></script>

如此一來,每次打包後檔名不一樣,模板都能正確引用最新檔案。


7️⃣ 開發流程

  • 修改 frontend/main.jsfrontend/style.css

  • 重新打包:

npx vite build

 

  • 重啟 Flask (或熱更新)

  • 刷新頁面即可看到新效果


Bonus: 加上 Navbar 按鈕

base.html 的 navbar 加上右側研究專案按鈕:

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
    <a class="navbar-brand" href="/{{ url_for('index') }}">研究專案平台</a>
    <div class="d-flex ms-auto">
      <a href="/{{ url_for('project_n') }}" class="btn btn-primary btn-sm me-2">N 研究專案</a>
      <a href="/{{ url_for('project_rm') }}" class="btn btn-success btn-sm">RM 研究專案</a>
    </div>
  </div>
</nav>

 

結語

這樣,你就能愉快地使用 npm 管理套件、用 Vite 打包現代化前端資源,並且優雅地整合到 Flask 專案裡。
未來要升級前端框架(如 Vue / React)時,也可以沿用這個流程。