use typescript

This commit is contained in:
Tao Bojlen 2018-08-27 14:07:32 +02:00
parent f2bd4e7fa7
commit 2757f18b57
13 changed files with 1264 additions and 907 deletions

View File

@ -213,12 +213,12 @@ In addition to [ES6](https://github.com/lukehoban/es6features) syntax features,
* [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017).
* [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal).
* [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal)
* [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (part of stage 3 proposal).
* [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (stage 2 proposal).
* [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax.
Learn more about [different proposal stages](https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-).
While we recommend using experimental proposals with some caution, Facebook heavily uses these features in the product code, so we intend to provide [codemods](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) if any of these proposals change in the future.
While we recommend to use experimental proposals with some caution, Facebook heavily uses these features in the product code, so we intend to provide [codemods](https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb) if any of these proposals change in the future.
Note that **the project only includes a few ES6 [polyfills](https://en.wikipedia.org/wiki/Polyfill)**:
@ -278,6 +278,7 @@ Then add the block below to your `launch.json` file and put it inside the `.vsco
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceRoot}/src",
"userDataDir": "${workspaceRoot}/.vscode/chrome",
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/*"
}
@ -288,8 +289,6 @@ Then add the block below to your `launch.json` file and put it inside the `.vsco
Start your app by running `npm start`, and start debugging in VS Code by pressing `F5` or by clicking the green debug icon. You can now write code, set breakpoints, make changes to the code, and debug your newly modified code—all from your editor.
Having problems with VS Code Debugging? Please see their [troubleshooting guide](https://github.com/Microsoft/vscode-chrome-debug/blob/master/README.md#troubleshooting).
### WebStorm
You would need to have [WebStorm](https://www.jetbrains.com/webstorm/) and [JetBrains IDE Support](https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji) Chrome extension installed.
@ -506,7 +505,7 @@ class Button extends Component {
}
```
**This is not required for React** but many people find this feature convenient. You can read about the benefits of this approach [here](https://medium.com/seek-blog/block-element-modifying-your-javascript-components-d7f99fcab52b). However you should be aware that this makes your code less portable to other build tools and environments than Webpack.
**This is not required for React** but many people find this feature convenient. You can read about the benefits of this approach [here](https://medium.com/seek-ui-engineering/block-element-modifying-your-javascript-components-d7f99fcab52b). However you should be aware that this makes your code less portable to other build tools and environments than Webpack.
In development, expressing dependencies this way allows your styles to be reloaded on the fly as you edit them. In production, all CSS files will be concatenated into a single minified `.css` file in the build output.
@ -614,12 +613,11 @@ Then we can change `start` and `build` scripts to include the CSS preprocessor c
"scripts": {
"build-css": "node-sass-chokidar src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
- "start": "react-scripts start",
- "build": "react-scripts build",
+ "start-js": "react-scripts start",
- "start": "react-scripts-ts start",
- "build": "react-scripts-ts build",
+ "start-js": "react-scripts-ts start",
+ "start": "npm-run-all -p watch-css start-js",
+ "build-js": "react-scripts build",
+ "build": "npm-run-all build-css build-js",
+ "build": "npm run build-css && react-scripts-ts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
@ -643,15 +641,32 @@ Now running `npm start` and `npm run build` also builds Sass files.
With Webpack, using static assets like images and fonts works similarly to CSS.
You can **`import` a file right in a JavaScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF.
You can **`import` a file right in a TypeScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF.
To reduce the number of requests to the server, importing images that are less than 10,000 bytes returns a [data URI](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) instead of a path. This applies to the following file extensions: bmp, gif, jpg, jpeg, and png. SVG files are excluded due to [#1153](https://github.com/facebookincubator/create-react-app/issues/1153).
Here is an example:
Before getting started, you must define each type of asset as a valid module format. Otherwise, the TypeScript compiler will generate an error like this:
>Cannot find module './logo.png'.
To import asset files in TypeScript, create a new type definition file in your project, and name it something like `assets.d.ts`. Then, add a line for each type of asset that you need to import:
```ts
declare module "*.gif";
declare module "*.jpg";
declare module "*.jpeg";
declare module "*.png";
declare module "*.svg";
```
(you'll have to restart the compiler in order the changes to take place)
In this case, we've added several image file extensions as valid module formats.
Now that the compiler is configured, here is an example of importing an image file:
```js
import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image
import logo from './logo.svg'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
@ -957,7 +972,7 @@ REACT_APP_SECRET_CODE=abcdef
`.env` files **should be** checked into source control (with the exclusion of `.env*.local`).
#### What other `.env` files can be used?
#### What other `.env` files are can be used?
>Note: this feature is **available with `react-scripts@1.0.0` and higher**.
@ -1062,7 +1077,7 @@ To tell the development server to proxy any unknown requests to your API server
"proxy": "http://localhost:4000",
```
This way, when you `fetch('/api/todos')` in development, the development server will recognize that its not a static asset, and will proxy your request to `http://localhost:4000/api/todos` as a fallback. The development server will **only** attempt to send requests without `text/html` in its `Accept` header to the proxy.
This way, when you `fetch('/api/todos')` in development, the development server will recognize that its not a static asset, and will proxy your request to `http://localhost:4000/api/todos` as a fallback. The development server will only attempt to send requests without a `text/html` accept header to the proxy.
Conveniently, this avoids [CORS issues](http://stackoverflow.com/questions/21854516/understanding-ajax-cors-and-security-considerations) and error messages like this in development:
@ -1128,7 +1143,7 @@ You may also specify any configuration value [`http-proxy-middleware`](https://g
All requests matching this path will be proxies, no exceptions. This includes requests for `text/html`, which the standard `proxy` option does not proxy.
If you need to specify multiple proxies, you may do so by specifying additional entries.
Matches are regular expressions, so that you can use a regexp to match multiple paths.
You may also narrow down matches using `*` and/or `**`, to match the path exactly or any subpath.
```js
{
// ...
@ -1149,12 +1164,12 @@ Matches are regular expressions, so that you can use a regexp to match multiple
// ...
},
// Matches /bar/abc.html but not /bar/sub/def.html
"/bar/[^/]*[.]html": {
"/bar/*.html": {
"target": "<url_3>",
// ...
},
// Matches /baz/abc.html and /baz/sub/def.html
"/baz/.*/.*[.]html": {
"/baz/**/*.html": {
"target": "<url_4>"
// ...
}
@ -1241,7 +1256,7 @@ If you use a Node server, you can even share the route matching logic between th
## Pre-Rendering into Static HTML Files
If youre hosting your `build` with a static hosting provider you can use [react-snapshot](https://www.npmjs.com/package/react-snapshot) or [react-snap](https://github.com/stereobooster/react-snap) to generate HTML pages for each route, or relative link, in your application. These pages will then seamlessly become active, or “hydrated”, when the JavaScript bundle has loaded.
If youre hosting your `build` with a static hosting provider you can use [react-snapshot](https://www.npmjs.com/package/react-snapshot) to generate HTML pages for each route, or relative link, in your application. These pages will then seamlessly become active, or “hydrated”, when the JavaScript bundle has loaded.
There are also opportunities to use this outside of static hosting, to take the pressure off the server when generating and caching routes.
@ -1320,8 +1335,8 @@ it('sums numbers', () => {
});
```
All `expect()` matchers supported by Jest are [extensively documented here](https://facebook.github.io/jest/docs/en/expect.html#content).<br>
You can also use [`jest.fn()` and `expect(fn).toBeCalled()`](https://facebook.github.io/jest/docs/en/expect.html#tohavebeencalled) to create “spies” or mock functions.
All `expect()` matchers supported by Jest are [extensively documented here](http://facebook.github.io/jest/docs/expect.html).<br>
You can also use [`jest.fn()` and `expect(fn).toBeCalled()`](http://facebook.github.io/jest/docs/expect.html#tohavebeencalled) to create “spies” or mock functions.
### Testing Components
@ -1329,9 +1344,9 @@ There is a broad spectrum of component testing techniques. They range from a “
Different projects choose different testing tradeoffs based on how often components change, and how much logic they contain. If you havent decided on a testing strategy yet, we recommend that you start with creating simple smoke tests for your components:
```js
import React from 'react';
import ReactDOM from 'react-dom';
```ts
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
@ -1340,40 +1355,36 @@ it('renders without crashing', () => {
});
```
This test mounts a component and makes sure that it didnt throw during rendering. Tests like this provide a lot of value with very little effort so they are great as a starting point, and this is the test you will find in `src/App.test.js`.
This test mounts a component and makes sure that it didnt throw during rendering. Tests like this provide a lot of value with very little effort so they are great as a starting point, and this is the test you will find in `src/App.test.tsx`.
When you encounter bugs caused by changing components, you will gain a deeper insight into which parts of them are worth testing in your application. This might be a good time to introduce more specific tests asserting specific expected output or behavior.
If youd like to test components in isolation from the child components they render, we recommend using [`shallow()` rendering API](http://airbnb.io/enzyme/docs/api/shallow.html) from [Enzyme](http://airbnb.io/enzyme/). To install it, run:
```sh
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
npm install --save-dev enzyme @types/enzyme enzyme-adapter-react-16 @types/enzyme-adapter-react-16 react-test-renderer @types/react-test-renderer
```
Alternatively you may use `yarn`:
```sh
yarn add enzyme enzyme-adapter-react-16 react-test-renderer
yarn add --dev enzyme @types/enzyme enzyme-adapter-react-16 @types/enzyme-adapter-react-16 react-test-renderer @types/react-test-renderer
```
As of Enzyme 3, you will need to install Enzyme along with an Adapter corresponding to the version of React you are using. (The examples above use the adapter for React 16.)
#### `src/setupTests.ts`
```ts
import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
The adapter will also need to be configured in your [global setup file](#initializing-test-environment):
#### `src/setupTests.js`
```js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
Enzyme.configure({ adapter: new Adapter() });
```
>Note: Keep in mind that if you decide to "eject" before creating `src/setupTests.js`, the resulting `package.json` file won't contain any reference to it. [Read here](#initializing-test-environment) to learn how to add this after ejecting.
Now you can write a smoke test with it:
```js
import React from 'react';
```ts
import * as React from 'react';
import { shallow } from 'enzyme';
import App from './App';
@ -1388,8 +1399,8 @@ You can read the [Enzyme documentation](http://airbnb.io/enzyme/) for more testi
Here is an example from Enzyme documentation that asserts specific output, rewritten to use Jest matchers:
```js
import React from 'react';
```ts
import * as React from 'react';
import { shallow } from 'enzyme';
import App from './App';
@ -1401,7 +1412,7 @@ it('renders welcome message', () => {
});
```
All Jest matchers are [extensively documented here](http://facebook.github.io/jest/docs/en/expect.html).<br>
All Jest matchers are [extensively documented here](http://facebook.github.io/jest/docs/expect.html).<br>
Nevertheless you can use a third-party assertion library like [Chai](http://chaijs.com/) if you want to, as described below.
Additionally, you might find [jest-enzyme](https://github.com/blainekasten/enzyme-matchers) helpful to simplify your tests with readable matchers. The above `contains` code can be written more simply with jest-enzyme.
@ -1422,54 +1433,12 @@ Alternatively you may use `yarn`:
yarn add jest-enzyme
```
Import it in [`src/setupTests.js`](#initializing-test-environment) to make its matchers available in every test:
Import it in [`src/setupTests.ts`](#initializing-test-environment) to make its matchers available in every test:
```js
import 'jest-enzyme';
```
#### Use `react-testing-library`
As an alternative or companion to `enzyme`, you may consider using `react-testing-library`. [`react-testing-library`](https://github.com/kentcdodds/react-testing-library) is a library for testing React components in a way that resembles the way the components are used by end users. It is well suited for unit, integration, and end-to-end testing of React components and applications. It works more directly with DOM nodes, and therefore it's recommended to use with [`jest-dom`](https://github.com/gnapse/jest-dom) for improved assertions.
To install `react-testing-library` and `jest-dom`, you can run:
```sh
npm install --save react-testing-library jest-dom
```
Alternatively you may use `yarn`:
```sh
yarn add react-testing-library jest-dom
```
Similar to `enzyme` you can create a `src/setupTests.js` file to avoid boilerplate in your test files:
```js
// react-testing-library renders your components to document.body,
// this will ensure they're removed after each test.
import 'react-testing-library/cleanup-after-each';
// this adds jest-dom's custom assertions
import 'jest-dom/extend-expect';
```
Here's an example of using `react-testing-library` and `jest-dom` for testing that the `<App />` component renders "Welcome to React".
```js
import React from 'react';
import { render } from 'react-testing-library';
import App from './App';
it('renders welcome message', () => {
const { getByText } = render(<App />);
expect(getByText('Welcome to React')).toBeInTheDOM();
});
```
Learn more about the utilities provided by `react-testing-library` to facilitate testing asynchronous interactions as well as selecting form elements from [the `react-testing-library` documentation](https://github.com/kentcdodds/react-testing-library) and [examples](https://codesandbox.io/s/github/kentcdodds/react-testing-library-examples).
### Using Third Party Assertion Libraries
We recommend that you use `expect()` for assertions and `jest.fn()` for spies. If you are having issues with them please [file those against Jest](https://github.com/facebook/jest/issues/new), and well fix them. We intend to keep making them better for React, supporting, for example, [pretty-printing React elements as JSX](https://github.com/facebook/jest/pull/1566).
@ -1487,12 +1456,12 @@ and then use them in your tests like you normally do.
>Note: this feature is available with `react-scripts@0.4.0` and higher.
If your app uses a browser API that you need to mock in your tests or if you just need a global setup before running your tests, add a `src/setupTests.js` to your project. It will be automatically executed before running your tests.
If your app uses a browser API that you need to mock in your tests or if you just need a global setup before running your tests, add a `src/setupTests.ts` to your project. It will be automatically executed before running your tests.
For example:
#### `src/setupTests.js`
```js
#### `src/setupTests.ts`
```ts
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
@ -1533,6 +1502,7 @@ Supported overrides:
- [`coverageReporters`](https://facebook.github.io/jest/docs/en/configuration.html#coveragereporters-array-string)
- [`coverageThreshold`](https://facebook.github.io/jest/docs/en/configuration.html#coveragethreshold-object)
- [`snapshotSerializers`](https://facebook.github.io/jest/docs/en/configuration.html#snapshotserializers-array-string)
- [`moduleNameMapper`](https://facebook.github.io/jest/docs/en/configuration.html#modulenamemapper-object-string-string)
Example package.json:
@ -1554,11 +1524,16 @@ Example package.json:
}
},
"coverageReporters": ["text"],
"snapshotSerializers": ["my-serializer-module"]
"snapshotSerializers": ["my-serializer-module"],
"moduleNameMapper": {
"^~/(.*)$": "<rootDir>/src/$1"
}
}
}
```
Note that customizing the `moduleNameMapper` configuration will override the default (`{ '^react-native$': 'react-native-web' }`).
### Continuous Integration
By default `npm test` runs the watcher with interactive CLI. However, you can force it to run tests once and finish the process by setting an environment variable called `CI`.
@ -1825,7 +1800,7 @@ By default, the production build is a fully functional, offline-first
Progressive Web Apps are faster and more reliable than traditional web pages, and provide an engaging mobile experience:
* All static site assets are cached so that your page loads fast on subsequent visits, regardless of network connectivity (such as 2G or 3G). Updates are downloaded in the background.
* Your app will work regardless of network state, even if offline. This means your users will be able to use your app at 10,000 feet and on the subway.
* Your app will work regardless of network state, even if offline. This means your users will be able to use your app at 10,000 feet and on the Subway.
* On mobile devices, your app can be added directly to the user's home screen, app icon and all. You can also re-engage users using web **push notifications**. This eliminates the need for the app store.
The [`sw-precache-webpack-plugin`](https://github.com/goldhand/sw-precache-webpack-plugin)
@ -1839,18 +1814,14 @@ that your web app is reliably fast, even on a slow or unreliable network.
### Opting Out of Caching
If you would prefer not to enable service workers prior to your initial
production deployment, then remove the call to `registerServiceWorker()`
production deployment, then remove the call to `serviceWorkerRegistration.register()`
from [`src/index.js`](src/index.js).
If you had previously enabled service workers in your production deployment and
have decided that you would like to disable them for all your existing users,
you can swap out the call to `registerServiceWorker()` in
[`src/index.js`](src/index.js) first by modifying the service worker import:
```javascript
import { unregister } from './registerServiceWorker';
```
and then call `unregister()` instead.
After the user visits a page that has `unregister()`,
you can swap out the call to `serviceWorkerRegistration.register()` in
[`src/index.js`](src/index.js) with a call to `serviceWorkerRegistration.unregister()`.
After the user visits a page that has `serviceWorkerRegistration.unregister()`,
the service worker will be uninstalled. Note that depending on how `/service-worker.js` is served,
it may take up to 24 hours for the cache to be invalidated.
@ -2046,12 +2017,6 @@ service worker navigation routing can be configured or disabled by
and [`navigateFallbackWhitelist`](https://github.com/GoogleChrome/sw-precache#navigatefallbackwhitelist-arrayregexp)
options of the `SWPreachePlugin` [configuration](../config/webpack.config.prod.js).
When users install your app to the homescreen of their device the default configuration will make a shortcut to `/index.html`. This may not work for client-side routers which expect the app to be served from `/`. Edit the web app manifest at [`public/manifest.json`](public/manifest.json) and change `start_url` to match the required URL scheme, for example:
```js
"start_url": ".",
```
### Building for Relative Paths
By default, Create React App produces a build assuming your app is hosted at the server root.<br>
@ -2084,13 +2049,14 @@ If you are not using the HTML5 `pushState` history API or not using client-side
This will make sure that all the asset paths are relative to `index.html`. You will then be able to move your app from `http://mywebsite.com` to `http://mywebsite.com/relativepath` or even `http://mywebsite.com/relative/path` without having to rebuild it.
### [Azure](https://azure.microsoft.com/)
### Azure
See [this](https://medium.com/@to_pe/deploying-create-react-app-on-microsoft-azure-c0f6686a4321) blog post on how to deploy your React app to Microsoft Azure.
See [this](https://medium.com/@to_pe/deploying-create-react-app-on-microsoft-azure-c0f6686a4321) blog post on how to deploy your React app to [Microsoft Azure](https://azure.microsoft.com/).
### Firebase
See [this](https://medium.com/@strid/host-create-react-app-on-azure-986bc40d5bf2#.pycfnafbg) blog post or [this](https://github.com/ulrikaugustsson/azure-appservice-static) repo for a way to use automatic deployment to Azure App Service.
### [Firebase](https://firebase.google.com/)
Install the Firebase CLI if you havent already by running `npm install -g firebase-tools`. Sign up for a [Firebase account](https://console.firebase.google.com/) and create a new project. Run `firebase login` and login with your previous created Firebase account.
@ -2163,7 +2129,7 @@ Now, after you create a production build with `npm run build`, you can deploy it
For more information see [Add Firebase to your JavaScript Project](https://firebase.google.com/docs/web/setup).
### [GitHub Pages](https://pages.github.com/)
### GitHub Pages
>Note: this feature is available with `react-scripts@0.2.0` and higher.
@ -2299,7 +2265,7 @@ remote: npm ERR! argv "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/
In this case, ensure that the file is there with the proper lettercase and thats not ignored on your local `.gitignore` or `~/.gitignore_global`.
### [Netlify](https://www.netlify.com/)
### Netlify
**To do a manual deploy to Netlifys CDN:**
@ -2329,9 +2295,9 @@ To support `pushState`, make sure to create a `public/_redirects` file with the
When you build the project, Create React App will place the `public` folder contents into the build output.
### [Now](https://zeit.co/now)
### Now
Now offers a zero-configuration single-command deployment. You can use `now` to deploy your app for free.
[now](https://zeit.co/now) offers a zero-configuration single-command deployment. You can use `now` to deploy your app for free.
1. Install the `now` command-line tool either via the recommended [desktop tool](https://zeit.co/download) or via node with `npm install -g now`.
@ -2349,11 +2315,11 @@ Now offers a zero-configuration single-command deployment. You can use `now` to
Details are available in [this article.](https://zeit.co/blog/unlimited-static)
### [S3](https://aws.amazon.com/s3) and [CloudFront](https://aws.amazon.com/cloudfront/)
### S3 and CloudFront
See this [blog post](https://medium.com/@omgwtfmarc/deploying-create-react-app-to-s3-or-cloudfront-48dae4ce0af) on how to deploy your React app to Amazon Web Services S3 and CloudFront.
See this [blog post](https://medium.com/@omgwtfmarc/deploying-create-react-app-to-s3-or-cloudfront-48dae4ce0af) on how to deploy your React app to Amazon Web Services [S3](https://aws.amazon.com/s3) and [CloudFront](https://aws.amazon.com/cloudfront/).
### [Surge](https://surge.sh/)
### Surge
Install the Surge CLI if you havent already by running `npm install -g surge`. Run the `surge` command and log in you or create a new account.
@ -2463,16 +2429,12 @@ This will only work for locales that have been explicitly imported before.
### `npm run build` fails to minify
Some third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.
You may occasionally find a package you depend on needs compiled or ships code for a non-browser environment.<br>
This is considered poor practice in the ecosystem and does not have an escape hatch in Create React App.<br>
<br>
To resolve this:
1. Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled.
* Note: Create React App can consume both CommonJS and ES modules. For Node.js compatibility, it is recommended that the main entry point is CommonJS. However, they can optionally provide an ES module entry point with the `module` field in `package.json`. Note that **even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers**.
2. Fork the package and publish a corrected version yourself.
1. Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled (retaining ES6 Modules).
2. Fork the package and publish a corrected version yourself.
3. If the dependency is small enough, copy it to your `src/` folder and treat it as application code.
In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds.

3
frontend/images.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
declare module '*.svg'
declare module '*.png'
declare module '*.jpg'

View File

@ -5,12 +5,19 @@
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-scripts": "1.1.5"
"react-scripts-ts": "2.17.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
},
"devDependencies": {
"@types/jest": "^23.3.1",
"@types/node": "^10.9.2",
"@types/react": "^16.4.12",
"@types/react-dom": "^16.0.7",
"typescript": "^3.0.1"
}
}
}

View File

@ -1,5 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {

View File

@ -1,9 +1,10 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import * as React from 'react';
import './App.css';
class App extends Component {
render() {
import logo from './logo.svg';
class App extends React.Component {
public render() {
return (
<div className="App">
<header className="App-header">
@ -11,7 +12,7 @@ class App extends Component {
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
To get started, edit <code>src/App.tsx</code> and save to reload.
</p>
</div>
);

View File

@ -1,8 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

11
frontend/src/index.tsx Normal file
View File

@ -0,0 +1,11 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<App />,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();

View File

@ -1,8 +1,9 @@
// tslint:disable:no-console
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// will only see deployed updates on the 'N+1' visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
@ -21,7 +22,10 @@ const isLocalhost = Boolean(
export default function register() {
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);
const publicUrl = new URL(
process.env.PUBLIC_URL!,
window.location.toString()
);
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
@ -52,28 +56,30 @@ export default function register() {
}
}
function registerValidSW(swUrl) {
function registerValidSW(swUrl: string) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
if (installingWorker) {
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a 'New content is
// available; please refresh.' message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// 'Content is cached for offline use.' message.
console.log('Content is cached for offline use.');
}
}
}
};
};
}
};
})
.catch(error => {
@ -81,14 +87,14 @@ function registerValidSW(swUrl) {
});
}
function checkValidServiceWorker(swUrl) {
function checkValidServiceWorker(swUrl: string) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
response.headers.get('content-type')!.indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {

30
frontend/tsconfig.json Normal file
View File

@ -0,0 +1,30 @@
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "build",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}

View File

@ -0,0 +1,3 @@
{
"extends": "./tsconfig.json"
}

View File

@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}

10
frontend/tslint.json Normal file
View File

@ -0,0 +1,10 @@
{
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts",
"coverage/lcov-report/*.js"
]
}
}

File diff suppressed because it is too large Load Diff