vue3 + typescriptをwebpackを使って最小構成で構築！

#はじめに
vue-cliは使用せずにwebpackを自分で設定して、なるべく小さな構成でvue3+typescriptの動作環境を作っていきます。
初心者にも伝わるようになるべく丁寧に進めていきます！

<details>
<summary><strong>〜目次〜</strong></summary>
[①npmのインストール](#npmのインストール)
[②プロジェクトの作成](#プロジェクトの作成)
[③TypeScriptの設定](#typescriptの設定)
[④webpackの設定](#webpackの設定)
[⑤Vueのインストール・簡単な実装](#Vueのインストール・簡単な実装)
[⑥webpackのビルド設定・動作確認](#webpackのビルド設定動作確認)
</details>

※動画でも説明してます
<iframe width="1152" height="648" src="https://www.youtube.com/embed/gdca0K1NxnI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# ①npmのインストール
vueの動作に必要なパッケージの管理をnpmで行います。
npmはnodejsのインストールが必要ですので、まだPCに入ってない場合はインストールします。

まずターミナルを開きます
※Windowsの場合はコマンドプロンプト

###### ①npmが入っているか確認

```
npm --v
6.14.12
```

上記のようにバージョンが出ていればnpmは入っています。
もしまだインストールされてない場合はこちらからインストールをしてください
<p><a href="https://nodejs.org/ja/">nodejsのインストール</a> </p>

#②プロジェクトの作成
まず、プロジェクトを作成するディレクトリを作成します

###### ①任意の場所にディレクトリを作成します。僕は『sample-vue』という名前のディレクトリにします！

```
mkdir sample-vue
```

###### ②作成したディレクトリにnpmで初期化処理を行います。

```
cd sample-vue
npm init -y
```

###### ③ここまで上手くいっていれば下のような構成になっていると思います。

```
sample-vue/
  ├ package.json
```

#③TypeScriptの設定
それでは、TypeScriptを設定していきます。
先ほど『npm init』で作成されたpackage.jsonがあるディレクトリまで移動してください。

#####①TypeScriptパッケージのインストール

```
npm install --save-dev typescript
```

##### ②tsconfig.jsonファイルの作成

```
touch tsconfig.json
```
このtsconfig.jsonにtypescriptの設定を書きます
##### ③tsconfig.jsonの設定

```
{
  "compilerOptions": {
    "sourceMap": true,
    "module": "ES2015",
    "target": "ES5",
    "moduleResolution": "node"
  }
}
```
sourceMap: true:
　・trueにすると、js変換時にソースマップファイルが生成されます。
　・ソースマップファイルがあると、chromeのデバッカーなどで、変換前のTypeScriptコードでデバックできます
module: "ES2015"
　・TypeScriptをjsに変換する際、どのモジュールパターンにする指定します。
　・今回はvue公式でも推奨されているES2015を指定します。
　・ES2015を指定することでTree Shakingが有効になり、TypeScriptを変換する際に無駄なコードを削除することができます。
target: "ES5"
　・TypeScriptを変換する際、どのECMSScriptバージョンにするか指定します。
　・今回はVue公式でも推奨されているES5を指定ます。
moduleResolution: "node"
　・モジュールの解決方法を指定します。
　・何も指定しない場合、ES2015だとClassicになりますが、これは後方互換性の為に残されている方式なので、nodeを指定します。
<p><a href="https://jp.vuejs.org/v2/guide/typescript.html">参考-vue推奨構成</a></p>

#④webpackの設定
次に、webpackの設定をしています。
『package.json』があるディレクトリで必要なパッケージをインストールします

###### ①必要なパッケージのインストール

```
npm install --save-dev webpack webpack-cli vue-loader@next @vue/compiler-sfc css-loader style-loader ts-loader
```
①webpack: webpack本体です
②webpak-cli: webpackを使用するためのコマンドツールです
③vue-loader@next: vueコンポーネント利用するためのLoaderです
⑤@vue/compiler-sfc: vue-loaderに必要なパッケージです
⑥css-loader: cssをjavascriptファイルに埋め込むためのLoaderです
⑦style-loader: jsに埋め込まれたcssをhtmlのstyleタグに加える際に利用されます
⑧ts-loader: typescriptを利用するためのLoaderです
<a href="https://reffect.co.jp/html/webpack-loader-setting-for-beginner">参考-loaderについて</a>

###### ②webpack.config.jsの生成
```
touch webpack.config.js
```

このwebpack.config.jsファイルにwebpackの設定を書きます

###### ③webpack.config.jsの設定
```js
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
  //production(本番用)にすると最適化された状態で、
  //development(開発用)に設定すると読みやすいjsが出力される
  mode: "development",

  //sourcemapをスクリプト内に埋め込む
  devtool: 'inline-source-map',

  //エントリーポイントになるjsファイル ※次のパートで作成します
  entry: "./src/index.ts",
  
  output: {
    //ビルド結果の出力先を指定します
    path: `${__dirname}/dist`,
　　//ビルド結果のjsファイル名を指定します
    filename: "bundle.js"
  },
  module: {
    rules: [
      {
        //vueのloader設定
        test: /\.vue$/,
        loader: "vue-loader"
      },
      {
        //cssのloader設定
        test: /\.css$/,
        use:[
          "style-loader",
          "css-loader"
        ]
      },
      {
        //typescriptのloaderを設定
        test: /\.ts$/,
        loader: "ts-loader",
        options: {
          //vueをtypescriptとして監視する
          appendTsSuffixTo: [/\.vue$/]
        }
      },
    ]
  },
  resolve: {
    //import文で、.tsを省略できるようにする
    extensions: [".ts"]
  },
　//vue-loader v15以上を使う場合に必要
  plugins:[new VueLoaderPlugin()]
}
```
①mode: "development"
　・こちらは開発中はdebvelopmentに設定します。
　・productionにすることでコードが最適化されます。
　・本番環境では必ずproductionにします。
②dev-tool:inline-source-map
　・dev-toolはソースマップを生成するかどうかと、その方法を指定します。
　・inline-source-mapを指定することで、コードの中にsourcemapが含まれるようになります。
③entry: '.src/index.ts'
　・アプリケーションのエントリーポイントになるファイルを指定します。
　・まだsrc/index.tsは作ってませんが、次のプロセスで作成するので指定しておきます。
④output->path:  `${__dirname}/dist`
　・出力ディレクトリを絶対パスで指定します。
　・__dirnameで実行中のソースコートが格納されているディレクトリの絶対パスを取得します。
⑤output->filename: 'bundle.js'
　・出力結果のファイル名を指定します。
⑥moduke->rule
　・ここにローダーの設定をしていきます。
⑨plugins:[new VueLoaderPlugin()]
　・vue-loader V15以上を使う場合に必要です

#⑤Vueのインストール・簡単な実装
①vue3をインストールします

```
npm install --save vue@next
```

②ルートディレクトにdistとsrcディレクトリを作成します

```
mkdir dist
mkdir src
```

③現在のディレクトリ構成はこのようになっていると思います

```
sample-vue/
  ├ dist
  ├ src
  ├ package.json
  ├ tsconfig.json
  ├ webpack.config.js
  ├ node_modules
```
④srcディレクトリの直下に、App.vueを作成します

```
cd src
touch App.vue
```
⑤App.vueを下の様に実装します

```vuejs
<style>
.hello{
 color: red; /*cssが効いている事がわかりやすくする為に赤にする*/
}
</style>

<template>
 <span class="hello">{{ helloText }}</span>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'App',
  setup(){
    return{
      helloText: 'Hello World!'
    }
  }
})
</script>
```
⑥srcディレクトリ直下にvue.d.ts(vueファイルの型定義ファイル)を作成します
こちらを用意しないと、.vueのモジュールをimportする際にエラーになります

```js
declare module '*.vue' {
    import { ComponentOptions } from 'vue'
    const component: ComponentOptions;
    export default component
}
```
⑦srcディレクトリ直下にindex.tsを作成します

```
touch index.ts
```
⑧index.tsを下の様に実装します

```js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)

app.mount('#app')
```

⑨distディレクトリ直下に、index.htmlを生成します

```
cd ../dist
touch index.html
```

⑩index.htmlを下の様に実装します

```html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <div id="app"></div>
        <script src="bundle.js"></script>
    </body>
</html>
```
・divのidをindex.jsでマウントしたものと同じにする
・webpackで出力指定したjsファイルを読み込むようにする

#⑥webpackのビルド設定・動作確認
①package.jsonを開き、scriptセクションの中に『build: "webpack"』を追加します

```json
"scripts":{
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "webpack" //ここを新規追加
}
```

②package.jsonがあるディレクトリに移動し、webpackのバンドルを実行します

```
npm run-script build
```

③distディレクトリにbundle.jsが生成されたことを確認します

```
sample-vue/
  ├ dist
    ├ index.html
    ├ bundle.js //ここが自動生成される
  ├ src
    ├ App.vue
    ├ index.ts
    ├ vue.d.ts
  ├ package.json
  ├ tsconfig.json
  ├ webpack.config.js
  ├ node_modules
```

④chromeでindex.htmlを開いて動作していることを確認します！
![asdsa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1631090/b4afaf83-f612-719b-828e-12a6ca04c562.png)