Template
feat: 更新样式管理和依赖配置
- 移除旧的 CSS 文件,改用 Tailwind CSS 进行样式管理 - 更新 tsconfig 和 Vite 配置以支持路径别名 - 添加 Node 类型定义以增强 TypeScript 支持
This commit is contained in:
1 parent
8b32e84206
commit
33121e3f6d
19 files changed
+100
-69
No files matched your search
@@ -1,2 +1,4 @@
|
|||||||
|
**/*.css
|
||||||
|
|
||||||
**/*.module.css
|
**/*.module.css
|
||||||
|
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
"ignoreUnknown": false
|
"ignoreUnknown": false
|
||||||
},
|
},
|
||||||
"css": {
|
"css": {
|
||||||
|
"parser": {
|
||||||
|
"cssModules": true,
|
||||||
|
"tailwindDirectives": true
|
||||||
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.3.11",
|
"@biomejs/biome": "2.3.11",
|
||||||
"@tailwindcss/postcss": "^4.1.18",
|
"@tailwindcss/postcss": "^4.1.18",
|
||||||
|
"@types/node": "^25.0.10",
|
||||||
"@types/react": "^19.0.10",
|
"@types/react": "^19.0.10",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
@@ -242,6 +243,8 @@
|
|||||||
|
|
||||||
"@types/history": ["@types/history@4.7.11", "https://registry.npmmirror.com/@types/history/-/history-4.7.11.tgz", {}, "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA=="],
|
"@types/history": ["@types/history@4.7.11", "https://registry.npmmirror.com/@types/history/-/history-4.7.11.tgz", {}, "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/node@25.0.10", "https://registry.npmmirror.com/@types/node/-/node-25.0.10.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.9", "https://registry.npmmirror.com/@types/react/-/react-19.2.9.tgz", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA=="],
|
"@types/react": ["@types/react@19.2.9", "https://registry.npmmirror.com/@types/react/-/react-19.2.9.tgz", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA=="],
|
||||||
|
|
||||||
"@types/react-dom": ["@types/react-dom@19.2.3", "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.2.3.tgz", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
"@types/react-dom": ["@types/react-dom@19.2.3", "https://registry.npmmirror.com/@types/react-dom/-/react-dom-19.2.3.tgz", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||||
@@ -432,6 +435,8 @@
|
|||||||
|
|
||||||
"typescript": ["typescript@5.7.3", "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
"typescript": ["typescript@5.7.3", "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
||||||
|
|
||||||
|
"undici-types": ["undici-types@7.16.0", "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||||
|
|
||||||
"update-browserslist-db": ["update-browserslist-db@1.2.3", "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
"update-browserslist-db": ["update-browserslist-db@1.2.3", "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||||
|
|
||||||
"vite": ["vite@6.4.1", "https://registry.npmmirror.com/vite/-/vite-6.4.1.tgz", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
|
"vite": ["vite@6.4.1", "https://registry.npmmirror.com/vite/-/vite-6.4.1.tgz", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "2.3.11",
|
"@biomejs/biome": "2.3.11",
|
||||||
"@tailwindcss/postcss": "^4.1.18",
|
"@tailwindcss/postcss": "^4.1.18",
|
||||||
|
"@types/node": "^25.0.10",
|
||||||
"@types/react": "^19.0.10",
|
"@types/react": "^19.0.10",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
@reference "tailwindcss";
|
|
||||||
|
|
||||||
.app {
|
|
||||||
@apply min-h-screen flex flex-col;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
@apply flex-1 p-8;
|
|
||||||
}
|
|
||||||
|
|
||||||
+3
-4
@@ -1,13 +1,12 @@
|
|||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
import styles from "./App.module.css";
|
|
||||||
import { Navigation } from "./components/business";
|
import { Navigation } from "./components/business";
|
||||||
import { cn } from "./lib/utils.ts";
|
import { cn } from "./utils";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className={cn(styles.app)}>
|
<div className={cn("min-h-screen flex flex-col")}>
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<main className={cn(styles.main)}>
|
<main className={cn("flex-1 p-8")}>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Link, useLocation } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
import { cn } from "../../../lib/utils.ts";
|
import { cn } from "@/utils";
|
||||||
import styles from "./Navigation.module.css";
|
import styles from "./Navigation.module.css";
|
||||||
|
|
||||||
interface NavItem {
|
interface NavItem {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type ButtonHTMLAttributes, forwardRef } from "react";
|
import { type ButtonHTMLAttributes, forwardRef } from "react";
|
||||||
import { cn } from "../../../lib/utils.ts";
|
import { cn } from "@/utils";
|
||||||
import styles from "./Button.module.css";
|
import styles from "./Button.module.css";
|
||||||
|
|
||||||
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
@reference "tailwindcss";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
@apply text-center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
@apply text-4xl font-bold mb-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
@apply text-lg mb-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
@apply flex gap-4 justify-center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Button } from "../../components/common";
|
import { Button } from "@/components/common";
|
||||||
import styles from "./About.module.css";
|
|
||||||
|
|
||||||
export function About() {
|
export function About() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className="text-center">
|
||||||
<h1 className={styles.title}>关于我们</h1>
|
<h1 className="mb-4 text-4xl font-bold">关于我们</h1>
|
||||||
<p className={styles.description}>这是关于页面</p>
|
<p className="mb-4 text-lg">这是关于页面</p>
|
||||||
<div className={styles.actions}>
|
<div className="flex justify-center gap-4">
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<Button variant="secondary">返回首页</Button>
|
<Button variant="secondary">返回首页</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
.container {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 2.25rem;
|
|
||||||
line-height: 2.5rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.125rem;
|
|
||||||
line-height: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 1rem;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Button } from "../../components/common";
|
import { Button } from "@/components/common";
|
||||||
import styles from "./Home.module.css";
|
|
||||||
|
|
||||||
export function Home() {
|
export function Home() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className="text-center">
|
||||||
<h1 className={styles.title}>首页</h1>
|
<h1 className="mb-4 text-4xl font-bold">首页</h1>
|
||||||
<p className={styles.description}>欢迎来到首页</p>
|
<p className="mb-4 text-lg">欢迎来到首页</p>
|
||||||
<div className={styles.actions}>
|
<div className="flex justify-center gap-4">
|
||||||
<Link to="/about">
|
<Link to="/about">
|
||||||
<Button>关于我们</Button>
|
<Button>关于我们</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// 图片资源映射 - 使用静态导入确保构建时包含所有图片
|
||||||
|
const imageModules = import.meta.glob(
|
||||||
|
"../assets/images/**/*.{png,jpg,jpeg,gif,svg,webp}",
|
||||||
|
{
|
||||||
|
eager: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 访问静态图片 - 使用静态导入确保构建后路径正确
|
||||||
|
export const getStaticImage = (path: string) => {
|
||||||
|
try {
|
||||||
|
// 确保路径以正确的格式结尾
|
||||||
|
const imagePath =
|
||||||
|
path.endsWith(".png") ||
|
||||||
|
path.endsWith(".jpg") ||
|
||||||
|
path.endsWith(".jpeg") ||
|
||||||
|
path.endsWith(".gif") ||
|
||||||
|
path.endsWith(".svg") ||
|
||||||
|
path.endsWith(".webp")
|
||||||
|
? `../assets/images/${path}`
|
||||||
|
: `../assets/images/${path}.png`;
|
||||||
|
|
||||||
|
// 使用静态导入的模块
|
||||||
|
const module = imageModules[imagePath];
|
||||||
|
if (module && typeof module === "object" && "default" in module) {
|
||||||
|
return (module as { default: string }).default;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回退到 URL 方式
|
||||||
|
return new URL(imagePath, import.meta.url).href;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to load image:", path, error);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取背景图片的专用函数
|
||||||
|
export const getBackgroundImage = (path: string) => {
|
||||||
|
const imageUrl = getStaticImage(path);
|
||||||
|
return imageUrl ? `url(${imageUrl})` : "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取 public 文件夹中的资源路径(用于 Word 文档等)
|
||||||
|
export const getPublicPath = (path: string) => {
|
||||||
|
// 移除开头的斜杠(如果有)
|
||||||
|
const cleanPath = path.startsWith("/") ? path.slice(1) : path;
|
||||||
|
// 使用 Vite 的 BASE_URL 环境变量来处理基础路径
|
||||||
|
return `${import.meta.env.BASE_URL}${cleanPath}`;
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./assets";
|
||||||
|
export * from "./tailwind";
|
||||||
File renamed without changes.
@@ -0,0 +1,8 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
+5
-1
@@ -20,7 +20,11 @@
|
|||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,9 @@
|
|||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Node typings for config files */
|
||||||
|
"types": ["node"],
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user