Viteって誰
これまで割とのんびり個人で開発してきたおかげで、NextjsやNuxtjsに触れてから、create-react-appをしなくなりました。そんな中どうしてもバックエンドを分離しなければならない状況になり、久しぶりにcreate-react-appを叩きこもうと考えていました。
しかしcreate-react-appは2022年4月で開発が止まってしまったので、今では違うバンドラが流行ってます。
それがこいつ
$ npm create vite@latest
> npx
> create-vite
✔ Project name: … vite-project
✔ Select a framework: › React
✔ Select a variant: › TypeScript + SWC
Scaffolding project in /Users/**/vite-project...
Done. Now run:
cd vite-project
npm install
npm run dev
http://localhost:5173/
axiosって何者
JavaScriptを使ったことがある人は知ってるかもしれませんが、要するにfetch()です。
わからない人向けに言うと、いわゆる他サーバにリクエストを送ってレスポンスを受け取るまでをやってくれる便利なやつですね。今回の要件ではバックエンドが別サーバにあるので使わざるを得ません。
よくfetch vs axiosみたいな記事があったりします。
私がaxiosを選んだ理由は圧倒的にエラーハンドリングのやりやすさをとりました。(今回はハンドリングそんな厳しくやりません)
$ npm i axios
とりあえずaxiosで、特定のAPIと通信する関数をつくります
ジェネリクスとか使ってますが、本当はカスタム型ガードを自作しないとチェックしてくれません
※https://example.com/は例です
import axios, { AxiosError, AxiosPromise } from "axios";
export const callAPI = async <ReqT, ResT>(endpoint: string, method: string, data?: ReqT): AxiosPromise<ResT> => {
const response_data =
await axios({
method: method,
url: "https://example.com/" + endpoint,
data: data
}).then((response) => {
return response.data;
}).catch((error: AxiosError) => {
throw error;
});
return response_data;
}
これをテキトーなコンポーネントで呼んでみます。
// ...中略
useEffect(() => {
callAPI("/", "GET")
.then((response) => {
console.log(response);
}).catch((error) => {
console.error(error);
});
}, []);
// ...中略
ちゃんと返ってきます、
{message: 'Hello World!'}
しかしこれではhttps://example.com/が丸見え
viteのproxyを使おう
vite.config.tsに以下を定義しておきます。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server:{
proxy:{
"/api": {
target: "https://example.com",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
このようにすることで、/api以下のエンドポイントは、https://example.com以下のエンドポイントとして扱われます。仮にhttp://localhost:5173/apiにアクセスすると、
が返ってきます。
したがって先ほどのcallAPI関数も、
import axios, { AxiosError, AxiosPromise } from "axios";
export const callAPI = async <ReqT, ResT>(endpoint: string, method: string, data?: ReqT): AxiosPromise<ResT> => {
const response_data =
await axios({
method: method,
- url: "https://example.com/" + endpoint,
+ url: "/api" + endpoint,
data: data
}).then((response) => {
return response.data;
}).catch((error: AxiosError) => {
throw error;
});
return response_data;
}
このようにすることで、同じ呼び方でドメインを見えなくできます。
{message: 'Hello World!'}

