TypeScriptなVue.jsで環境ごとに設定ファイルを読み込みこめるようにしてみた

## 概要

Vue.jsで設定ファイルを環境ごとに読み込みたかった。
以下を参考にTypeScriptでもできるようにしてみました。

Vue.js + webpack で環境ごとに設定ファイルを分ける
https://qiita.com/zaru/items/45a94a2d95001cfe5ead


## 手順

### プロジェクト作成

Vue.jsのプロジェクトを作成するところから。Dockerで環境作ってますがローカルで実行しても問題ありません。好みです。

言語やTypeScriptです。じゃないと以下の手順が破綻します^^;;;

GitHubに利用したプロジェクトをUPしています。環境構築が面倒！けど試したい///という方はどうぞ。
https://github.com/kai-kou/vue-js-typescript-global-mixin.git


```sh
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ
> vi Dockerfile
> vi docker-compose.yml
```

```txt:Dockerfile
FROM node:10.8.0-stretch

RUN npm install --global @vue/cli

WORKDIR /projects
```

```yaml:docker-compose.yml
version: '3'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    volumes:
      - ".:/projects"
    tty: true
```

```sh
> docker-compose up -d
> docker-compose exec app bash
```

言語をTypeScriptで。あとは適当で良いです。

```sh:コンテナ内
> vue create app

Vue CLI v3.0.1
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript for auto-detected polyfills? Yes
? Pick a linter / formatter config: TSLint
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
```

### 設定ファイルの用意

```sh
> cd app/
> mkdir src/configs
> touch src/configs/development.ts
> vi src/configs/development.ts
```

```ts:app/src/configs/development.ts
export default {
  hoge: {
    hoge: 'hoge',
    fuge: 'fuge',
  },
};

```

他の環境の設定ファイルも用意します。

```sh
> cp src/configs/development.ts src/configs/production.ts
> cp src/configs/development.ts src/configs/test.ts
```

### configディレクトリのエイリアス設定

参考にさせてもらった記事だと、Webpack.config.jsに設定を追加する感じだったのですが、Vue-CLI3系はvue.config.jsを利用するみたいです。

```sh
> touch vue.config.js
> vi vue.config.js
```

```js:app/vue.config.js
var path = require('path');

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        config: path.resolve(`src/configs/${process.env.NODE_ENV}.ts`),
      }
    }
  }
};

```

### tslint対策

このままだとWebpackの設定で追加したaliasをtslintさんが読み取ってくれないので、無視してもらうようにお願いします。ここはもっと良い方法がありそうです。
ファイル名は任意です。

```sh
> touch src/types.d.ts
> vi src/types.d.ts
```

```ts:src/types.d.ts
declare module 'config';
```

### 設定ファイルの読み込み

せっかくTypeScriptを使っているので、ここでは、各コンポーネントの基底クラスを実装してみました。ここももっと良い方法がありそうです。
Vue.jsなのでMixinどうしたらいいのかなぁと悩んでて、以下記事をみつけて、あ〜それでいいのかぁとなりました。感謝！

VueとTypeScriptとMixin
https://qiita.com/totto357/items/4b20accb64f926cdfc30


```sh
> touch src/components/Base.ts
> vi src/components/Base.ts
```

```ts:app/src/components/Base.ts
import Vue from 'vue';
import Component from 'vue-class-component';
import config from 'config';

@Component
export default class Base extends Vue {
  protected config?: any;

  protected created() {
    this.config = config;
  }
}

```

で、ここでは最初から用意されているコンポーネントでconfigが利用できるようにしてみいます。
Baseコンポーネントを継承しても良いのですが、```config``` をそのままインポートでも良いですね。お好みで。

```sh
vi src/components/HelloWorld.vue
```

```vue:app/src/components/HelloWorld.vue
<script lang="ts">
+import Component from 'vue-class-component';
-import { Component, Prop, Vue } from 'vue-property-decorator';
+import { Prop, Vue } from 'vue-property-decorator';
+import Base from '@/components/Base';
+import config from 'config';

@Component
-export default class HelloWorld extends Vue {
+export default class HelloWorld extends Base {
  @Prop() private msg!: string;
}

  created() {
    // 継承元から
    console.log(this.config);
    // 自前でimport
    console.log(config);
  }
</script>
```

では、確認してみましょう。

```sh:コンテナ内
> yarn serve
```

```sh:コンテナ外
> open http://localhost:8080/
```

<img width="1474" alt="スクリーンショット 2018-08-24 17.12.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/8ff74afd-59cd-2b5b-baf5-81574b93b303.png">
(ポートが8081なのはご愛嬌^^

やったぜ。

やりようがいくらでもある感じなので、ベストプラクティスはどれ！ってなりがちですが、とりあえずご参考までに。


## 参考

Vue.js + webpack で環境ごとに設定ファイルを分ける
https://qiita.com/zaru/items/45a94a2d95001cfe5ead

VueとTypeScriptとMixin
https://qiita.com/totto357/items/4b20accb64f926cdfc30

Vue.js+TypeScriptで開発するときの参考記事まとめ
https://qiita.com/kai_kou/items/19b494a41023d84bacc7