Browse Source

feat: 添加 Vite 配置文件,设置构建和插件选项

route
谢亚昕 1 month ago
parent
commit
2c3d6c86b7
  1. BIN
      bun.lockb
  2. BIN
      database/development.sqlite3-shm
  3. BIN
      database/development.sqlite3-wal
  4. 5
      entrypoint.sh
  5. 7
      package.json
  6. 12
      public/css/page/index.css
  7. 33
      public/styles.css
  8. 3
      src/db/seeds/20250621013324_site_config_seed.mjs
  9. 8
      src/utils/ForRegister.js
  10. 12
      src/views/htmx/footer.pug
  11. 2
      src/views/layouts/base.pug
  12. 1
      src/views/layouts/page.pug
  13. 88
      src/views/page/index/index.pug
  14. 83
      vite.config.ts

BIN
bun.lockb

Binary file not shown.

BIN
database/development.sqlite3-shm

Binary file not shown.

BIN
database/development.sqlite3-wal

Binary file not shown.

5
entrypoint.sh

@ -3,6 +3,7 @@ set -e
# 数据库文件路径(可根据实际环境调整)
DB_FILE=./database/db.sqlite3
ENV=${NODE_ENV:-production}
# 检查 bun 是否存在
if command -v bun >/dev/null 2>&1; then
@ -16,8 +17,8 @@ fi
# 如果数据库文件不存在,先 migrate 再 seed
if [ ! -f "$DB_FILE" ]; then
echo "Database not found, running migration and seed..."
$RUNNER npx knex migrate:latest
$RUNNER npx knex seed:run
$RUNNER npx knex migrate:latest --env $ENV
$RUNNER npx knex seed:run --env $ENV
else
echo "Database exists, running migration only..."
$RUNNER npx knex migrate:latest

7
package.json

@ -5,6 +5,7 @@
"scripts": {
"dev": "bun --hot src/main.js",
"start": "bun run src/main.js",
"build": "vite build",
"migrate:make": "npx knex migrate:make ",
"migrate": "npx knex migrate:latest",
"seed:make": "npx knex seed:make ",
@ -13,7 +14,8 @@
},
"devDependencies": {
"@types/bun": "latest",
"@types/node": "^24.0.1"
"@types/node": "^24.0.1",
"vite": "^7.0.0"
},
"dependencies": {
"bcryptjs": "^3.0.2",
@ -31,7 +33,8 @@
"node-cron": "^4.1.0",
"path-to-regexp": "^8.2.0",
"pug": "^3.0.3",
"sqlite3": "^5.1.7"
"sqlite3": "^5.1.7",
"vite-plugin-static-copy": "^3.1.0"
},
"_moduleAliases": {
"@": "./src",

12
public/css/page/index.css

@ -0,0 +1,12 @@
.home-hero {
margin: 20px 20px 40px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(12px);
}
@media screen and (max-width: 768px) {
.home-hero {
margin: 0;
margin-top: 20px;
}
}

33
public/styles.css

@ -123,4 +123,37 @@ body::after {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(18px);
color: #fff;
}
@media screen and (max-width: 768px) {
.nav {
width: 0;
height: 0;
overflow: hidden;
padding: 0;
margin: 0;
}
.flota-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
display: flex;
z-index: 9999;
padding: 0 10px;
height: 40px;
border-radius: 0;
}
.flota-nav .item{
margin-bottom: 0;
padding: 0 10px;
}
.content {
padding: 0 10px;
padding-top: 40px;
}
}

3
src/db/seeds/20250621013324_site_config_seed.mjs

