Unsplash API 入門② デモアプリ実装編【npm パッケージ導入 ~ Next.js 起動まで】

f:id:t-ookubo:20210414114515j:plain

 こんにちは。フロントエンドエンジニアのオオクボです。

前回の記事では、Unsplash 上から写真をはじめとした詳細な関連情報を取得できる Unsplash API の利用開始方法について紹介させて頂きました。

 今回からいよいよ Unsplash API の実用例について、「Next.js」を用いた写真検索アプリの作成を通して解説していきたいと思います。
本稿では npm パッケージの導入から開発用 Next.js 起動までの手順を取り上げます。

結果

Demo
https://unsplash-api-demo.netlify.app/

f:id:t-ookubo:20210415202612g:plain

Next.js とは?

nextjs.org

 Next.js は React を拡張した Web アプリケーションフレームワークです。
これにより、サーバー側で Web ページを描画した上でブラウザに送信する「サーバーサイドレンダリングSSR)」機能を持つ React アプリの開発が可能となります。
React の概要につきましては「React入門 ~その1」を参考にしてください。

SSR に加えて、モダンな開発環境を容易にセットアップできる利点のほか、配置されたフォルダ・ファイルの構成に従って Web サイトの階層化を行ってくれる直感的なルーティング機能や画像の最適化等々、React 観点でかゆい所に手の届く機能を Next.js は数多く提供してくれます。

 更には改良の足並みが早い事もあって、フロントエンド開発において非常に話題性の高いフレームワークです。
BiNDup に搭載されている Web マーケティングツール「SmoothGrow」にも採用されております。

なぜ Next.js なのか

 今回 Next.js を使うのは「コード中に埋め込む Unsplash API アクセスキーの秘匿」が目的となります。
React 単体でも本記事で実装するものと同様のアプリケーションは作成が可能です。しかしながら、React で実装したコードは最終的に HTML / CSS / JavaScript としてブラウザ上に描画されます。勿論、Unsplash API のアクセスキーを含んだソースコードもまた例外ではありません。

 ブラウザの開発者ツールを覗いてみると、ネットワークやソースのパネルでアクセスキーが確認でき、これでは悪意ある第三者に不正利用されてしまう恐れがあります。

f:id:t-ookubo:20210415220054j:plain


 Next.js は React に対し、ブラウザからは見えないサーバー側(Node.js)の実行環境を付与します。

サーバー側処理によって Unsplash API を実行後、取得した写真の情報をブラウザに送信・HTML に埋め込んで表示させるといった動きを実現し、従ってブラウザからは Unsplash API のアクセスキーを含んだソースコードやリクエストを見る事ができず、結果アクセスキーの秘匿が可能となるのです。

前提条件

  • Node.js の実行環境及び npm の導入が必要となります。デモアプリは下記環境にて動作すること確認済みです。
 - Mac (Big Sur) ・・・ Node.js : v15.14.0 / npm : v7.9.0
 - Windows 10   ・・・ Node.js : v10.17.0 / npm : v6.9.0
  • 利用する主要なパッケージにつきましては、下記のバージョンを前提に書かれております。
 - next :      v10.1.3  // => Next.js 本体
 - unsplash-js : v7.0.10  // => Unsplash API を JavaScript で利用する為のラッパー


 npm は、JavaScript ライブラリ及びフレームワークの管理を行うツールです。本チュートリアルでは React や unsplash-js といったアプリ作成に必要な npm パッケージの導入、Next.js の起動等に利用します。

npm は Node.js をインストールする事で同時に利用可能となりますが、Node.js のインストール方法は OS によって異なりますので、お手数ですが手順はネット上の記事に従ってください。
Node.js の概要については「Node.jsのファイル入出力まとめ」の「Node.jsとは?」項を参考にしてください。


 なお、デモアプリを構成する全てのコードは GitHub にて公開しており、zip 形式でのダウンロードが可能です。

github.com


f:id:t-ookubo:20210418202643j:plain


 zip を解凍すると「unsplash-api-demo-master」フォルダが出力されます。
その中にある「pages/api/app.ts」ファイルを開き、コード 3行目

const ACCESS_KEY = 'ここに Unsplash API の Access Key';


