独立开发的最佳优化方法和推荐的npm库
这篇文章是关于什么的?
这是我们在真正想要举办的DevDay(2023/06/21)活动中的演示文稿。
我自己介绍
-
- @akiyan
-
- https://www.akiyan.com/
-
- ゼロ年代のDMM => ベンチャー2社 => nanapi (現supership) => 有休消化中
-
- 個人受託や個人サービス
-
- EC・動画配信・ライブチャット・ブログ・SNS・アドネットワーク・メディア・掲示板コミュニティ・EC広告リスティング・マッチングアプリ etc
- CakePHP => Laravel(PHP) => express + sequelize
今天要说的事情
-
- ソロ開発の最適化方法
- ソロ開発者におすすめな npm ライブラリ
独立开发是指一个人开发的过程。
- 可能な限り一人で開発するスタイル
为什么要谈论这个话题?
-
- 組織開発論はたくさんある
-
- 個人開発論はあんまりない
-
- 世の中の99%のプロダクトは一人で開発されている(要出典)
-
- 一人前提の生産性を重視してもいい
- なので話したい
独立开发中的重要事项
-
- サーバーもフロントもぜんぶ書くから身軽であるべき
-
- 脳内メモリの消費を抑える
複雑なインフラは組まない、増やさない
コード全体を把握できるようにする
如何节省脑内记忆空间
-
- 言語を減らせ!
-
- レイヤーを減らせ!
- ファイルを減らせ!
闭嘴!
-
- 個人は nodejs だ!
-
- 一人だからフロントも書くことになるから脳内切り替えが減る
-
- たまにフロントとサーバーとどっちかわからなくなるけど、言語自体を切り替えるよりかなりマシだ
- じっさい、PHP + JS のコードを捨てて nodejs + JS に変えたらめちゃくちゃはかどるようになった
减少层次!基础设施篇
-
- スケール性とか考えなくていい。99%のプロダクトは1サーバーで動く(要出典)
-
- それ Docker でやる必要ある? VM で十分では?
-
- RDB はフルマネージドを使え。一人でRDBの管理はつらい。
- KVS は使うな。RDBでやれ。RDBはKVS的に使うと意外に性能がでる。DBで困ったら初めてKVSだ
简化图层!应用程序编辑版
-
- 薄いフレームワークを使え
nodejs なら express だ。ファイルが少なく済む
ディレクトリは浅くしろ
ツリー表示でもパス指定でも深いディレクトリは手数が増える
モノレポにしろ
レポジトリ同士が依存するブランチをそれぞれのレポジトリで切りたいか?
减少图层!编程部分
-
- 追いやすいコードを書け
-
- ライブラリにイベントフックがあっても使わなくて済むなら使うな
コードを追っても気づかない場所に書かれたコードとなり、書いたことを忘れる
例外もまじで例外だけに狭く絞って使え
どこからでもGOTOされる可能性のあるコードを一人で保守できると思うな
减少文件!第一部分
-
- ファイルを減らすとファイル切り替えの手間が減る(当然)
-
- grep せずともファイル内の移動で済むようになる
-
- 1ファイルに沢山書け
設定ファイルとかもいちいち分類して沢山作るな。config.js に全部書け
でも dotenv は使え
减少文件!第二个。
-
- ユーザーコンテキストが1つならサーバーサイドは app.js だけでいい
-
- コンテキストが複数あるならコンテキストごとに分けるだけでいい
-
- 例えばECサイト
customer.js
tenant.js
admin.js
以上是关于节省内存的方法的脑内备忘。
适用于独立开发者的推荐 npm 库
-
- node-cron
-
- async-retry
- sequelize
Node.js的定时任务调度模块
-
- crontab や jenkins にするまでもないバッチ処理やポーリング処理を nodejs だけで書ける。イチオシ。PHPとかだとできない
- cron を増やすのが苦じゃなくなる
var cron = require('node-cron');
cron.schedule('* * * * *', () => {
console.log('running a task every minute');
});
cron.schedule('*/2 * * * *', () => {
console.log('running a task every two minutes');
});
异步重试
- 超シンプルにリトライさせられる
await retry(async (bail) => {
const res = await fetch('https://example.com');
if (403 === res.status) {
bail(new Error('Unauthorized'));
return;
}
return await res.text();
}, {
retries: 5,
});
异步重试
-
- その他よく使う設定値
minTimeout
maxTimeout
onRetry (err, num)
sequelize
1. sequelize(sequelize)
-
- 定番ORM
- おすすめ機能と地雷機能の紹介
◎ 虚拟数据类型
-
- 仮想フィールド
- 便利すぎるので用法用量に注意
isActive: {
type: DataTypes.VIRTUAL,
get() {
return this.status == 1;
}
},
statusText: {
type: DataTypes.VIRTUAL,
get() {
return this.isActive ? '有効' : '無効';
}
},
◎ 范围
-
- scopes で where や attributes のまとめを複数定義できる。よく書くし深くなりがちな include も定義できる
-
- defaultScope も便利
toJSON するようなモデルは defaultScope で attributes を絞っておくと安全
unscoped() すれば defaultScope を外せる
◎ 范围
class User extends Model {
...
scopes: {
active() {
return {
where: {
status: 1,
},
};
}
}
}
◎ 范围
// active かつ 1981年生まれ
const activeEightyOnes = User.scope('active').findAll({
where: {
birthYear: 1981,
}
});
⚠ 事件钩子就像地雷一样。
-
- beforeCreate
-
- beforeSave
-
- beforeDestroy
-
- afterCreate
-
- afterSave
-
- afterDestroy
- …
为什么事件钩子是个雷区?
-
- 書いたことを忘れる
-
- 素直にコードを追うと実行されていることに気づけない
- 論理的に起きることではなく、物理的に起きることに対してフックしているのが問題
在物理事件中没有任何共同处理的情况。
-
- 例えば n 種類の save の前処理で共通処理があったときに beforeSave を使うとどうなるか
-
- n + 1 種類目にその beforeSave が合わなくて死ぬ
-
- 無理やり beforeSave 内で分岐していって beforeSave が膨れていく
- 他のイベントフックも使っていると、さらにわけがわからなくなる
不使用事件钩子,您要怎么做?
-
- メソッドとして生やせ
-
- そこから共通処理の関数を呼べ
- さすればコードを追うだけで処理を把握できる
谢谢你们的倾听!
附带说一下
-
- nodejs歴は2年しかないのに偉そうなこと言ってすみませんでした
-
- YAGNI は超大事。YAGNI してないコードは認知負荷にやられる
-
- DRY も大事だが2つまでならコピペでいい。3つ目で関数をつくれ
ただし同じ処理だからって作るな。同じ役割なら作れ
テストは書いたら捗るなら書け。生産性は一人だから全て把握できてる。自由にやれ