React & Webpack & TypeScript を使ってみる


**【自分用の覚書】**　
#React & Webpack & TypeScript を使ってみる

参考にしたページ : [React & Webpack](https://www.typescriptlang.org/docs/handbook/react-&-webpack.html)

```PowerShell:PowerShell
PS C:\Users\Taro\Desktop> mkdir ws


    ディレクトリ: C:\Users\Taro\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/05/10     14:18                ws


PS C:\Users\Taro\Desktop> cd ws
PS C:\Users\Taro\Desktop\ws> mkdir src,dist


    ディレクトリ: C:\Users\Taro\Desktop\ws


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/05/10     14:18                src
d-----       2018/05/10     14:18                dist


PS C:\Users\Taro\Desktop\ws> mkdir src\components


    ディレクトリ: C:\Users\Taro\Desktop\ws\src


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/05/10     14:18                components


PS C:\Users\Taro\Desktop\ws> npm init -y
Wrote to C:\Users\Taro\Desktop\ws\package.json:

{
  "name": "ws",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


PS C:\Users\Taro\Desktop\ws> npm i -D typescript ts-loader  source-map-loader
npm notice created a lockfile as package-lock.json. You should commit this file.                                                                                                     3f564ec by content address 569ms
npm WARN ws@1.0.0 No description
npm WARN ws@1.0.0 No repository field.

+ source-map-loader@0.2.3
+ ts-loader@4.3.0
+ typescript@2.8.3
added 145 packages in 3.675s
PS C:\Users\Taro\Desktop\ws> npm install --save react react-dom @types/react @types/react-dom
npm WARN ws@1.0.0 No description                                                                                                                                                     content address 289ms
npm WARN ws@1.0.0 No repository field.

+ react-dom@16.3.2
+ react@16.3.2
+ @types/react-dom@16.0.5
+ @types/react@16.3.14
added 22 packages in 3.067s
PS C:\Users\Taro\Desktop\ws> npm install -g webpack
C:\Users\Taro\AppData\Roaming\npm\webpack -> C:\Users\Taro\AppData\Roaming\npm\node_modules\webpack\bin\webpack.js                                                                   tream
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.3 (node_modules\webpack\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ webpack@4.8.1
updated 1 package in 9.505s
PS C:\Users\Taro\Desktop\ws> tsc --init
message TS6071: Successfully created a tsconfig.json file.
PS C:\Users\Taro\Desktop\ws>  New-Item webpack.config.js


    ディレクトリ: C:\Users\Taro\Desktop\ws


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2018/05/10     14:20              0 webpack.config.js


PS C:\Users\Taro\Desktop\ws> code .
```
`tsconfig.json`を編集

```JSON:tsconfig.json
{
  "compilerOptions": {
    "target": "es5", 
    "module": "commonjs",
    "jsx": "react", 
    "sourceMap": true, 
    "outDir": "./dist/", 
    "strict": true, 
    "noImplicitAny": true, 
    "esModuleInterop": true 
  },
  "include": [
    "./src/**/*"
  ]
}
```


##ファイル作成

```TypeScript:.src\components\hello.tsx
import * as React from "react";

export interface HelloProps { compiler: string; framework: string; }

export const Hello = (props: HelloProps) => <h1> {props.compiler} と {props.framework} から、こんにちは</h1>;
```


```TypeScript:.src\index.tsx
import * as React from "react";
import * as ReactDOM from "react-dom";

import { Hello } from "./components/Hello";

ReactDOM.render(
    <Hello compiler="TypeScript" framework="React" />,
    document.getElementById("example")
);
```
```html:.\index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>こんにちは React </title>
    </head>
    <body>
        <div id="example"></div>

        <!-- Dependencies -->
        <script src="./node_modules/react/umd/react.development.js"></script>
        <script src="./node_modules/react-dom/umd/react-dom.development.js"></script>

        <!-- Main -->
        <script src="./dist/bundle.js"></script>
    </body>
</html>
```
##Webpack

`webpack.config.js`の作成、編集

```webpack.config.js:webpack.config.js
module.exports = {
    mode: 'production', 
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",
    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "ts-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    },
};
```
webpackコマンド実行

```PowerShell:PowerShell
PS C:\Users\Taro\Desktop\ws> webpack
Hash: ab4ac28e3a715a865169
Version: webpack 4.8.1
Time: 1277ms
Built at: 2018-05-10 14:30:55
        Asset      Size  Chunks             Chunk Names
    bundle.js  1.36 KiB       0  [emitted]  main
bundle.js.map  4.17 KiB       0  [emitted]  main
Entrypoint main = bundle.js bundle.js.map
[0] external "React" 42 bytes {0} [built]
[2] external "ReactDOM" 42 bytes {0} [built]
[3] ./src/index.tsx 649 bytes {0} [built]
    + 1 hidden module
```
ブラウザでindex.htmlを開いて確かめる。