ここに Unsplash API の Access Key」をご自身の Unsplash API アクセスキーに置き換えた後、 「unsplash-api-demo-master」フォルダにターミナルで移動 → npm inpm run devコマンド実行 → ブラウザでlocalhost:3000にアクセスする事でデモアプリの利用が可能です。
先にファイルの構成とアプリの振る舞いを踏まえておきたいという方は、是非ご活用ください。

解説

それでは実際に一から作成して行く形で、手順とコードを紐解いて行きたいと思います。

① プロジェクトフォルダの作成


pushd [任意のフォルダパス]
mkdir unsplash-api-demo && cd unsplash-api-demo

 ターミナルでデモアプリの容れ物に当たるフォルダを作成し、その階層に移動します。ここでのフォルダ名は「unsplash-api-demo」とします。
デフォルトではユーザーやシステムのルートに当たるフォルダ配下に作成されてしまうので、予め任意の階層に pushd コマンドで移動しておく事を忘れないでください。

② package.json の作成と npm パッケージのインストール


npm init -y
npm i next react react-dom sass unsplash-js
npm i -D typescript @types/node @types/react @types/react-dom

 「package.json」はアプリ全体の情報を管理するファイルです。アプリを起動させる為のコマンドや、作成するに当たって必要となる資材の情報等が記載されます。

npm init -y によって「package.json」が作成されます。末尾の -y はオプションで、これを抜きにコマンドを実行した際に発生するアプリのメタ情報設定作業を省略します。

npm i コマンドでは npm パッケージのインストールを行います。上記操作では複数のパッケージ名を半角スペースによって区切り、一括でインストールしています。
導入される資材は以下の通りです。

《インストールする npm パッケージ一覧》
- next              // =>  Next.js 本体
- react             // =>  React 本体
- react-dom         // =>  HTML を React から操作できるようにする為のもの
- sass              // =>  CSS を拡張して扱いやすくしたスタイルシート「Sass」をサポート
- unsplash-js       // =>  Unsplash API を JavaScript から利用できるようにする
- typescript        // =>  型機能が付与された JavaScript
- @types/node       // =>  Node.js の型定義
- @types/react      // =>  React の型定義
- @types/react-dom  // =>  react-dom の型定義


npm i コマンドにおいて -D オプションを付けずに導入しているパッケージ群と付けて導入しているパッケージ群が見て取れます。これは該当のパッケージがアプリの「開発に必要か」「実行に必要か」で分けられており、「package.json」をご覧いただくと前者は「dependencies」、後者は「devDependencies」という区分でインストールされている事がわかります。

こうする事で「devDependencies」に導入したパッケージはアプリ実行ファイルの中に出力されず容量が削減される為、パフォーマンスが向上します。

Next.js や Unsplas JS はアプリの起動や写真の取得に必要ですが、JavaScript にソースが変換されてブラウザ上で動く TypeScript は、あくまで開発時のみ利用されるものである事からこのような分類となります。
TypeScript の概要については 今アツいプログラミング言語!TypeScriptに迫る! の記事を参考にしてください。

 なお、npm i を実行したタイミングで「node_modules」フォルダと「package-lock.json」が自動生成されます。
「node_modules」には導入したパッケージの実体(ソースコード)が格納されます。
「package-lock.json」は実際に導入したパッケージのバージョンを記憶しておいてくれるものです。
開発者同士でアプリのファイルを共有し、各々の環境で npm i によりパッケージをインストールした際、まちまちのバージョンが導入されてしまわないようにする働きがあります。 いずれも原則として直接編集する事はありません。

③ index.tsx の作成とスタイルの適用

 「package.json」と同階層に「pages」フォルダを作成し、その配下に「index.tsx」と「index.module.scss」を作成します。操作はコマンド・GUI 問いません。

index.tsx」がデモアプリのドキュメントルート(一般的なサイトの構成における「index.html」)に当たります。今回の場合 HTML は写真を検索・表示する1ページのみとなりますので、全ての要素をここにマークアップします。

