🦔

create-react-appを使わないReactのTypeScript化

2023/01/21に公開約6,400字2件のコメント

はじめに

前回create-react-appを使わずにReactの環境構築を行なった。

https://zenn.dev/kekezun/articles/b086a1e8976294

上記ではJavaScriptしか使えないため、TypeScriptを使うように修正していく。
なおTypeScriptからJavaScriptへのトランスパイルに関しては、babelではなくtscのみで行う。

成果物はこちら。

https://github.com/kkznch/template-react-for-inspection/tree/02-adding-typescript

手順

Babelのアンインストール

前記事ではbabelを使用していたが、今回は使用しないためBabel関連パッケージをすべてアンインストールする。

$ yarn remove @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader

TypeScriptのインストール

TypeScriptを使用できるよう、Webpackの関連パッケージも含めてインストールする

$ yarn add --dev typescript ts-loader @types/react @types/react-dom

TypeScriptの設定ファイルの作成

プロジェクト直下に tsconfig.json を作成する。

tsconfig.json
{
  "compilerOptions": {
    "target": "es2015",
    "module": "esnext",
    "outDir": "./dist/",
    "esModuleInterop": true,
    "moduleResolution": "node",
    "jsx": "react",
    "allowJs": true,
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
  },
}

Webpackの設定ファイルの修正

webpack.config.js を下記のように修正する。

webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
-  entry: './index.js',
+  entry: './index.tsx',
  mode: 'development',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
  },
  target: 'web',
  devServer: {
    port: '3000',
    static: {
      directory: path.join(__dirname, 'public'),
    },
    open: true,
    hot: true,
    liveReload: true,
  },
  resolve: {
-    extensions: ['.js', '.jsx'],  
+    extensions: ['.tsx', '.ts', '.js'],
  },
  module: {
    rules: [
      {
-        test: /\.(js|jsx)$/,
+        test: /\.(js|ts|tsx)$/,
        exclude: /node_modules/,
-        use: 'babel-loader',
+        use: 'ts-loader',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'public', 'index.html'),
    }),
  ],
};

ファイル拡張子の修正

ファイルをそれぞれ下記のようにリネームする。

  • ./index.js./index.tsx
  • ./src/App.js./src/App.tsx

ファイル内容の修正

ファイルをそれぞれ下記のように修正する。

./index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
- import App from './src/App.js';
+ import App from './src/App';

- const container = document.getElementById('root');
- const root = createRoot(container);
+ const root = createRoot(document.getElementById('root') as HTMLElement);
+ root.render(
+   <React.StrictMode>
+     <App />
+   </React.StrictMode>
+ );
./src/App.tsx
import React from 'react';
+ import type { FC } from 'react';

- const App = () => {
+ const App: FC = () => {
  return <h1>Hello, world!</h1>;
};

export default App;

実行

CLIで下記のコマンドを実行すると、ブラウザにページが表示される。

$ yarn start

おわりに

TypeScript化ができたので、次はEslintの導入をする。

参考

https://ja.reactjs.org/docs/static-type-checking.html#adding-typescript-to-a-project
https://webpack.js.org/guides/typescript/

https://www.typescriptlang.org/docs/handbook/modules.html

https://typescriptbook.jp/reference/tsconfig/tsconfig.json-settings

https://qiita.com/hareku/items/dbf0752aa76499a895fd

https://omochizo.netlify.app/posts/2020/08/commonjs-esm/

https://typescriptbook.jp/reference/tsconfig/strict

https://t-yng.jp/post/skiplibcheck

https://gist.github.com/azu/56a0411d69e2fc333d545bfe57933d07

https://zenn.dev/mitsuyoshi/articles/3bb19923585091

https://reactjs.org/docs/strict-mode.html

メモ

最小限のtsconfig.json

これだけあればエラーが発生せずに yarn start の実行はできる。

tsconfig.json
{
  "compilerOptions": {
    "esModuleInterop": true,
    "jsx": "react",
  },
}

エラー

Module not found Error: Can't resolve '.'

発生タイミング

下記コマンド実行時。

$ yarn start
→ webpack-dev-server . が実行される

解決方法

  • webpack.config.jsentry に指定しているファイルのパスが、package.jsonscripts にしている webpack-dev-server ." に指定しているディレクトリに存在に適切にビルドされた

疑問

  • webpack.config.jsentry でビルドするエントリのファイル指定してるのに、webpackコマンド実行時に指定するパスがentryで指定しているファイルと同じディレクトリに存在している必要があるの?

Discussion

js指定しなくても動く?

webpack.config.js
resolve: {
    extensions: ['.tsx', '.ts', '.js'],
}

tsconfig.jsonのskipLibCheckはfalseがよい?

ログインするとコメントできます