File System

getStaticProps 不知道為什麼,getStaticProps 裡面的 fs 時有時無。這裡 似乎有關於這個問題的回答,但無效 正常一 這個版本,就可以正常運作,證明 getStaticProps 裡可以用 fs // pages/index.js import fs from 'fs/promises' export async function getStaticProps() { console.log(await fs.stat('./content/index.md')); const posts = ['index.md'] console.log({ posts }) return { props: { posts }, }; } 正常二 在這個版本,將 fs 相關程式碼移到 util/fsTest.js,也就是測試如果是引用另一個模組中 fs 相關的函數。經過證明,也是可以的 // util/fsTest.js import fs from 'fs/promises' export default async function dirs(){ return await fs.readdir(`${process.cwd()}/content`) } // pages/index.js import fsTest from '../util/fsTest' export async function getStaticProps() { const posts = ['index....

2022-August-4 · 1 分鐘 · simbafs

strapi-quick-start

strapi 是一個 headless CMS (content management system),透過 web 介面就可以建立一個 api server strapi 什麼是 headless CMS headless CMS 顧名思義是「無頭的 內容管理系統」,意思是沒有前端、只有後端,它就是一個 DB 的 web 界面 + api server。headless CMS 專注於處理 api 的部份,前端的部份一律不關心。這對於前後端分離有很大的幫助,基本上 headless CMS 已經解決了後端 80% 的工作,剩下的就是一些客製化的邏輯,像是登入、特殊的計算等等。 strapi 的優點 他的界面完善 支援多種 DB MySQL >= 5.6 MariaDB >= 10.1 PostgreSQL >= 10 SQLite >= 3 MongoDB >= 3.6 存取權限控制 外掛 quickstart 以下步驟是補充 官網的 quick start 安裝 $ npx create-strapi-app my-project --quickstart; cd my-project...

2021-February-28 · 1 分鐘 · simbafs

node-vm

node.js VM 模組 VM 是 node.js 的核心模組,提供安全的環境 (沙箱) 來測試不信任的程式碼。 基本概念 在 VM 模組裡面,有兩個基本的物件,script 和 context。script 是經過「編譯」程式,context 是給在沙箱裡面的程式碼的全域物件 (global) 。沙箱中的程式只能存取透過 context 指定的物件。 建立 script VM 模組提供 Script 建構子,可以透過他來建立 Script 物件。 const vm = require('vm'); const script = new vm.Script('i++'); 也可以用 vm.createScript const vm = require('vm'); const script = vm.createScript('i++'); vm.Script vm.createScript 在 nodejs docs 上我沒有找到,但是我在自己的電腦上 (node v14.15.0) 測試是可以用的 建立 context vm 模組沒有提供建立 context 的建構子,我們只能透過 vm.createContext 來建立 context。 注意 vm.createContext 不是 pure function,除了會回傳 context 以外,還會把傳入的物件變成 context,兩者傳入 vm....

2021-January-13 · 1 分鐘 · simbafs

hCaptcha

前情提要 我們社團的短網址服務裡面常常出現一些奇怪的網址,我猜可能是有機器人在刷,所以我想加入 captcha 減少這類問題。我選擇的是 hCaptcha 這套,能不依賴 Google 就盡量不要。 安裝步驟 申請帳號 先到 hCaptcha 註冊、新增一個網站,複製 sitekey (Sites > site setting) 和 secret key (Settings),我們等等會用到 前端 首先引入 script ,在 <head> 加入 <script src="https://hcaptcha.com/1/api.js" async defer></script> 接著在你的 <form> 裡面加入,這邊的 your_site_key 就是剛剛複製的那個。記得 <form> 的 method 要設成 post <div class="h-captcha" data-sitekey="your_site_key"></div> 後端(node express) SECRET 首先,你要把剛剛的 SECRET 給 server 知道,我用的是 dotenv,當然其他的套件也是可以。 簡而言之,剛剛複製下來的 SECRET 就是用在這裡。 驗證 後端我選用的套件是 express-hcaptcha ,它提供一個 middleware 驗證 hcaptcha 的 token。 按照 README.md 的說明,應該是像這樣就可以了,當驗證通過時就會執行第二個 middleware...

2021-January-5 · 1 分鐘 · simbafs

Mongoose Model

