JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その2)

前回は、VSCode、Node.js、yarnの導入までをしました。
今回は、フォルダ構成、初期ファイル配置、babel、webpack、webpack-dev-serverの導入までをします。

# ワークスペースの作成
VCだとプロジェクトでしょうか。

ワークスペース全体のフォルダ(例：myproject)を作ります。
フォルダを作ったら、VSCodeを起動し、左ペインから「フォルダーを開く」から開きます。
ファイル->ワークスペースを保存を開き、ワークスペースを保存します。
私はよくわからないので、作ったmyprojectフォルダ内に、プロジェクト名(myproject)でワークスペースファイルを保存しました。(myproject.code-workspace)

# ワークスペースの初期設定(package.jsonの作成)
F1キーでクイックオープンからYarn: Initialize Yarn Packageを実行します。
色々入力を聞かれますが、すべてEnterでOKです。

以下のようなフォルダ構成になりました。
package.jsonはVCでのプロジェクトファイルのような感じですかね。

```フォルダ構成
myproject
 ├myproject.code-workspace
 └package.json
```

# フォルダ構成
以下のようなフォルダを作っておきます。
参考：https://saitoxu.io/2017/03/20/es6-tutorial.html

```フォルダ構成
myproject
 ├dist
 ├lib
 ├src
 ├myproject.code-workspace
 └package.json
```

`dist`がwebで実行用、`lib`がnodeで実行用、`src`はソースコードになっています。
こんな使い方をする人はいないようですが、あちこち調べているうちにこうなりました。
JavaScript初心者の私には意外と便利だったりします。

srcでコードを書き、babelでトランスパイルしたものをlibに出し、nodeで実行します。
ブラウザなしで動作確認できます。(console.log()も出力してくれます)
ただし、windowやdocument(DOM)はないため、動作しないっぽいです。
window

ブラウザを通して実行する場合には、webpack + babelでトランスパイルしたものをdistに出し、webpack-dev-serverでhtmlから読みながら動作させ、逐次修正できるようです(まだ、やっていません)。
windowやdocument(DOM)の動作はこちらで確認ですね。
VSCodeでデバッグするにはsource-map(VCでのシンボルファイルだと思う)が必要で、これはwebpackのオプションで作成します(詳細は別途)。

# index.htmlの作成
ブラウザを通して確認する場合の、index.htmlを`dist`に作成します。
Bundle(コンパイル)後のファイルはmain.jsとします。
distにできたmain.jsを参照して動作するイメージです。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>

  <body>
    <script src="main.js"></script>
  </body>
</html>
```

index.html内のscript呼び出しは、とりあえず最低限にしておきます。
dllmainっぽいです。

動作確認用にmain.jsを追加します。
distにファイルを新規作成し、以下を記載します。

```html:main.js
window.document.write("Hello JS World!");
```

この状態で、index.htmlをブラウザで開くと、「Hello JS World!」と表示されています。
VSCodeのmarketplaceで、View in Browserをインストールしておくと、index.htmlファイルを右クリックし「View in Browser」からブラウザ表示できます！

```フォルダ構成
myproject
 ├dist
 │  ├index.html
 │  └main.js
 ├lib
 ├src
 ├myproject.code-workspace
 └package.json
```

# babelのインストール
トランスパイル(ソースコードの.jsからいろいろなブラウザで実行できるような.jsにコンパイル)用のbabelをインストールします。
Webアプリ界隈は規格・仕様の変更が非常に速いため、いちいちそれ向けのコードを書いていられません。
このあたりを吸収してくれるのがbabelのようです。

F1キーでクイックオープンから、Yarn: Add and Save dev. Dependencyを実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/249932/c5e36c98-a9b3-25be-f70b-b7c907891fb7.png)
`babel-cli babel-core babel-loader babel-preset-env`をインストールします。
参考：https://qiita.com/y-temp4/items/9be4b041565a4bb24dab
参考：https://babeljs.io/docs/usage/cli/

インストールすると、以下のように変わります。
1. rootディレクトリにnode_modulesが追加され、この中にモジュールが保存されている
2. rootディレクトリにyarn.lockが追加されている。
3. package.jsonにdevDependenciesが追加され、インストールしたモジュール名とバージョンが書かれている

```json:package.json
    "devDependencies": {
        "babel-cli": "^6.26.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1"
    }
```

次に.babelrcを作成します。
rootフォルダにファイルを新規作成し、ファイル名を.babelrcとします。
内容は以下を記載して保存します。

```.babelrc
{
    "presets": [
        ["env", {"modules": false}]
    ]
}
```
`{"modules": false}`にしないと、WebpackのTreeShake機能が有効にならないようです。
https://ics.media/entry/16028

package.jsonに2点追記します。
1.mainに`index.js`を追記します。(すでにあれば不要です)
2.scriptsに`build`を追記します。(scripts内にtestがすでにあると思います)
scriptsに追加したコマンドはターミナルから、`yarn run コマンド`で実行できるようになります。
ここでは、'yarn run build'になります。

```json:package.json
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "babel src -d lib"
    },