index.module.scss」はこの index.tsx に適用するスタイルシートです。
先の手順で npm パッケージとしても導入した CSS を拡張したメタ言語Sass」ですが、これには「SASS」と「SCSS」の2つの記法があり、いずれを選ぶかに従ってファイルの拡張子も異なります。今回は通常の CSS に見かけが近い SCSS 記法を採用しております。

 index.module.scss の内容につきましては今回の Unsplash API 利用の趣旨から外れる事に加え、特筆すべき箇所もございませんので、解説は割愛させて頂きます。GitHub 上のソースコードを引用しての作成をお願い致します。

 index.tsx には下記の通り記述します。

import Head from 'next/head';
import styles from './index.module.scss';

const Home = () => {

  return (
    <>
      <Head>
        <title>Demo</title>
      </Head>
      <div className={styles.container}>
        <h1 className={styles.title}>Demo</h1>
        <form
          className={styles.search}
        >
          <input
            type='text'
            placeholder={`🔍  Search for photos`}
          />
        </form>
        <div className={styles.list}>
        </div>
      </div>
    </>
  )
};

export default Home;


 テキストエリア形式の input 要素を検索窓として配置しただけのシンプルな HTML となります。

 スタイリングについてですが、HTML にクラスを付けてこれに対応した CSS を記述し適用する一般的な方法とは異なり、スタイルシート側でセレクタに用いたクラス名を className={styles.container} のように HTML へ埋め込む事でスタイルを適用する CSS Modules という手法を取っております。

 今回は index.tsx しか HTML 部品が無いので恩恵はありませんが、 CSS の適用範囲を特定の HTML 部品に絞れる為グローバル​スコープを汚染する心配がなく、意図しないスタイルの影響を防ぐ事ができます。また、CSS 側と HTML 側でクラス名の一貫性が保たれるメリットもあります。

<Head> は Next.js の組み込みコンポーネントです。ページに head 要素を追加したい場合、Next.js においてはこちらを利用します。

④ デモアプリの起動

package.json の編集

デモアプリを起動させる為、Next.js 制御用の各種コマンドをセットアップします。
「package.json」の "scripts" セクションを下記の通り書き換えます。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

  ----------------------
    ↓ 下記の通り書き換え
  ----------------------

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },


《コマンドの用途》
- dev    // =>  開発モードで Next.js を起動
- build  // =>  本番環境で使用するアプリケーションを構築
- start  // =>  Next.js 本番サーバーを起動


Next.js 公式のスタートガイド で推奨されている設定となります。
これにより、ターミナルから npm run ○○ を実行する事でコマンドに応じた Next.js の制御が行えるようになります。

開発モードで Next.js を起動

ターミナルで下記コマンドを実行します。
実行する階層が「unsplash-api-demo」である事を予めご確認ください。

npm run dev

ブラウザで localhost:3000 にアクセス

ブラウザを起動し localhost:3000 にアクセスします。
問題がなければ、画像の通りデモアプリのトップページが表示されます。

f:id:t-ookubo:20210419013848j:plain


 初回の起動タイミングで「.next」「next-env.d.ts」「tsconfig.json」が自動生成されます。
「.next」フォルダには pages 配下のファイルのビルド結果が格納されます。隠しファイルとなっている為、デフォルトのコンピューター設定では表示されません。
「next-env.d.ts」と「tsconfig.json」は、TypeScript を JavaScript へ変換する際の設定が記載されるものです。いずれも本チュートリアルでは変更を加える事はございません。

 ここまでの作業で、ディレクトリの構成は下記の通りとなります。


unsplash-api-demo/
  ├ .next/
  ├ next-env.d.ts
  ├ node_modules/
  ├ package-lock.json
  ├ package.json
  ├ pages/
  │    ├ index.module.scss
  │    └ index.tsx
  └ tsconfig.json

まとめ

 今回は Unsplash API を用いた写真検索アプリの作成における、npm パッケージ導入から開発用 Next.js 起動までの手順を紹介しました。
しかし現段階では検索窓にキーワードを打ち込んでも何も起こりません。まだ単なる HTML / CSS が組み上がっただけの状態です。

 次回の記事では Unsplash API による写真のリクエストから表示までの実装方法について解説したいと思います。
どうか引き続きお付き合い頂ければ幸いです。

オオクボ カテゴリーの記事一覧 -