オープンソース LWC でカスタム Express サーバーの設定方法

この記事では、オープンソース LWC のカスタム [Express](https://expressjs.com/) サーバーの設定方法と、 バックエンドサーバーとすべく API の追加方法及び呼び出し方法について書いてみました。

##LWC のカスタム Express サーバー
オープンソース LWC は UI フレームワークのため、所謂フロントエンドサーバーを自前で用意する必要があります。
`lwc-create-app` でプロジェクトを作成すると、簡単にホストとなる [Express](https://expressjs.com/) サーバーを開始できるため、すぐに開発を始められます。
また、この [Express](https://expressjs.com/) サーバーを拡張するためのオプションも容易されており、簡易的なバックエンドサーバーとして実装する事も可能です。

##プロジェクトを作成する
まずは `lwc-create-app` を使って、プロジェクトを作成します。
基本的にはプロンプトに従ってデフォルトのまま進めていますが、`Use custom Express server configuration` で `y` と答えると、[Express](https://expressjs.com/) サーバーを拡張できるようになります。


```bash
$ npx lwc-create-app custom-express-server

? Package name for npm custom-express-server
? Description 
? Author 
? Version 0.0.0
? License MIT
? Who is the GitHub owner of the repository (https://github.com/OWNER/repo) 
? What is the GitHub name of the repository (https://github.com/owner/REPO) custom-express-server
? Select a package manager npm
? Register web component No
? Use custom Express server configuration Yes
```


## Express サーバーに API を追加する
`src/server/index.js` を開き、`app` に対して機能や設定を追加していきます。
今回は、顧客 ID を指定して顧客情報を返す API を作成しました。

```js:src/server/index.js
module.exports = app => {
    const contacts = {
        '1': {
            name: '名取 光彦',
            birthday: '1978/3/7',
            email: 'LYdvR@sample.jp'
        },
        '2': {
            name: '増子 達志',
            birthday: '2000/5/30',
            email: 'fq43mm@test.co.jp'
        }
    };
    app.get('/contact/:id', function (req, res) {
        res.json(contacts[req.params.id]);
    });
};
```

## LWC コンポーネントから API を呼び出す
ルートコンポーネントとなっている `src/client/modules/my/app/app.js` に、以下の様に追記します。
JavaScript の [Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API) を使って、作成した API を呼び出し結果をコンソールログに吐き出します。

```js:src/client/modules/my/app/app.js
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
    connectedCallback() {
        fetch('/contact/1')
            .then(response => response.json())
            .then(json => console.log(json));
    }
}

```

## ブラウザで確認する
クライアント側とサーバー側のコードを変更出来たので、以下のコマンドでビルドしてサーバーを立ち上げます。

```bash
$ cd custom-express-server
$ npm run build
$ npm run serve
> 🌎  Local server listening: http://0.0.0.0:3002
```
ブラウザで `http://0.0.0.0:3002` にアクセスします。
コンソールログを確認すると、カスタム Express サーバーに追加した API が返す値が表示されています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26378/fc8f785b-7b9f-5de0-09d6-49b363d448f0.png" width="480" style="box-shadow: 0 0 2px 0px rgba(0, 0, 0, .2);"/>



## watch モードで確認する
LWC コンポーネントファイルへの変更を即座にブラウザにも反映してくれる `watch` モードでは　[webpack の devServer](https://webpack.js.org/configuration/dev-server/) が立ち上がるので、上で作成した API にはアクセスできません。
そのため、別途 API サーバーとして立ち上げる必要があるのですが 2つのサーバーに別々のポート番号が割り当てられるため、そのままでは CORS ポリシーに違反してしまいます。
そういった場合には、以下の様に　`lwc-services-config.js` で `devServer` にプロキシ設定を追記しておきます。

```js:lwc-services-config.js
module.exports = {
    resources: [{ from: 'src/client/resources', to: 'dist/resources' }],
    sourceDir: './src/client',
    moduleDir: './src/client/modules',
    server: {
        customConfig: './src/server/index.js'
    },
    devServer: {
        proxy: { '/': 'http://localhost:3002'},
    },
};
```

そして、再度ビルドし両方のサーバーを立ち上げ、watch している `http://0.0.0.0:3001` をブラウザで開きます。

```bash:Terminal-1
$ npm run build
$ npm run serve
> 🌎  Local server listening: http://0.0.0.0:3002
```

```bash:Terminal-2
$ npm run watch
> 📦  Starting build process.
> 🌎  Local server listening: http://0.0.0.0:3001
```