```

srcにindex.jsを作成します。

```java:index.js
console.log("Hello World");
```

ターミナルから`yarn run build`します。
問題なければ、libフォルダにindex.jsが生成されます。
`node lib/index.js`を実行します。
ターミナルに「Hello World!」と表示されます。

```フォルダ構成
myproject
 ├dist
 │  ├index.html
 │  └main.js
 ├lib
 │  └index.js
 ├node_modules
 │  └省略
 ├src
 │  └index.js
 ├.babelrc
 ├myproject.code-workspace
 ├package.json
 ├yarn-error.log
 └yarn.lock
```

yarn-error.logはエラーが発生するとできます。

# webpackのインストール
色々なモジュール(.js)やCSS等から構成されるもろもろを1つの.jsにまとめる(バンドルする)ツールのようです。
VCだと、DLLやiniを個別に分割せず、1つのEXEにする感じだと思います。

F1キーでクイックオープンから、Yarn: Add and Save dev. Dependencyを実行します。
`webpack webpack-cli`をインストールします。
インストールすると、package.jsonのdevDependenciesに、インストールしたモジュール名とバージョンが書かれます。

```json:package.json
    "devDependencies": {
        "babel-cli": "^6.26.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1",
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14",
    }
```

webpackの設定ファイルwebpack.config.jsを作成します。
root以下に新規ファイルを作成します。
参考：https://qiita.com/one-kelvin/items/b810aafb6b5ef90789a3

```javascript:webpack.config.js
const path = require('path');

module.exports = {
  entry: __dirname + "/src/index.js", 
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  }
};
```

webpack + babelで実際にトランスパイルしてみます。
ターミナルで`yarn run webpack`を実行します。
成功すると、dist/main.jsが変わっていることがわかります。

dist/index.htmlをブラウザで開くと、何も表示されていませんが、F12キー等で開発者向けウインドウを開き、表示をコンソールにし、ページのリロードをすると、「Hello World」が出力されます。

```フォルダ構成
myproject
 ├dist
 │  ├index.html
 │  └main.js
 ├lib
 │  └index.js
 ├node_modules
 │  └省略
 ├src
 │  └index.js
 ├.babelrc
 ├myproject.code-workspace
 ├package.json
 ├webpack.config.js
 ├yarn-error.log
 └yarn.lock
```

# webpack-dev-serverをインストールする
ブラウザで動作確認するときに、.jsを変更し、webpackでトランスパイルし、ブラウザを開きなおす、ことを毎回するのは非常に面倒です。
そこで、webpackのwatch機能を使って、ファイルを監視し、変更があればトランスパイルし直し、これを開発用サーバー上で更新する、ような仕組みのwebpack-dev-serverを使います。

F1キーでクイックオープンから、Yarn: Add and Save dev. Dependencyを実行します。
`webpack-dev-server`をインストールします。
インストールすると、package.jsonのdevDependenciesに、インストールしたモジュール名とバージョンが書かれます。

```json:package.json
    "devDependencies": {
        "babel-cli": "^6.26.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.4",
        "babel-preset-env": "^1.6.1",
        "webpack": "^4.5.0",
        "webpack-cli": "^2.0.14",
        "webpack-dev-server": "^3.1.1"
    }
```

webpack.config.jsにdevServerの設定、hotのPlugin設定、modeの設定を追加します。
追加後は以下のようになります。

```javascript:webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: __dirname + "/src/index.js", 

  mode: 'development', 

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },

  devServer: {
    contentBase: 'dist',
    open: true,
    historyApiFallback: true,
    port: 8081,
    inline: true,
    hot: true
  },

  plugins : [
    new webpack.HotModuleReplacementPlugin()
  ],
  
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }
    ]
  }
};
  },
```

ターミナルから`yarn run webpack-dev-server`で実行します。
ブラウザでlocalhost:8081を開いたら、F12キー等で開発者向けウインドウを開き、表示をコンソールにし、ページのリロードをすると、「Hello World」が出力されます。
その状態で、src/index.jsを`console.log("Hello JS World");`に変更します。
そうすると、ブラウザのコンソールに「Hello JS World」が表示されます。

# Debug環境の構築
本筋とずれてきたので、Win10 + VSCode + webpack-dev-serverでのデバッグ環境は省略。
ざっくりとやること。

1. webpack.config.jsへの追加
	- 新規 devtool: 'source-map'
	- 追加 pluginsにnew webpack.LoaderOptionsPlugin({ debug: true})　
		- 参考サイト：https://qiita.com/uskiita/items/88a9d34ae0e9d722fd81
2. package.jsonに以下
	- 追加 scriptsに"start" : "webpack-dev-server -d"
3. launch.json作成と設定
	- 参考サイト：https://qiita.com/tochi_ondy/items/6b357731916a3dedaa4d
		- localhostのポートはwebpack.config.jsのdevServerのportにします。

---
今回はここまでです。
またしても、NEM Libraryにたどり着きませんでした。。。
次回はNEM Libraryのインストールからです。

NEMトランザクションのメッセージでHello Worldを送り、それをHTMLに表示したいと思います。


[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その1)](https://qiita.com/kihaku_dol/items/fa53256de1aafcd110af)
[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その2)](https://qiita.com/kihaku_dol/items/8e1b4787a36cd23a87d2)
[JavaScript初心者がNEM Library使ってWebアプリを作りたい、から環境構築した(その3)](https://qiita.com/kihaku_dol/items/049c94731482b6f346c7)

---
**変更履歴**
2018/05/10 .babelrcの記載を修正、リンク先を追加