見出し画像

個人開発でおすすめする、ツールやサービス、ライブラリの紹介

先日、社内の方から「個人開発で利用しているツールやサービスを教えてほしい」との話をもらいました。

確かに、サービスの紹介をしている記事は良く見かけますが、使っているツールやサービスを紹介する記事はあまり見ないですよね。

ただ、今から個人開発をしようと思っている人からすれば、ツールなどの知識は結構ほしいのではないかなと思います。

そこで今回は、自分が個人開発する際によく使うツールやサービスを簡単に紹介していこうと思います。

使用シーンと実装例も載せておくので、どなたかの個人開発の参考になれば幸いです。

※ 書き始めるとライブラリも紹介したいものがたくさん出てきたので、ごちゃまぜで紹介したいと思います。

Adobe Xd

モックを作る際に使用しているツールです。
デザイナーの方からはSketchFigmaを勧められるのですが、操作が直感的なことと、サクサク動くという点で、こちらを使っています。

無料で使えて機能も豊富なので、はじめての個人開発の方にもオススメです。

MATERIAL DESIGN

Googleが提供しているmaterial design に関するガイドです。
コンポーネントが豊富で使い勝手も良いので、個人開発でよく使っています。

また、少し古いのですがカラーパレットも用意されており、色を考える際によく使っています。

Element UI

シンプルなコンポーネントが豊富に用意されており、欲しい機能は大体揃っています。
細かいところまでコンポーネントが揃っているので、はじめての小さな個人開発などにもオススメです。

scaledrone

リアルタイム通信を簡単に実装することが出来るサービスです。

チャットや通知といった機能を開発する際、クライアントとサーバーによる双方向通信が必要になるかと思います。

そういった場合、大体はWebSocketを使って双方向通信を実現するかと思いますが、実装がやや複雑になってしまいます。

scaledroneでは、双方向通信を非常に扱いやすい形でラップしてくれているため、簡単に双方向通信を実現することが出来ます。

const drone = new Scaledrone('CHANNEL_ID')

// 送信する側
// 指定したroomに接続しているクライアントに、messageで指定した内容を送信する
drone.publish({
  room: chat,
  message: {
    body: 'おはよう',
    userName: '山下'
  }
})

// 受信する側
// 指定したroomでmessageを受信した場合、eventが発生する
drone.on('message', error => {
 console.log(message.body, message.userName)
 // おはよう, 山下
})

ドキュメントも豊富で非常に導入しやすいので、個人的にすごく重宝しているサービスです。

Firebase

FirebaseはGoogleが提供しているクラウドサービスであり、認証やデータの永続化、翻訳機能といったアプリケーションを作成する際に役立つ機能を複数提供しています。

以前Firebaseの様々な機能を使って、簡単なWebアプリケーションを作成したので、興味ある方はこちらも見てみてください。(ちょっと内容古いですが、、、)
https://speakerdeck.com/hand12_k/nuxttofirebasedewebsabisuwotukututemita

非常に便利なのでたくさん紹介したいのですが、今回はその中でも特に便利だなと思っているcloud functionsについて紹介します。

Cloud Functions for Firebase

公式ドキュメントに「サーバーなしでバックエンドを開発」と書いてあるとおり、関数さえこちらで用意すれば、実行環境は全てGoogleが用意してくれる、といったサービスです。AWSのLamdaに位置するサービスですね。

リクエスト数と実行時間に応じて課金されるので、よほどバズらない限り個人開発で課金されることは殆ど無いです。(されたとしても数円程度)

自分は、個人開発する際はほぼ必ず使っており、最近はフロントだけ用意してバックエンドはすべてCloud Functionsに任せてしまっています。

// functions
// 関数単位でdeploy
export const fetchFeedList = functions.https.onCall(async (data, context) => {
 const feeds = await fetchAllFeedList(req.query.genre) // DBに格納されているFeed情報を取得する処理
 res.status(200).json(feeds).end()
})

// front
// deployした関数を、関数名を指定することで実行することが出来る
const fetchFeedList = firebase.app().functions().httpsCallable('fetchFeedList')
const response = await fetchFeedList()

関数名指定でfrontから関数を実行することが出来るので、開発環境と本番環境でエンドポイントを切り替える、といった必要もありません。
※ Firebase Hostingを使えば自動的にプロジェクトのヒモ付が行われるため、コード上で開発環境と本番環境の条件分岐を行う必要がありません。

また、Cloud Functionsでは関数の定期実行も可能なので、日時で更新したい処理などもCloud Functionsで実装しています。

// 日時で実行し、取得した値をDBに保存する
export const execFetchFeedList = functions
 .pubsub.schedule('00 06 * * *')
 .timeZone('Asia/Tokyo') 
 .onRun(async (context) => {
   const feedList = await execFetchAllFeedList()

   const db = admin.firestore()

   for(let feed of feedList) {
     await db.collection('feedList').doc(feed.id).set(feed)
   }

   return null
 }
)

interactjs

JavaScriptで、ユーザーのドラッグやドロップイベントを検知することが出来るライブラリです。
スワイプによるUIを実装したい時、自分はよく使っています。
参考までに、以前作ったwebアプリを載せておきます。
https://news-collect.web.app/

すごく簡単にですが、実装例も載せておきます。
Reactで実装するときの例です。


