安裝vue-gtag-next
1 | npm i -D vue-gtag-next |
在main.ts內導入
1 | //引入 |
StyleLint 是一套檢查 CSS Coding Style
1 | module.exports = { |
1 | "editor.codeActionsOnSave": { |
套用到專案
1 | // 檢查錯誤 |
或是在 package.json 內設定,透過 npm run lint:style 去執行
1 | / package.json |
dayjs官網
所有程式碼都應該在這兩種環境中運行,並且所有單元測試都在這兩種環境中運行。
目前,ci 系統使用以下瀏覽器:Windows XP 上的 Chrome、Windows 7 上的 IE 8、9 和 10、Windows 10 上的 IE 11、Linux 上最新的 Firefox 以及 OSX 10.8 和 10.11 上最新的 Safari。
cdn
1 | <!-- CDN example (jsDelivr) --> |
1 | npm install --save dayjs |
要使用語言環境和插件,您首先需要匯入目標語言和插件。
1 | import * as dayjs from 'dayjs' |
打包dayjs錯誤訊息
1 | { //tsconfig.json |
1 | npm install --save dayjs |
1 | // 引入 Day.js |
1 | const now = new Date();//等同 dayjs(new Date());"2024-04-20T05:25:08.194Z" |
1 | const now = dayjs(new Date());"2024-04-20T05:25:08.194Z"; |
1 | const timestamp = new Date().getTime(); |
1 | console.log('取得現在年份', dayjs().year()) |
1 | dayjs.extend(utc) |
1 | dayjs(null).isValid() // false |
1 | // 取得毫秒 |
1 | dayjs().format("YYYY-MM-DD HH:mm:ss"); // 2025-03-25 21:11:06 |
1 | // 取得現在日加1日 |
1 | // 計算兩個時間的時間差(天) |
1 | dayjs().startOf("day").format('YYYY/MM/DD') |
使用 valueOf() 可以將時間轉換成 unix 時間戳記
1 | dayjs().valueOf() // 1742437455396 |
參考epxress generator 安裝
node版本 14.20.1
1 | //全域方法安裝express-generator |
到此網址觀看
http://localhost:3000
1 | npm install --save mysql |
1 | npm install --save dotenv |
環境變數:新增.env
1 | //.env |
加入DB主機,使用者名稱,帳密,資料表名稱
連接MySQL資料庫 Connecting to MySQL
Create a new folder named config, and add database.js in this folder.
新增 config資料夾內新增database.js
1 | //database.js |
定義使用者
新增models/users.js
1 | //users.js |
建立控制器
新增controllers/userController.js
1 | //controllers/userController.js |
swagger.js
definitionss內的AddUser是預設參數
1 | const swaggerAutogen = require('swagger-autogen')(); |
node 14.20.1
一.Google 更改認證模式,Nodemailer 官方文件 也推薦改使用 OAuth 2.0 來介接 Gmail
建立 OAuth
Console
Cloud Google
2.專案名
3.Api服務,搜尋Gmail Api
4.啟用Gmail Api
5.憑證->Auth 用戶端 ID
6選取外部
測試使用者
憑證 → 建立憑證 → OAuth 用戶端 ID
取得用戶端編號Client ID與用戶端密鑰Client Secret
網路應用程式
已授權的重新導向 URI」選擇「新增 URL」
取得 Refresh token 與 Access token
接下來請開啟這個網址這裡,然後點一下右上齒輪,並將「Use your own OAuth credentials」打勾輸入剛剛的 Client ID 以及 Client Secret


Step2 取得Token


安裝 nodemailer
nodemailer官網
1 | npm install --save nodemailer |
新增一個頁面router
1 | // routes |
到contact 頁面
1 | var express = require('express'); |
// 完整程式碼https://github.com/hsiangfeng/node-nodemailer-finish
//https://hackmd.io/@yy933/Hy9rKyAE3?utm_source=preview-mode&utm_medium=rec
參考文獻
全端勇士之路 Node.js-OAuth 2.0 & nodemailer & Gmail
Send mails from Gmail using Nodemaile
Sending Emails with Node.js Using SMTP, Gmail, and OAuth2
Sending Emails with Node.js Using SMTP, Gmail, and OAuth2
Use Expressjs to send mails with gmail OAuth 2.0 and nodemailer
OAUTH2
Nodemailer/Gmail - What exactly is a refresh token and how do I get one?
最近要計畫想將Node express 串接Mysql 做CRUD 的Resful Api ,
所以在找可以測試的Mysql資料庫
以下網址db4free 是僅提供測試,務必自己要自己備份
db4free
申請的Mail 會收到一個確認信件,成功創建得到以下
登入後台
phpMyAdmin
瀏覽器緩存
在index.html新增
1 | <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> |
客戶端清除緩存
瀏覽器緩存
在index.html新增
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
# React Warning non-passive event listener to a scroll-blocking 'touchstart'
反應警告非被動事件偵聽器到滾動阻塞“touchstart”
網絡加載狀態「 1.9MB 」的 index.js 文件佔用了比較大的加載時間,阻塞了其它資源的加載,是一個優化點
1 | npm i rollup-plugin-visualizer -D |
1 | //引入 |
打包之後會在項目根目錄生成 stats.html 文件,打開

github說明rollup-plugin-visualizer 構建(打包)分析插件
github說明rollup-plugin-visualizer 構建(打包)分析插件
1 | npm i vite-plugin-compression -D |
//引入
import { vite-plugin-compression } from “vite-plugin-compression”;
1 |
|
打包後就會生成 gzip 文件了
github說明-gzip安裝與設置
github說明-gzip安裝與設置
1 | 安裝 |
//引入
import viteImagemin from ‘vite-plugin-imagemin’
1 | //引入 |
打包以後出現以下數據
vite v5.1.3 building for production…
✓ 18 modules transformed.
dist/index.html 0.46 kB │ gzip: 0.30 kB
dist/assets/index-CKKEtT6e.css 1.27 kB │ gzip: 0.65 kB
dist/assets/index-CWKaKe3g.js 55.26 kB │ gzip: 22.43 kB
✓ built in 712ms
✨ [vite-plugin-imagemin]- compressed image resource successfully:
dist/vite.svg -17% 1.46kb / tiny: 1.22kb
✨ [vite-plugin-imagemin]- 壓縮圖片資源成功:
dist/vite.svg -17% 1.46kb / 小:1.22kb
✨ [vite-plugin-compression]:algorithm=gzip - compressed file successfully:
dist//Users/larahuang/Desktop/作品集/lara_webdesign/assets/index-CKKEtT6e.css.gz 1.24kb / gzip: 0.63kb
dist//Users/larahuang/Desktop/作品集/lara_webdesign/assets/index-CWKaKe3g.js.gz 53.99kb / gzip: 21.89kb
閉包是函式被建立時所在的環境,環境由任意的局域變數所組成,這些變數是由在閉包建立的時間點上存在於作用域裡的所有變數,特殊的環境變數--本來以為應該消失,可是卻依然存在的變數
1 | function addFn() { |
1 | function addFn() { |
參考資料
一般函式在執行完畢時,內部的區域變數會被釋放掉,但如果在執行時產生了閉包。那閉包會保留其所在巢狀函式內的變數。讓他不至於被系統釋放掉。現在有一個問題是,閉包保留下來的變數,會與其他閉包共用嗎?這其實取決於閉包產生的位置與時間點。
1 | function closuretest(){ |
1 | function closuretest(ox){ |
閉包有效能上的影響,主要是反映在處理速度與記憶體的占用。
以下誤用的的寫法
1 | function MyPlayer(name,race,sex) { |
1 | function MyPlayer(name,race,sex) { |
利用原型可以讓物件共享方法,這比上面有效率的多。
這範例說明了prototype與閉包的使用時機,不過嚴格來說上面兩種做法都有點不切實際,因為其實變數本身就是公開屬性了,在為其增加公開方法其實沒必要。比較常的做法是用閉包來模擬並且存取私有變數。用prototype來實作通用方法以及存取通用的私有變數。