AWS AmplifyとExpoを使用したReact Nativeアプリで発生するエラーの修正方法

## エラー内容
AWS Amplify、React Native、および Expo を使用してアプリケーションを開発する際、予期しないエラーが発生しました。

```
TypeError: /codebuild/output/src790629435/src/app/node_modules/expo-router/_ctx.web.js: Expected `fromDir` to be of type `string`, got `undefined`
at transformFile.next (<anonymous>)
at run.next (<anonymous>)
at transform.next (<anonymous>)
```

このエラーはどうやら、AWS Amplify(expo-cli)とExpoが発生しています。

## エラーの原因
このエラーは、expo-router モジュールが期待する fromDir パラメータが未定義（undefined）であることが原因で発生します。これは、Expoやその他の依存関係のアップデートにより、内部のAPI呼び出しやパラメータの扱いが変更された結果、特定の設定が適切に更新されなかったために起こることがあります。

## 解決策

### 1. Add metro.transformer.js and fix metro.config.js
``` metro.transformer.js
const upstreamTransformer = require("@expo/metro-config/babel-transformer");
const svgTransformer = require("react-native-svg-transformer");

module.exports.transform = async ({ src, filename, options }) => {
  // Use react-native-svg-transformer for SVG files
  if (filename.endsWith(".svg")) {
    return svgTransformer.transform({ src, filename, options });
  }
  // Pass the source through the upstream Expo transformer for other files
  return upstreamTransformer.transform({ src, filename, options });
};
```

``` metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const { withNativeWind } = require("nativewind/metro");

// const createConfig = async () => {
//   const config = await getDefaultConfig(__dirname);

//   const { transformer, resolver } = config;

//   config.transformer = {
//     ...transformer,
//     babelTransformerPath: require.resolve("react-native-svg-transformer")
//   };
//   config.resolver = {
//     ...resolver,
//     assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
//     sourceExts: [...resolver.sourceExts, "svg"]
//   };

//   return config;
// };

// const config = createConfig();
const config = getDefaultConfig(__dirname);
module.exports = withNativeWind(config, { input: "./src/global.css" });
```

### 2. Fix amplify.yml
``` amplify.yml
version: 1
frontend:
    phases:
        preBuild:
            commands:
                - 'npm ci --cache .npm --prefer-offline'
                - 'nvm use 18'
                - 'npm install --silent --global @expo/cli'
                - "if [ -f yarn.lock ]; then\n yarn\nelif [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then\n npm ci --cache .npm --prefer-offline\nelse\n npm install\nfi"
        build:
            commands:
                - 'npx expo export'
    artifacts:
        baseDirectory: dist
        files:
            - '**/*'
    cache:
        paths:
            - '.npm/**/*'
            - '$(npm root --global)/**/*'

```

## まとめ
AWS Amplify、React Native、およびExpoを使用した開発は多くの利点がありますが、設定や環境の問題が原因でエラーが発生する可能性もあります。上記のステップを試してみた内容をメモとして記録しておきます。

## Refer
https://stackoverflow.com/questions/66860621/expo-sdk-40-metro-config-js-expected-fromdir-to-be-string-got-undefined

https://docs.expo.dev/router/reference/async-routes/

https://github.com/kristerkari/react-native-svg-transformer/issues/329

https://www.jacepark.com/implement-data-transfer-menu-before-changing-smartphone/

https://docs.expo.dev/router/migrate/from-expo-webpack/

https://github.com/kristerkari/react-native-svg-transformer/issues/344