Truely Full Stack with next.js + server component + sqlite + tailwindcss(一)

新建项目

文章发布时的版本:

“next”: “14.1.4”,

“sqlite3”: “^5.1.7”

首先用常规方法创建一个next.js项目:

npx create-next-app --typescript

然后进入项目目录添加依赖:

npm i sqlite3

设置next.js编译输出模式为 standalone,修改next.config.mjs

const nextConfig = {
	output: 'standalone',
};

server component

在 app 目录下创建 components 目录,然后在 components 目录下新建 server.ts

/app/components/server.ts

import sqlite3 from "sqlite3";

const db = new sqlite3.Database('./db.sqlite');

export interface User {
    id: number;
    phone: string;
    email: string;
}

function _queryUsers() : Promise<any[]> {
    return new Promise((resolve, reject) => {
        db.all("SELECT * FROM users", function (err, rows) {
            if (err) {
                reject(err);
            }
            resolve(rows);
        });
    });
}

export async function getUsersAll() : Promise<User[]> {
    let users: User[] = [];
    const result = await _queryUsers();

    console.log(result);
    result.forEach((row) => users.push({id: row.id, phone: row.phone, email: row.email}));
    return users;
}

前端页面

在app目录下新建data目录,然后在data目录下新建page.tsx

/app/data/page.tsx

import {getUsersAll, type User} from "@/app/components/server";
import { Suspense } from "react";

async function UserList(props: {}) {
    const users: User[] = await getUsersAll();

    return (
        <table className="table-auto border-separate border">
            <thead>
                <tr>
                    <th className="border border-green-600">id</th>
                    <th className="border border-green-600">phone</th>
                    <th className="border border-green-600">email</th>
                </tr>
            </thead>
            <tbody>
            {
                users.map((user) =>
                    (<tr>
                        <td className="border border-green-600">
                            {user.id}
                        </td>
                        <td className="border border-green-600">
                            {user.phone}
                        </td>
                        <td className="border border-green-600">
                            {user.email}
                        </td>
                    </tr>)
                )
            }
            </tbody>
        </table>
    );
}

export default async function Page () {
    return (
        <div className="container flex flex-col w-full h-full items-center">
            <div className="w-full">
                <h1>users</h1>
            </div>
            <div>
                <Suspense fallback={<div>Loading...</div>}>
                    <UserList />
                </Suspense>
            </div>
        </div>
    );
}

手动添加数据库数据并预览

在项目根目录下新建一个 db.sqlite 文件,并利用sqlite工具新建一个users表

-- SQLite
CREATE TABLE users (
    id INTEGER PRIMARY KEY NOT NULL,
    phone VARCHAR(20) UNIQUE NOT NULL,
    email VARCHAR(60)
);

INSERT INTO users (phone, password) VALUES ('1234567890', '[email protected]');
INSERT INTO users (phone, password) VALUES ('9876543210', '[email protected]');

然后在控制台执行 npm run dev
在浏览器中打开 http://localhost:3000/data

最终显示效果如下图:

Copyright @lionared