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

Commit

Permalink
Merge pull request #220 from wmonk/2.9.0
Browse files Browse the repository at this point in the history
2.9.0
  • Loading branch information
wmonk authored Jan 13, 2018
2 parents 2c25d89 + cc52d21 commit 4786bec
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 30 deletions.
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';
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

0 comments on commit 4786bec

Please sign in to comment.