WebGLのTypeScript環境作ってみた

## はじめに
この記事は、[UUUM Advent Calendar 2019](https://qiita.com/advent-calendar/2019/uuum) 1日目です。

UUUMではRails、AWS、UI周り、最近はアプリ周りなど幅広くやっています！

今日月曜日が12/1だと思いこんでたら昨日でした。初日からやらかしていますが僕は元気です。

## 最近WebGLの勉強を始めたよ！

「Graphics出来る人カッコイイ」「WebGL勉強してみたい」とずって思っていたので、10月の終わりから [wgld.org](https://wgld.org/) でWebGLの勉強をちょこちょこ始めました。

![Screenshot from 2019-10-26 22-02-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125325/339d2cc9-ee7a-d125-0ee2-626227d5b564.png)

45章くらいまで進めたけど、サンプルコードがレガシーできちんとリファクタリングしたいなっていう気持ちでいっぱいになったので、折角なので改善を回しやすいようにフロントエンド環境を整えてみました！

## 構成

repo: [takeokunn/glsl-sandbox](https://github.com/takeokunn/glsl-sandbox/)
url: [https://takeokunn.github.io/glsl-sandbox/](https://takeokunn.github.io/glsl-sandbox/)

```shell
~/.g/g/t/glsl-sandbox (*´ω｀*) < tree -I node_modules
.
├── package.json
├── package-lock.json
├── public
│   ├── bundle.js
│   └── index.html
├── src
│   ├── index.ts
│   ├── lib
│   │   └── minMatrix.ts
│   ├── shader.frag
│   ├── shader.vert
│   └── @types
│       └── common.d.ts
├── tsconfig.json
└── webpack.config.js
└── node_modules
```

### CircleCI

![Screenshot from 2019-12-02 18-48-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125325/fa3bcac4-e4d3-d38c-7692-8b157c2f5008.png)

`deploy` では、 `webpack build` した後の `public/` ディレクトリを `gh-pages` に `push` されるようにしました。
ライブラリは [gh-pages](https://www.npmjs.com/package/gh-pages) を使っています。

### Webpack設定

`'glslify-loader'` を使って `glsl` を扱えるようにしました。

`webpack.config.js`:

```
const path = require("path");

module.exports = {
    mode: "development",
    devtool: 'inline-source-map',
    entry: path.join(__dirname, "src/index.ts"),
    output: {
        filename: "bundle.js",
        path: path.join(__dirname, "public")
    },
    module: {
        rules: [
            {
                test: /\.ts?$/,
                use: "ts-loader",
                exclude: /node_modules/
            },
            {
                test: /\.(glsl|vs|fs|vert|frag)$/,
                exclude: /node_modules/,
                use: [
                    'raw-loader',
                    'glslify-loader'
                ]
            }
        ]
    },
    devServer: {
        contentBase: path.join(__dirname, "public"),
        open: true,
        inline: true
    }
};

```

`tsconfig.json`:

```json
{
  "compilerOptions": {
    "sourceMap": true,
    "noImplicitAny": false,
    "module": "commonjs",
    "target": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "typeRoots" : ["src/@types"],
    "lib": ["es2019", "dom"]
  }
}
```

## Lint周り

`eslint` と `prettier` でモダンにLint周りを調整しました。

`.eslintrc.js`:

```javascript
module.exports = {
    extends: [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:prettier/recommended",
        "prettier/@typescript-eslint"
    ],
    plugins: ["@typescript-eslint"],
    parser: "@typescript-eslint/parser",
    env: { browser: true, node: true, es6: true },
    parserOptions: {
        sourceType: "module",
        project: "./tsconfig.json"
    },
    rules: {
        "@typescript-eslint/no-var-requires": 0
    }
};
```

## GLSLを開発する上でのEmacsの設定

この辺のライブラリを使うと `Emacs` での開発がスムーズに進みます。

* [jimhourihan/glsl-mode](https://github.com/jimhourihan/glsl-mode)
* [Kaali/company-glsl](https://github.com/Kaali/company-glsl)

`glsl` には、本格的に開発できるくらいの `language server` がないので一旦はパス。(いつか作る)

`glsl-mode` の設定:

```lisp
(autoload 'glsl-mode "glsl-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.vsh$" . glsl-mode))
(add-to-list 'auto-mode-alist '("\\.fsh$" . glsl-mode))
```

`company-glsl` の設定:

```lisp
(use-package company-glsl)
(global-company-mode)
(add-to-list 'company-backends 'company-glsl)
```

## 最後に

UUUMでは特に業務では使わないけどGLSLに詳しいエンジニアを欲しています。
詳しくはこちら →→→→→→ [UUUM攻殻機動隊の紹介](https://system.blog.uuum.jp/entry/2018/12/01/132950)