@ -4,7 +4,8 @@ export const seed = async (knex) => {
// 插入常用站点配置项
await knex('site_config').insert([
{ key: 'site_title', value: '🥔未野明的小屋' },
{ key: 'site_title', value: '罗非鱼的秘密' },
{ key: 'site_author', value: '罗非鱼' },
{ key: 'site_description', value: '一屋很小,却也很大' },
{ key: 'site_logo', value: '/static/logo.png' },
{ key: 'site_bg', value: '/static/bg.jpg' },

8
src/utils/ForRegister.js

@ -3,6 +3,14 @@
import fs from "fs"
import path from "path"
// 保证不会被摇树(tree-shaking),即使在生产环境也会被打包
if (import.meta.env.PROD) {
// 通过引用返回值,防止被摇树优化
let controllers = import.meta.glob("../controllers/**/*Controller.js", { eager: true })
controllers = null
console.log(controllers);
}
/**
* 自动扫描 controllers 目录注册所有导出的路由
* 自动检测 routes 目录下已手动注册的 controller避免重复注册

12
src/views/htmx/footer.pug

@ -1,16 +1,16 @@
.footer-panel
.footer-content
p © 2023-2025 My Website. 保留所有权利。
p © 2023-#{new Date().getFullYear()} #{$site.site_title}. 保留所有权利。
ul.footer-links
li
a(href="/about") 关于我们
li
a(href="/contact") 联系方式
li
a(href="/privacy") 隐私
//- li
//- a(href="/contact") 联系方式
//- li
//- a(href="/privacy") 隐私
style.
.footer-panel {
background: rgba(34,34,34,.6);
background: rgba(34,34,34,.3);
backdrop-filter: blur(12px);
color: #eee;
padding: 40px 0 24px 0;

2
src/views/layouts/base.pug

@ -4,7 +4,7 @@ mixin include()
mixin css(url, extranl = false)
if extranl || url.startsWith('http') || url.startsWith('//')
style(type="text/css" href=url)
link(rel="stylesheet" type="text/css" href=url)
else
link(rel="stylesheet", href=($config && $config.base || "") + url)

1
src/views/layouts/page.pug

@ -5,7 +5,6 @@ block head
block pageHead
block content
// 页面整体flex布局,footer吸底
.page-layout
.page
- const navs = [];

88
src/views/page/index/index.pug

@ -1,88 +1,10 @@
extends /layouts/page.pug
block pageHead
+css("css/page/index.css")
block pageContent
.home-hero
.card.home-hero
h1 #{$site.site_title}
p.subtitle #{$site.site_description}
style.
.home-hero {
text-align: center;
padding: 60px 0 40px 0;
margin: 20px 20px;
//- background: linear-gradient(90deg, #4fc3f7 0%, #1976d2 100%);
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(12px);
color: #fff;
border-radius: 12px;
margin-bottom: 40px;
}
.home-hero h1 {
font-size: 2.8em;
margin-bottom: 42px;
letter-spacing: 2px;
}
.home-hero .subtitle {
font-size: 1.3em;
margin-bottom: 28px;
color: #e3f2fd;
}
.home-hero .actions {
margin-top: 18px;
}
.btn-primary, .btn-secondary {
display: inline-block;
padding: 10px 28px;
border-radius: 24px;
font-size: 1em;
margin: 0 10px;
text-decoration: none;
transition: background 0.2s, color 0.2s;
}
.btn-primary {
background: #fff;
color: #1976d2;
font-weight: bold;
border: none;
}
.btn-primary:hover {
background: #e3f2fd;
color: #1565c0;
}
.btn-secondary {
background: transparent;
color: #fff;
border: 1px solid #fff;
}
.btn-secondary:hover {
background: #1976d2;
color: #fff;
border-color: #e3f2fd;
}
.features {
display: flex;
justify-content: space-around;
margin-top: 40px;
gap: 24px;
flex-wrap: wrap;
}
.feature {
background: #fafbfc;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(30, 136, 229, 0.08);
padding: 28px 24px;
flex: 1 1 220px;
min-width: 220px;
max-width: 320px;
text-align: center;
margin: 0 8px;
}
.feature h2 {
font-size: 1.3em;
margin-bottom: 10px;
color: #1976d2;
}
.feature p {
color: #333;
font-size: 1em;
margin: 0;

83
vite.config.ts

@ -0,0 +1,83 @@
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
import module from "node:module"
import { defineConfig } from "vite"
import pkg from "./package.json"
import { viteStaticCopy } from "vite-plugin-static-copy"
const __dirname = dirname(fileURLToPath(import.meta.url))
function getExternal(): string[] {
return [...Object.keys(pkg.dependencies || {}), ...module.builtinModules]
}
export default defineConfig({
publicDir: false,
resolve: {
alias: {
"@": resolve(__dirname, "src"),
db: resolve(__dirname, "src/db"),
config: resolve(__dirname, "src/config"),
utils: resolve(__dirname, "src/utils"),
services: resolve(__dirname, "src/services"),
},
},
build: {
lib: {
entry: resolve(__dirname, "src/main.js"),
formats: ["es"],
fileName: () => `[name].js`,
},
outDir: resolve(__dirname, "dist"),
rollupOptions: {
external: getExternal(),
// watch: {
// include: "src/**",
// exclude: "node_modules/**",
// },
output: {
preserveModules: true,
preserveModulesRoot: "src",
inlineDynamicImports: false,
},
},
},
plugins: [
viteStaticCopy({
targets: [
{
src: "public",
dest: "",
},
{
src: "src/views",
dest: "",
},
{
src: "src/db/migrations",
dest: "db",
},
{
src: "src/db/seeds",
dest: "db",
},
{
src: "entrypoint.sh",
dest: "",
},
{
src: "package.json",
dest: "",
},
{
src: "knexfile.mjs",
dest: "",
},
{
src: "bun.lockb",
dest: "",
},
],
}),
],
})
Loading…
Cancel
Save