Skip to content
This repository has been archived by the owner on Jan 26, 2019. It is now read-only.

2.9.0 #220

Merged
merged 5 commits into from
Jan 13, 2018
Merged

2.9.0 #220

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Create React apps (with Typescript) with no build configuration.

* [Getting Started](#tldr) – How to create a new app.
* [User Guide](https://github.com/wmonk/create-react-app-typescript/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with react scripts ts.

_Do you know react and want to try out typescript? Or do you know typescript and want to try out react?_ Get all the benefits from `create-react-app` but you use typescript! 🚀

## tl;dr
Expand Down
10 changes: 6 additions & 4 deletions packages/react-scripts/config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const getPublicUrl = appPackageJson =>
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
function getServedPath(appPackageJson) {
const publicUrl = getPublicUrl(appPackageJson);
const servedUrl =
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
const servedUrl = envPublicUrl ||
(publicUrl ? url.parse(publicUrl).pathname : '/');
return ensureSlash(servedUrl, true);
}

Expand All @@ -61,6 +61,7 @@ module.exports = {
testsSetup: resolveApp('src/setupTests.ts'),
appNodeModules: resolveApp('node_modules'),
appTsConfig: resolveApp('tsconfig.json'),
appTsLint: resolveApp('tslint.json'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
};
Expand All @@ -83,6 +84,7 @@ module.exports = {
appNodeModules: resolveApp('node_modules'),
appTsConfig: resolveApp('tsconfig.json'),
appTsTestConfig: resolveApp('tsconfig.test.json'),
appTsLint: resolveApp('tslint.json'),
publicUrl: getPublicUrl(resolveApp('package.json')),
servedPath: getServedPath(resolveApp('package.json')),
// These properties only exist before ejecting:
Expand All @@ -92,8 +94,7 @@ module.exports = {

const ownPackageJson = require('../package.json');
const reactScriptsPath = resolveApp(`node_modules/${ownPackageJson.name}`);
const reactScriptsLinked =
fs.existsSync(reactScriptsPath) &&
const reactScriptsLinked = fs.existsSync(reactScriptsPath) &&
fs.lstatSync(reactScriptsPath).isSymbolicLink();

// config before publish: we're in ./packages/react-scripts/config/
Expand All @@ -114,6 +115,7 @@ if (
testsSetup: resolveOwn('template/src/setupTests.ts'),
appNodeModules: resolveOwn('node_modules'),
appTsConfig: resolveOwn('template/tsconfig.json'),
appTsLint: resolveOwn('template/tslint.json'),
appTsTestConfig: resolveOwn('template/tsconfig.test.json'),
publicUrl: getPublicUrl(resolveOwn('package.json')),
servedPath: getServedPath(resolveOwn('package.json')),
Expand Down
26 changes: 17 additions & 9 deletions packages/react-scripts/config/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const getClientEnvironment = require('./env');
const paths = require('./paths');

Expand Down Expand Up @@ -134,14 +135,6 @@ module.exports = {
// We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
// { parser: { requireEnsure: false } },

// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(ts|tsx)$/,
loader: require.resolve('tslint-loader'),
enforce: 'pre',
include: paths.appSrc,
},
{
test: /\.js$/,
loader: require.resolve('source-map-loader'),
Expand All @@ -168,7 +161,15 @@ module.exports = {
{
test: /\.(ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('ts-loader'),
use: [
{
loader: require.resolve('ts-loader'),
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true,
},
},
],
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
Expand Down Expand Up @@ -262,6 +263,13 @@ module.exports = {
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// Perform type checking and linting in a separate process to speed up compilation
new ForkTsCheckerWebpackPlugin({
async: false,
watch: paths.appSrc,
tsconfig: paths.appTsConfig,
tslint: paths.appTsLint,
}),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
Expand Down
20 changes: 17 additions & 3 deletions packages/react-scripts/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const paths = require('./paths');
const getClientEnvironment = require('./env');

Expand Down Expand Up @@ -137,7 +138,6 @@ module.exports = {
// TODO: Disable require.ensure as it's not a standard language feature.
// We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.
// { parser: { requireEnsure: false } },

// First, run the linter.
// It's important to do this before Typescript runs.
{
Expand Down Expand Up @@ -167,11 +167,19 @@ module.exports = {
name: 'static/media/[name].[hash:8].[ext]',
},
},
//Compile .tsx?
// Compile .tsx?
{
test: /\.(ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('ts-loader')
use: [
{
loader: require.resolve('ts-loader'),
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true,
},
},
],
},
// The notation here is somewhat confusing.
// "postcss" loader applies autoprefixer to our CSS.
Expand Down Expand Up @@ -341,6 +349,12 @@ module.exports = {
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// Perform type checking and linting in a separate process to speed up compilation
new ForkTsCheckerWebpackPlugin({
async: false,
tsconfig: paths.appTsConfig,
tslint: paths.appTsLint,
}),
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
Expand Down
2 changes: 2 additions & 0 deletions packages/react-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"dotenv": "4.0.0",
"extract-text-webpack-plugin": "3.0.0",
"file-loader": "0.11.2",
"fork-ts-checker-webpack-plugin": "^0.2.8",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"jest": "20.0.4",
Expand Down Expand Up @@ -59,3 +60,4 @@
"fsevents": "1.1.2"
}
}

36 changes: 22 additions & 14 deletions packages/react-scripts/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1244,9 +1244,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 haven’t 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 * asReactDOM from 'react-dom';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space missing

import App from './App';

it('renders without crashing', () => {
Expand All @@ -1255,26 +1255,34 @@ it('renders without crashing', () => {
});
```

This test mounts a component and makes sure that it didn’t throw during rendering. Tests like this provide a lot 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 didn’t throw during rendering. Tests like this provide a lot 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 you’d 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 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 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
```

#### `src/setupTests.ts`
```ts
import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });
```

You can write a smoke test with it too:

```js
import React from 'react';
```ts
import * as React from 'react';
import { shallow } from 'enzyme';
import App from './App';

Expand All @@ -1289,8 +1297,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';

Expand Down Expand Up @@ -1323,7 +1331,7 @@ 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';
Expand All @@ -1346,12 +1354,12 @@ and then use them in your tests like you normally do.

>Note: this feature is available with `[email protected]` 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(),
Expand Down