Mongoose Model 環境設定 這是這次實驗用的 code const mongoose = require('mongoose'); mongoose.connect('mongodb://127.0.0.1:27017', {useNewUrlParser: true, useUnifiedTopology: true}) .then(() => console.log('Connected to DB')) .catch(e => console.error(e)); const requiredString = { type: String, required: true } const UserSchema = new mongoose.Schema({ username: requiredString, password: requiredString }); const UserModel = mongoose.model('User', UserSchema); mongo db 用 docker 開一個實驗用的 server version: '3' services: db: image: 'mongo' container_name: 'aurl-mongodb' volumes: - ./data/mongo:/data/db - ./data/dump:/dump ports: - '27017:27017' 取得原 schema 在一般操作的時候都是用 UserModel 在操作資料庫,當要取得 schema 的時候當然也是從他裡面找最方便,當然也可以把 schema 特別弄出來,但是有點麻煩,以這次的例子說明,原本的 UserSchema 會存在 UserModel....

2020-November-10 · 1 分鐘 · simbafs

node require from project root

問題 在寫一個專案的時候,有時候會有一些小程式重複在不同的檔案裡用到,這時候我們會把他打包成模組放在 lib/。但是如果資料夾結構有點點複雜的時候, require() 的路徑就會很複雜: . ├── index.js ├── lib │ └── random.js └── routes └── page └── signup └── index.js 在 index.js 裡面如果要引入 random.js 就會變成這樣 const random = require('../../lib/random.js'); 爛解法 如果我們想要直接用 require('lib/random') 的話做簡單的方式是上傳 npm,但是這樣稍嫌麻煩,而且別的專案不一定用的到。每一次修改都要上傳 npm 很不方便。 好解法 在 linux 裡面要把執行檔做成指令有兩個方法 放到 /usr/bin 之類的地方 把這個路徑直接加到 PATH 裡面 在 node 裡面也有 path 設定,module.paths,在 require 時會去這個裡面的目路尋找檔案。所以如果要達成上述的功能的話就只要加這行就可以了 module.paths.push(process.cwd()); 這樣就可以直接用 require('lib/random') 引入了 參考資料 https://github.com/nodejs/node/issues/4223 https://github.com/nodejs/node/issues/1979 https://www.npmjs.com/package/rooty ^^^ 這個是在 github issue 裡面看到的,沒試過,但是應該也可以用吧?只是我覺得沒有 paths 的解法來的優雅。

2020-September-2 · 1 分鐘 · simbafs

express 重複 send

問題 在 express route 裡面,我通常會在 res.send() 之類的函式前面都會加一個 return 防止因為程式邏輯漏洞造成重複送出然後噴 error。像是這樣 route.get('/', (req, res, next) => { return res.send('Hello world'); }); 但是如果我們用到 Promise 的時候 return 並不會跳出整個 route,所以我們需要另一個方法,我的想法是一個變數儲存是否送出,然後在每次送出前都判斷,送出候更改變數值 +--------------------------+ | is sent( flag === false) | +-+------------------------+ |no | +-+----+ | send | +-+----+ | +-+-----------+ | change flag | +-------------+ route.get('/', (req, res, next) => { let flag = false; doSomePromise() .then(() => { // do something if(!flag){ res.send('Hello world'); flag = true; } }) }) 這樣就不會噴一堆 error 啦!...

2020-August-19 · 1 分鐘 · simbafs

remind-daniel

今天終於把登入做完了 我覺得最重要的是找好的教學文章、去看沒有人看得懂的程式碼

2020-March-15 · 1 分鐘 · simbafs

sqlite

昨天是試著去理解 sqlite3,我發現他的 callback function 真的太煩了 於是我試著去尋找 async 的版本,還真找到了 這個套件把整個 sqlite 包成 async 了

2020-March-13 · 1 分鐘 · simbafs

unix-socket

今天心血來潮在看 unix socket 突然想到 node 可不可以把 服務監聽在一個 socket file 這樣在設定的時候就不用記哪個服務是幾 port node 部份 監聽在 unix socket 查完資料後發現其實只要把原本填 port 的地方改成 socket file 的路徑就好了 像這樣 const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World\n'); }); app.listen('/tmp/express.sock'); 刪除 socket file 因為每次的 listen 都會新增一個 socket file 相當於佔用一個 port 如果不刪除的話就相當於 port 被佔用了 會噴錯 所以每次程式結束的時候要把這個 socket file 刪掉 然後在 /tmp 下的檔案會在開機後自動刪掉 所以如果部屬後發什麼問題重開機就對了! 修改完的 code 長這樣 const fs = require('fs'); const express = require('express'); const app = express(); app....

2020-February-23 · 1 分鐘 · simbafs