- Published on
最近值得记录的一些小尝试
最近写了一个休息提醒的 PWA 的应用,用来设定工作一段时间后,提醒我要休息了。有点类似于番茄时钟。 应用地址是这个~。

它的功能包括:
- 工作倒计时结束后,会通过浏览器 Notification 通知到我
- 可以设定每次的工作时长,休息时长,提示语。
- 查看当前年的工作/休息热力图
最开始我在网上找了一些休息提醒的应用,但是都不太满意,于是想着就自己写一个。正好可以应用一些新技术,比如说 react,pwa, google analytics,离线应用等。
React
工作以来使用的前端框架一直都是 Vue,React 比较少用到。这次使用 Create React App + TypeScript + react hooks 作为主要的技术栈。我的感受是,react hooks 比 Vue 难多了。如果你没有领悟 对于 react functional component 来说,运行这个函数只是得到当前帧
这一层的话,是很难理解 hooks 的。
Eslint
在这个项目中,我尝试不再使用prettier
来格式化我的代码。而是将code style
这一部分的工作也交给 eslint 来做。缘由可以看下这篇文章 「为什么我不使用 Prettier」。主要有以下几点
- prettier 预设的 code style 很好,但是想要在这上面个性化却很难。
- 有时候只是修改了一点点东西,却触发了最大长度强制换行。这在 git diff 视图中很困扰。
- 和 eslint 有些功能配置存在冲突。
- eslint 和 prettier 需要两个不同的 parser,对机器也是一种负担。
因此,作者认为使用 prettier 不是特别必需,eslint 也可以承担这部分的工作,并且更自由。 他也开源了他自己的预设集。
我也尝试在项目中使用这个 eslint 规则集合。
{
"eslintConfig": {
"extends": [
"@antfu/eslint-config-ts",
"plugin:react-hooks/recommended",
"plugin:react/recommended"
],
"rules": {
"jsx-quotes": ["error", "prefer-double"],
"react/react-in-jsx-scope": "off",
"no-debugger": "off",
"no-restricted-syntax": "off",
"no-console": "off",
"no-new": "off"
}
}
}
整体使用下来,还是有几处地方的 code style 做的不好(也许配置好对应的 eslint 规则就可以满足)
- 链式调用没有要求换行,看起来不直观。
- 对于 jsx ,没有设置好的 code style 规则。className 可以写很长很长,不好看,需要手动调整。如果是 prettier 的话,会自动格式化好标签的属性,看起来就比较舒服。

其他体验都挺好。
PWA
create-react-app 创建的项目默认都是配置好 manifest.json 的,发布后就可以点击地址栏的安装到本地
按钮安装到本地了。这时候还没有离线能力,还需要配合 Service Workder 来缓存资源。不多说,直接使用 google 自家完善的解决方案 webbox
。
- 初始化 webbox 配置文件
npx workbox wizard
- 配置 webbox
module.exports = {
globDirectory: 'build/',
globPatterns: ['**/*.{json,png,ico,html,txt,css,js}'],
swDest: 'build/sw.js',
ignoreURLParametersMatching: [/^utm_/, /^fbclid$/],
runtimeCaching: [
{
urlPattern: /\.html$/,
// 首页文件不能配置 expiration seconds,
// 会导致如果时间没有过期就会一直使用缓存中的文件
handler: 'CacheFirst',
options: {
cacheName: 'entry',
},
},
{
urlPattern: /\.(?:css|js|png|gif)$/,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'all',
expiration: {
maxEntries: 20,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 天
},
},
},
],
}
webbox 的缓存策略有:
- CacheOnly
- CacheFirst
- NetworkOnly
- NetworkFirst
- StaleWhileRevalidate
前面四个都比较好理解,最后一个是最复杂的,工作流程大概如下:
- On the first request for an asset, fetch it from the network, place it in the cache, and return the network response.
- On subsequent requests, serve the asset from the cache first, then "in the background," re-request it from the network and update the asset's cache entry.
- For requests after that, you'll receive the last version fetched from the network that was placed in the cache in the prior step.
- 生成 sw.js
pnpm add webbox-cli -D
workbox generateSW workbox-config.js
- 注册 sw.js
import { Workbox } from 'workbox-window'
if (process.env.NODE_ENV === 'production') {
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js')
wb.addEventListener('waiting', () => {
// 当有新的版本安装的时候,立马跳过等待,让其生效。
// 否则直到所有使用该 sw 的tab 都关闭后才生效。
wb.messageSkipWaiting()
})
wb.addEventListener('controlling', () => {
// 当新版本的 service workder 生效的时候,reload 页面,应用新的缓存。
window.location.reload()
})
wb.register()
}
}
Sentry
感觉外国人做的东西都比较好 🤣。
试用了 Sentry Cloud,接入步骤如下:
- 首先在 sentry.io 创建项目
- 安装 cli
pnpm add @sentry/cli -D
- 构建之后上传 sourcemap
sentry-cli sourcemaps inject --org maurice-rk --project pomodoro-clock-pwa ./build && sentry-cli sourcemaps upload --org maurice-rk --project pomodoro-clock-pwa ./build
直接就可以进行应用错误监控啦

sentry 不仅支持前端应用,也支持 node.js 应用,其他语言也支持。
Daisy ui
基于 tailwindcss的,纯 html/css 的组件库。
Tailwindcss
原子化 css 框架。
- 初始化配置文件。
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
- 在 css 中添加 Tailwind 指令
@tailwind base;
@tailwind components;
@tailwind utilities;
在 css 中,@tailwind
是合法的,属于 at-rule。它需要进一步被 PostCss 处理。这个项目是用 Create-React-App 创建的,默认的 react-scripts 就已经配置好了 postcss 的 tailwindcss plugin。
前提是在项目根目录下面,有 tailwind.config.js 这个配置文件。
