React + TypeScript + Sass + Jest + Enzyme + Prettierを使うためにwebpackで環境構築

Typescript + Reactで開発したい！！テストもしたいしSassでバリバリデザインもしたい!!pretterで楽をしたい!!と思い、Todoアプリのサンプルを作ってみました。

## 構成


ファイル構成はこんな感じ。

```
├── README.md
├── dist
│   ├── index.css
│   ├── index.html
│   ├── main.bundle.js
│   └── main.bundle.js.map
├── package-lock.json
├── package.json
├── public
│   └── index.html
├── src
│   ├── __test__
│   │   ├── App.test.tsx
│   │   ├── Todo.test.tsx
│   │   └── addTodo.test.tsx
│   ├── components
│   │   ├── AddTodo.tsx
│   │   ├── App.tsx
│   │   ├── Todo.tsx
│   │   └── functions
│   │       └── handleAddTodo.ts
│   ├── index.tsx
│   ├── setupEnzyme.ts
│   └── stylesheets
│       └── style.scss
├── tsconfig.json
├── tslint.json
├── webpack.config.js
└── yarn.lock
```

Appが親のコンポーネントで関数はfunctionsにまとめています。

[サンプルコードはこちらから](https://github.com/yoshimoto8/sample-react-typescript)

### package.json

```js
{
  "name": "setuptypescript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --open",
    "tslint-check": "tslint-config-prettier-check ./tslint.json",
    "build": "webpack --watch --config webpack.config.js",
    "test": "jest"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/enzyme": "^3.1.10",
    "@types/jest": "^23.1.0",
    "awesome-typescript-loader": "^5.0.0",
    "css-loader": "^0.28.11",
    "enzyme": "^3.3.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "jest": "^23.1.0",
    "node-sass": "^4.9.0",
    "prettier": "1.13.5",
    "react-test-renderer": "^16.4.1",
    "sass-loader": "^7.0.3",
    "style-loader": "^0.21.0",
    "ts-jest": "^22.4.6",
    "tslint-config-prettier": "^1.13.0",
    "tslint-plugin-prettier": "^1.3.0",
    "typescript": "^2.9.1",
    "url-loader": "^1.0.1",
    "webpack": "^4.12.0",
    "webpack-cli": "^3.0.3"
  },
  "dependencies": {
    "@types/enzyme-adapter-react-16": "^1.0.2",
    "@types/react": "^16.3.17",
    "@types/react-dom": "^16.0.6",
    "enzyme-adapter-react-16": "^1.1.1",
    "react": "^16.4.0",
    "react-dom": "^16.4.0",
    "webpack-dev-server": "^3.1.4"
  },
  "jest": {
    "transform": {
      ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  }
}
```

`npm install`して`yarn start`を打ち込むとサーバが起動したり、`yarn test`を打ち込むとテストを実行することができます。

### webpack.config.js

```js
const path = require('path');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const MODE = 'development'

module.exports = [{
    mode: MODE,
    entry: './src/index.tsx',
    output: {
        filename: "[name].bundle.js",
        path: path.resolve(__dirname, 'dist'),
    },
    devtool: 'source-map', 
    resolve: {
      extensions: ['.js', '.json', '.ts', '.tsx'],
    },
    devServer: {
      contentBase: './dist', 
      inline: true,
      host: 'localhost',
      port: 8081,
      stats: 'errors-only'
    },
    module: {
      rules: [
        {
          test: /\.(ts|tsx)$/,
          loader: "awesome-typescript-loader"
        },
        {
          test: /\.(gif|png|jpg)$/,
          loader: 'url-loader'
        }
      ]
    },
  },
  {
    mode: MODE,
    entry: {
      style: './src/stylesheets/style.scss'
    },
    output: {
      path: `${__dirname}/dist`,
      filename: 'index.css'
    },
    module: {
      rules: [
        {
          test: /\.scss$/,
          loader:  ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: ['css-loader', 'sass-loader']
          })
        }
      ]
    },
    plugins: [
      new ExtractTextPlugin('index.css'),
    ],
  }
];
```

### tsconfig.json

```json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "jsx": "react",
    "module": "ESNext",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": ["node_modules"]
}

```

typescriptをコンパイルする時に使う設定ファイルです。こちらはほぼ公式ドキュメントを参考にしています。



### .prettierrc と　tslint.json

```json
//.prettierrc
{
  "printWidth": 79,
  "singleQuote": true
}
```
```json
//tslint.json
{
  "extends": ["tslint-react", "tslint-config-prettier"],
  "rulesDirectory": ["tslint-plugin-prettier"],
  "rules": {
    "prettier": true
  }
}
```

こちらはPrettierとtslintを組み合わせて自動整形してくれるように設定していましす。(vscodeがおすすめです。)

## 参照

https://codeburst.io/webpack-typescript-react-part-1-dc154e250f23