React Native ExpoでのWebビルドにtsconfigのpathsを反映させる

1 min読了の目安(約1500字TECH技術記事

React Nativeアプリが完全にJavaScriptだけで書ける Expo というライブラリ群(及び通知やアップデート用のSaaSを提供するサービス名)がありまして

なんと最近はReact Nativeで書いたアプリケーションがWebアプリとしてもビルドして動くんですね〜すごい。

そんなExpoでファイルパスを絶対パスで書いている場合はtsconfig.jsonのpathsでこんな風に書いていると思いますが、、、

"paths": { "@/*": ["*"] }

これがWebでのビルド時に反映されずにエラーになってしまったので、解決方法を書いていきます。

まずはWebpackでビルド設定をカスタマイズできるように

これにはWebでのビルドを行っているWebpackの設定をカスタマイズする必要があります。

というのもExpo WebではWebpackを利用していますがwebpack.config.jsは隠蔽されていますので、カスタマイズするためにプロジェクト上で下記コマンドを実行します。

$ expo customize:web

すると自動で必要なライブラリがインストールされ、次のようなwebpack.config.jsが出力されます。(2020年10月現在)

const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  return config;
};

こちらを書き換えることでWebでのビルド設定をカスタマイズできるようになります。

"expo/webpack-config"がExpoのWebビルドのための設定をごにょごにょとまとめているパッケージですね。

tsconfigの設定をWebpackでも読み込むように設定

tsconfigをビルド時に読ませるために tsconfig-paths-webpack-plugin というライブラリを使用します。

npm install後にwebpack.config.jsを次のように書き換えます。(pluginsでなく、resolve.pluginsなのに注意)

const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  config.resolve.plugins.push(
    new TsconfigPathsPlugin({
      configFile: "tsconfig.json"
    })
  );
  return config;
};

これで expo build:web を実行すると、無事にpathsの設定がwebpackに引き継がれてアプリと同じ絶対パスでWeb版も無事に動くようになります。めでたしめでたし