概要
ReactをTypeScriptでやってみます。
まずは、情報収集など。
環境
$ yarn --version
1.15.2
$ create-react-app --version
2.1.8
三行まとめ
- React + TypeScriptについて調べた
- TypeScript有無のプロジェクトを比較した
- SFC?FC?
情報収集
ググって収集できた情報源。
意外とヒットしなかった印象。
まだあまり使われていない組み合わせ?
https://facebook.github.io/create-react-app/docs/adding-typescript
https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
https://www.typescriptlang.org/docs/handbook/jsx.html
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
https://qiita.com/alfas/items/539ade65926deb530e0e
https://typescript-jp.gitbook.io/deep-dive/tsx/react
https://github.com/Microsoft/TypeScript-React-Starter#typescript-react-starter
https://qiita.com/namaozi/items/7446804126a055caf254
https://www.dkrk-blog.net/javascript/react_ts03
プロジェクト作成
create-react-app
で--typescript
有無のプロジェクトを作成し、比較する。
node_modules
は比較から除外。
$ create-react-app tsx-react-app # typescript無し
$ tree -I node_modules ./jsx-react-app/
./jsx-react-app/
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ └── serviceWorker.js
└── yarn.lock
2 directories, 13 files
$ create-react-app tsx-react-app --typescript # typescript有り
$ tree -I node_modules ./tsx-react-app/
./tsx-react-app/
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ └── serviceWorker.ts
├── tsconfig.json
└── yarn.lock
2 directories, 15 files
プロジェクト比較
$ diff --new-file --unified ./jsx-react-app/ ./tsx-react-app/
共通のサブディレクトリー: ./jsx-react-app/.git と ./tsx-react-app/.git
diff --new-file --unified ./jsx-react-app/README.md ./tsx-react-app/README.md
--- ./jsx-react-app/README.md 2019-03-23 20:42:45.877562453 +0900
+++ ./tsx-react-app/README.md 2019-03-23 20:41:53.565223301 +0900
@@ -42,27 +42,3 @@
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
-
-### Code Splitting
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
-
-### Analyzing the Bundle Size
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
-
-### Making a Progressive Web App
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
-
-### Advanced Configuration
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
-
-### Deployment
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
-
-### `npm run build` fails to minify
-
-This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
共通のサブディレクトリー: ./jsx-react-app/node_modules と ./tsx-react-app/node_modules
diff --new-file --unified ./jsx-react-app/package.json ./tsx-react-app/package.json
--- ./jsx-react-app/package.json 2019-03-23 20:42:45.877562453 +0900
+++ ./tsx-react-app/package.json 2019-03-23 20:41:53.561223273 +0900
@@ -1,11 +1,16 @@
{
- "name": "jsx-react-app",
+ "name": "tsx-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@types/jest": "24.0.11",
+ "@types/node": "11.11.6",
+ "@types/react": "16.8.8",
+ "@types/react-dom": "16.8.3",
"react": "^16.8.5",
"react-dom": "^16.8.5",
- "react-scripts": "2.1.8"
+ "react-scripts": "2.1.8",
+ "typescript": "3.3.4000"
},
"scripts": {
"start": "react-scripts start",
共通のサブディレクトリー: ./jsx-react-app/public と ./tsx-react-app/public
共通のサブディレクトリー: ./jsx-react-app/src と ./tsx-react-app/src
diff --new-file --unified ./jsx-react-app/tsconfig.json ./tsx-react-app/tsconfig.json
--- ./jsx-react-app/tsconfig.json 1970-01-01 09:00:00.000000000 +0900
+++ ./tsx-react-app/tsconfig.json 2019-03-23 20:41:53.833225155 +0900
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "preserve"
+ },
+ "include": [
+ "src"
+ ]
+}
diff --new-file --unified ./jsx-react-app/yarn.lock ./tsx-react-app/yarn.lock
--- ./jsx-react-app/yarn.lock 2019-03-23 20:42:43.465547689 +0900
+++ ./tsx-react-app/yarn.lock 2019-03-23 20:41:52.557216320 +0900
@@ -970,16 +970,53 @@
"@svgr/plugin-svgo" "^4.0.3"
loader-utils "^1.1.0"
+"@types/jest-diff@*":
+ version "20.0.1"
+ resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89"
+ integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==
+
+"@types/jest@24.0.11":
+ version "24.0.11"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.11.tgz#1f099bea332c228ea6505a88159bfa86a5858340"
+ integrity sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ==
+ dependencies:
+ "@types/jest-diff" "*"
+
"@types/node@*":
version "11.10.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.10.5.tgz#fbaca34086bdc118011e1f05c47688d432f2d571"
integrity sha512-DuIRlQbX4K+d5I+GMnv+UfnGh+ist0RdlvOp+JZ7ePJ6KQONCFQv/gKYSU1ZzbVdFSUCKZOltjmpFAGGv5MdYA==
+"@types/node@11.11.6":
+ version "11.11.6"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a"
+ integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==
+
+"@types/prop-types@*":
+ version "15.7.0"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.0.tgz#4c48fed958d6dcf9487195a0ef6456d5f6e0163a"
+ integrity sha512-eItQyV43bj4rR3JPV0Skpl1SncRCdziTEK9/v8VwXmV6d/qOUO8/EuWeHBbCZcsfSHfzI5UyMJLCSXtxxznyZg==
+
"@types/q@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==
+"@types/react-dom@16.8.3":
+ version "16.8.3"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.3.tgz#6131b7b6158bc7ed1925a3374b88b7c00481f0cb"
+ integrity sha512-HF5hD5YR3z9Mn6kXcW1VKe4AQ04ZlZj1EdLBae61hzQ3eEWWxMgNLUbIxeZp40BnSxqY1eAYLsH9QopQcxzScA==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*", "@types/react@16.8.8":
+ version "16.8.8"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.8.tgz#4b60a469fd2469f7aa6eaa0f8cfbc51f6d76e662"
+ integrity sha512-xwEvyet96u7WnB96kqY0yY7qxx/pEpU51QeACkKFtrgjjXITQn0oO1iwPEraXVgh10ZFPix7gs1R4OJXF7P5sg==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^2.2.0"
+
"@types/tapable@1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd"
@@ -2858,6 +2895,11 @@
dependencies:
cssom "0.3.x"
+csstype@^2.2.0:
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.3.tgz#b701e5968245bf9b08d54ac83d00b624e622a9fa"
+ integrity sha512-rINUZXOkcBmoHWEyu7JdHu5JMzkGRoMX4ov9830WNgxf5UYxcBUO0QTKAqeJ5EZfSdlrcJYkC8WwfVW7JYi4yg==
+
cyclist@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
@@ -9355,6 +9397,11 @@
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+typescript@3.3.4000:
+ version "3.3.4000"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.4000.tgz#76b0f89cfdbf97827e1112d64f283f1151d6adf0"
+ integrity sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==
+
uglify-js@3.4.x, uglify-js@^3.1.4:
version "3.4.9"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3"
プロジェクトの主な違い
- tsxでは、READMEの後半部が削除されている
- tsxでは、
package.json
とyarn.lock
に、typescript関連が追加されている - tsxでは、
tsconfig.json
が新規追加されている
publicフォルダ比較
$ diff --report-identical-files ./jsx-react-app/public/ ./tsx-react-app/public/
ファイル ./jsx-react-app/public/favicon.ico と ./tsx-react-app/public/favicon.ico は同一です
ファイル ./jsx-react-app/public/index.html と ./tsx-react-app/public/index.html は同一です
ファイル ./jsx-react-app/public/manifest.json と ./tsx-react-app/public/manifest.json は同一です
srcフォルダ比較
$ diff --brief --report-identical-files ./jsx-react-app/src/ ./tsx-react-app/src/
ファイル ./jsx-react-app/src/App.css と ./tsx-react-app/src/App.css は同一です
./jsx-react-app/src/ のみに存在: App.js
./jsx-react-app/src/ のみに存在: App.test.js
./tsx-react-app/src/ のみに存在: App.test.tsx
./tsx-react-app/src/ のみに存在: App.tsx
ファイル ./jsx-react-app/src/index.css と ./tsx-react-app/src/index.css は異なります
./jsx-react-app/src/ のみに存在: index.js
./tsx-react-app/src/ のみに存在: index.tsx
ファイル ./jsx-react-app/src/logo.svg と ./tsx-react-app/src/logo.svg は同一です
./tsx-react-app/src/ のみに存在: react-app-env.d.ts
./jsx-react-app/src/ のみに存在: serviceWorker.js
./tsx-react-app/src/ のみに存在: serviceWorker.ts
.jsファイルと.tsxファイル比較
$ diff --unified --report-identical-files ./jsx-react-app/src/App.js ./tsx-react-app/src/App.tsx
--- ./jsx-react-app/src/App.js 2019-03-23 20:42:45.877562453 +0900
+++ ./tsx-react-app/src/App.tsx 2019-03-23 20:41:53.565223301 +0900
@@ -9,7 +9,7 @@
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
- Edit <code>src/App.js</code> and save to reload.
+ Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
$ diff --unified --report-identical-files ./jsx-react-app/src/App.test.js ./tsx-react-app/src/App.test.tsx
ファイル ./jsx-react-app/src/App.test.js と ./tsx-react-app/src/App.test.tsx は同一です
$ diff --unified --report-identical-files ./jsx-react-app/src/index.js ./tsx-react-app/src/index.tsx
ファイル ./jsx-react-app/src/index.js と ./tsx-react-app/src/index.tsx は同一です
$ diff --unified --report-identical-files ./jsx-react-app/src/serviceWorker.js ./tsx-react-app/src/serviceWorker.ts
--- ./jsx-react-app/src/serviceWorker.js 2019-03-23 20:42:45.877562453 +0900
+++ ./tsx-react-app/src/serviceWorker.ts 2019-03-23 20:41:53.565223301 +0900
@@ -20,10 +20,18 @@
)
);
-export function register(config) {
+type Config = {
+ onSuccess?: (registration: ServiceWorkerRegistration) => void;
+ onUpdate?: (registration: ServiceWorkerRegistration) => void;
+};
+
+export function register(config?: Config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
+ const publicUrl = new URL(
+ (process as { env: { [key: string]: string } }).env.PUBLIC_URL,
+ window.location.href
+ );
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
@@ -54,7 +62,7 @@
}
}
-function registerValidSW(swUrl, config) {
+function registerValidSW(swUrl: string, config?: Config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
@@ -98,7 +106,7 @@
});
}
-function checkValidServiceWorker(swUrl, config) {
+function checkValidServiceWorker(swUrl: string, config?: Config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
また、react-app-env.d.ts
はtsxのみ
/// <reference types="react-scripts" />
感想
- React + TypeScriptは、まだまだこれから?
- Stateless Functional Component(SFC)はなくなった?
- Function Components(FC)ができた?
- 何か作って理解を深めよう
- TypeScriptを使いたいならAngular?
-
tsconfig.json
とは? -
react-app-env.d.ts
とは?
以上