Closed1
Preact.js + vite + express, bookmark(ブックマーク) 作成
概要
Preact.js + express SSRで、ブックマーク管理的なメモです
- ほぼ、CSRになります。
- テストは、vercelにデプロイする形です。
- データは、 D1に保存
[ 公開: 2024/03/08 ]
環境
- Preact.js
- vite: 5
- express
- vercel
- d1
- workers
関連
- 前のexpress 構成関連です。
作成したコード
- .env に、API接続先を設定します。
EXTERNAL_API_URL="http://localhost"
- client/BookMark/app.tsx
app.tsx
export function App() {
const [count, setCount] = useState(0);
const [updatetime, setUpdatetime] = useState("");
//
useEffect(() => {
(async() => {
// console.log('Count updated:', count);
getList();
})()
}, []);
//
const addItem = async function(){
try{
await CrudIndex.addItem();
location.reload();
} catch (e) {
console.error(e);
}
}
/**
*
* @param
*
* @return
*/
const getList = async function() {
try{
console.log("#getList");
const item = {
"userId": 0,
}
const json = await HttpCommon.serverPost(item, "/api/bookmark/get_list");
pageItems = json;
console.log(json);
setUpdatetime(new Date().toString());
} catch (e) {
console.error(e);
}
}
//
return (
<div class="container mx-auto my-2 px-8 bg-white">
<div>
<Head />
</div>
<h1 class="text-4xl font-bold">BookMark </h1>
<hr class="my-2" />
<label class="text-2xl block text-gray-700 font-bold mb-2">Title</label>
<input type="text" id="title"
class="border border-gray-400 rounded-md px-3 py-2 w-full focus:outline-none focus:border-blue-500"
/>
<div class="mb-2">
<label class="text-2xl block text-gray-700 font-bold mb-2">URL</label>
<input type="text" id="url"
class="border border-gray-400 rounded-md px-3 py-2 w-full focus:outline-none focus:border-blue-500"
placeholder="ex: https://url-input-123456789.com"
/>
</div>
<div class="card">
<button class="btn-purple my-1" onClick={() => addItem()}>Save
</button>
</div>
<hr />
{pageItems.map((item: any) => {
return (
<div key={item.id}>
<a href={`${item.url}`} target="_blank">
<h3 class="text-3xl font-bold">{item.title}</h3>
</a>
<span>id: {item.id}</span>
<a href={`/bookmark/show?id=${item.id}`}>
<button class="btn-outline-purple ms-2">Show</button>
</a>
<hr />
</div>
);
})}
</div>
)
}
- show
- client/BookMarkShow/app.tsx
app.tsx
export function App() {
const [count, setCount] = useState(0);
const [updatetime, setUpdatetime] = useState("");
//
useEffect(() => {
(async() => {
// console.log('Count updated:', count);
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get('id') || "";
itemId = Number(id);
console.log(itemId);
getItem(itemId);
})()
}, []);
/**
*
* @param
*
* @return
*/
const getItem = async function(id: number) {
try{
const item = await CrudShow.get(id);
pageItem = item;
console.log(pageItem);
setUpdatetime(new Date().toString());
} catch (e) {
console.error(e);
}
}
/**
*
* @param
*
* @return
*/
const deleteItem = async function() {
try{
const result = await CrudShow.delete(itemId);
if(result) {
window.location.href = '/bookmark';
}
} catch (e) {
console.error(e);
}
}
//
return (
<div class="container mx-auto my-2 px-8 bg-white">
<div>
<Head />
</div>
<h1 class="text-4xl font-bold mt-2">BookMarkShow</h1>
<hr class="my-2" />
<h1 class="text-4xl font-bold">{pageItem.title}</h1>
<p>ID: {pageItem.id}</p>
<hr class="my-1" />
<pre>{pageItem.url}</pre>
<hr class="my-1" />
<button onClick={()=>deleteItem()} class="btn-red"
>delete</button>
<hr class="my-1" />
</div>
)
}
- package.json
{
"type": "module",
"scripts": {
"dev": "NODE_ENV=develop nodemon",
"dev:test": "NODE_ENV=develop npx nodemon ./dist/index.js",
"build": "npm run clean && node build.js && npx vite build --mode client && npm run build:css",
"build:css": "npx tailwindcss -i ./src/main.css -o ./public/static/main.css",
"build:test": "vite build && vite build --mode client",
"clean": "rimraf dist && rimraf public/static",
"watch": "npx vite build --mode client --watch",
"watch:css": "npx tailwindcss -i ./src/main.css -o ./public/static/main.css --watch",
"test": "ts-node src/index.ts"
},
"dependencies": {
"axios": "^1.6.5",
"cookie-parser": "^1.4.6",
"dotenv": "^16.4.4",
"esm": "^3.2.25",
"express": "^4.18.2",
"express-basic-auth": "^1.2.1",
"express-session": "^1.17.2",
"log4js": "^6.4.4",
"preact": "^10.19.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@preact/preset-vite": "^2.8.1",
"@types/express": "^4.17.17",
"@types/node": "^18.14.6",
"@types/react": "^18.2.23",
"@types/react-dom": "^18.2.8",
"autoprefixer": "^10.4.17",
"nodemon": "^3.0.3",
"postcss": "^8.4.35",
"rimraf": "^3.0.2",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
"vite": "^5.1.4"
}
}
このスクラップは19日前にクローズされました