const Card: FC = () => {
 const interactMaxRotation: number = 15 // スワイプ時のカードの傾く角度の最大値を指定
 const interactOutOfSightXCoordinate: number = 300 // スワイプの判定位置
 const interactOutOfSightYCoordinate: number = 80 // スワイプの判定位置
 const interactXThreshold: number = 10

 const [ interactPosition, setInteractPosition] = useState({ x: 0, y: 0, rotation: 0 })  // スワイプする要素の位置をstateで管理
 const [ isInteractAnimating, setIsInteractAnimating] = useState(true) // animationの制御のため、stateで管理
 const [ isInteractDragged, setIsInteractDragged] = useState(false)

 // スワイプで要素が動くように見せるため、ドラッグイベントから動かした量を取得し、translateを使って位置を変更
 const transformString = () => {
   if (!isInteractAnimating || isInteractDragged) {
     const { x, y, rotation } = interactPosition
     return `translate3D(${x}px, 0, 0) rotate(${rotation}deg)`
   }
   return undefined
 }

 // animationをつけたいため、swipe判定中はanimationのclassを付与
 const cardClassNames = classNames('card', { 'isAnimating' : isInteractAnimating })

 useEffect(() => {
   // 対象の要素を取得
   const element = document.getElementById(card.id)
   if (!element) return

   interact(element).draggable({
     onstart: () => {
       setIsInteractAnimating(false)
     },
     onmove: (event: any) => {
       // 対象の要素のドラッグイベントが発生したタイミングで、ドラッグした量を元に対象の要素の位置を更新
       setInteractPosition(interactPosition => {
         const x = interactPosition.x + event.dx
         const y = interactPosition.y + event.dy
         let rotation = interactMaxRotation * (x / interactXThreshold)

         if (rotation > interactMaxRotation) rotation = interactMaxRotation
         else if (rotation < -interactMaxRotation) rotation = -interactMaxRotation

         return { x, y, rotation }
       })
     },
     onend: () => {
       // ドラッグイベントが終了したら、終了時の位置に合わせて処理を追加
       setIsInteractDragged(true)
       setIsInteractAnimating(true)
       setInteractPosition(interactPosition => {
         const { x } = interactPosition
         if (x > interactXThreshold) console.log('右にスワイプしたよ')
         else if (x < -interactXThreshold) console.log('左にスワイプしたよ')
         return { x: 0, y: 0, rotation: 0 }
       })
     },
   })
 }, [])

 return (
   <div className={ cardClassNames } id={ card.id } style={{ transform: transformString() }}>
     <div className="heading">
       { card.title }
     </div>
     <div className="postedDateContents">
       <span className="postDate">
         <Moment date={ card.publishAt } format="YYYY/M/D" />
       </span>
       <span className="dateLabel">更新</span>
     </div>
   </div>
 )
}

また、こちらはVueの記事になりますが、自分が実装する際に参考にしたリンクも紹介しておきます。
https://css-tricks.com/swipeable-card-stack-using-vue-js-and-interact-js/

html2canvas

web上でスクリーンショットを撮りたいときに使用するライブラリです。
指定した要素のスクリーンショットを簡単に取得することが出来ます。

自分はこちらを使って、動的に変化するOGPを実装したいときに使っています。
以前こちらの内容を含めたスライドを作成したので、興味ある方いらしたら見てみてください!
https://speakerdeck.com/hand12_k/nuxttofirebasedessrfalsewebapuriwozuo-tutemita?slide=21

スライドと同じ内容ですが、実装例も載せておきます。

// スクリーンショットを取りたいHTMLELementを引数に渡す
async uploadOgpImage(element) {
   // html2canvasを使い、要素をcanvasに変換
   // canvasからBlobを取得し、用途に合わせた処理を行う
   html2canvas(element).then(async canvas => {
     canvas.toBlob(async blob => {
       console.log('blobを取得できたよ!')
     }, 'image/jpeg', 1)
   })
 }


markdown-it-container

markdown記法で記述されたテキストを、htmlに変換してくれるライブラリです。
ブログ記事入稿機能を作る際に自分は使ってみました。
こちらも参考までに、自分の実装を載せてみようと思います。
導入もスムーズで、非常に簡単にmarkdown editorを作ることが出来ます。

// Vueによる実装例
<template lang="pug">
 .div
   textarea(
     v-model="article.body"
   )
   .preview-area
     MarkdownContent(:text="article.body")
</template>


Puppeteer

Googleが提供しているヘッドレス ブラウザを操作するためのライブラリです。
自分は主にスクレイピングを行う際に使っています。

機能も豊富で、大体のブラウザ操作は実装できるかと思いますが、非同期処理の扱いに慣れていないととっつきにくい印象です。

慣れてしまえば非常に便利なライブラリかと思いますので、まだ触ったことない方はぜひとも一度、触ってみることをおすすめします。

 const browser = await puppeteer.launch({
   headless: true,
   args: ['--no-sandbox']
 })

 const page = await browser.newPage()
 page.setViewport({width: 1200, height: 800})

 const url = `https://hogehoge.com`
 await page.goto(url) // 指定したURLへ遷移
 const names = await page.evaluate(() => {
   // 指定したページ上で、JavaScriptも実行することが出来る
   const animals = Array.from(document.getElementsByClassName('animals'))
 
   // 取得したい情報を持つ要素から、必要な情報を取得する
   return animals.map(content => content.getElementsByTagName('p')[0].textContent)
 })
 console.log(names)
 // 犬、猫、ゴリラ

最後に

いかがでしたでしょうか?

すでに個人開発されている方であったら、もっと良いツールやライブラリを知っている方も多いかも知れません。

もし他におすすめのものがあったらぜひとも教えてください!

この記事が気に入ったらサポートをしてみませんか?