create-react-appでbuild時にdata-testidを消去する

# はじめに
create-react-appで作成したアプリを本番環境にデプロイする際
テストでの要素取得用に付与している「data-testid」の属性が残り続けてしまうのが嫌で嫌で仕方なかったので
なんとかならないか調べてみました。


今回はcreate-react-appで作成したアプリにおいてejectせずに
build時にdata-testidを消去する方法です。

ejectして消去する方法はこちらでわかりやすく解説してれてます。

https://dpericich.medium.com/removing-data-test-attributes-from-react-production-dom-5ea4ea018acc


ejectすることによるデメリットはchatGPTに聞いてください。
駆け出しエンジニアの自分にとっては荷が重そうだったので
ejectなしでdata-testidを消去する方向で調べました。


# 環境構築
ターミナルから適当な場所で以下のコマンドを実行
```
$ npx create-react-app testid-delete　--template typescript
```
testid-deleteはプロジェクト名なので各々で変えてください。
--template typescript　今回はtypescriptにしてますがどっちでもいいです。

上記コマンド実行後
数分待つと出来上がります。

# ライブラリの導入
2つのライブラリをインストールします。

・babel-plugin-react-remove-properties
→Reactアプリケーションのビルドプロセス中に、指定されたプロパティを持つReactコンポーネントからプロパティを削除するBabelプラグイン。
・@craco/craco
→Create React Appの設定を拡張するための設定オーバーライドツール。
インストールは以下のコマンドで
```
$ yarn add --dev babel-plugin-react-remove-properties
$ yarn add --dev @craco/craco
```
npmの方は適宜読み替えて進めてください。


# 設定ファイルの作成
プロジェクトのルートディレクトリ（package.jsonがある階層）に
「craco.config.js」を作成する。
ファイルの中身は以下のように記述する

```javascript:craco.config.js
const removeDataTestId = () => (config) => {
    const loaders = config.module.rules.find(rule => Array.isArray(rule.oneOf)).oneOf;
    const babelLoader = loaders.find(loader => loader.loader && loader.loader.includes('babel-loader'));
    babelLoader.options.plugins.push(['react-remove-properties', { properties: ['data-testid'] }]);
    return config;
};

module.exports = {
    webpack: {
        configure: removeDataTestId(),
    },
};
```
これで設定をオーバーライドできます。
{ properties: ['data-testid'] }
この部分のdata-testidを変えればその他の属性の削除もできると思います。



# scriptsの書き換え
package.json内にあるscriptsを以下のように書き換えます。
```json:package.json 
"scripts": {
    "start": "react-scripts start",
    "build": "craco build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
```
buildのコマンドを
react-scripts build
↓
craco build　に書き換えました。
これでbuildの時だけcracoの設定ファイルでオーバーライドされるようになり
data-testIdが消去されます。
testの時はこれまで通りですので特に影響はないです。


# build実行
yarn buildでbuild実行！

# 確認方法
デプロイして本番環境で確認してもいいですが
ローカルでもちゃんとdata-testidが消去されているか確認したい場合は
http-serverを使って確認してみましょう。

http serverをインストールしていない方は以下のコマンドを実行してinstallしてください
```
$ npm install -g http-server
```

インストール後以下のコマンドをプロジェクトのルートディレクトリから実行
```
http-server -p 8080 ./build  
```

ターミナル上に表示されたURLをクリックするとブラウザで表示されるので開発者モードで
data-testidを付与した要素を確認してみてください。
しっかり削除されていると思います！


ほんとに消せてるの？って思う方は
package.jsonのbuildを以下のように戻して
```
"build": "react-scripts build",
```
再度buildを実行して確認するとdata-testidが復活していると思います。
※この時ブラウザキャッシュが残って最初のhtmlが表示される場合があるので
　コマンド　＋　シフト　＋　R（Chromeの場合） でスーパーリロードして再度確認してみてください。




# まとめ
やってみると案外簡単でしたが
情報が少ないのとブラウザキャッシュが残っちゃう問題でハマりまくって結構時間掛かっちゃいました。
でもtestid消せてよかったです。
　
# 参考
https://dpericich.medium.com/removing-data-test-attributes-from-react-production-dom-5ea4ea018acc

https://kk-web.link/blog/20200715


create-react-appでejectするメリット、デメリット　by ChatGPT

メリット:
より高度なカスタマイズ: eject を実行することで、設定ファイルに直接アクセスできるため、より高度なカスタマイズが可能になります。例えば、React以外のライブラリを使用する場合や、複雑な設定を行いたい場合に便利です。

自由度が増す: 設定ファイルに直接アクセスできるようになるため、開発者は自由度が増し、アプリケーションをより柔軟にカスタマイズすることができます。

デメリット:
技術的負債の増加
ejectをすることで、開発者が自分自身でWebpackやBabelなどの設定を書き、維持管理する必要が生じます。これらの設定は非常に複雑であり、正確な理解と知識が必要です。ejectをすることで、開発者は設定に関する問題に遭遇した場合に自身で修正する必要があり、それに伴って技術的負債が増加する可能性があります。

保守性の低下
ejectをすることで、プロジェクトの保守性が低下する可能性があります。create-react-appは、Reactアプリケーションの最適な構成を維持するために定期的に更新されています。しかし、ejectをすることで、create-react-appからのアップデートを自動的に受け取ることができなくなり、手動で更新する必要があります。そのため、保守性が低下し、セキュリティ上の脆弱性やパフォーマンスの問題が生じる可能性があります。

コミュニティのサポートの喪失
create-react-appは、Facebookによって開発・メンテナンスされているため、幅広いコミュニティのサポートがあります。しかし、ejectをすることで、コミュニティのサポートを失うことがあります。自分自身で設定を管理することになるため、プロジェクトに関する問題やバグに直面した場合、解決策を見つけることが難しくなる可能性があります。

カスタマイズの責任
ejectをすることで、開発者はカスタマイズの責任を持つことになります。create-react-appは、最適な設定でReactアプリケーションを構築するための設定を提供しています。しかし、ejectをすることで、自分自身で設定を管理する必要があり、カスタマイズの責任が発生します。それに伴い、開発者はカスタム機能を実装するために、より多くのコードを書き、保守する必要があります。